+ (unwind-protect
+ (map-glist 'list #'identity glist ',element-type)
+ (destroy-glist glist ',element-type)))))
+
+(defmethod from-alien-function ((type (eql 'glist)) &rest args)
+ (declare (ignore type))
+ (destructuring-bind (element-type) args
+ #'(lambda (glist)
+ (unwind-protect
+ (map-glist 'list #'identity glist element-type)
+ (destroy-glist glist element-type)))))
+
+(defmethod copy-from-alien-form (glist (type (eql 'glist)) &rest args)
+ (declare (ignore type))
+ (destructuring-bind (element-type) args
+ `(map-glist 'list #'identity ,glist ',element-type)))
+
+(defmethod copy-from-alien-function ((type (eql 'glist)) &rest args)
+ (declare (ignore type))
+ (destructuring-bind (element-type) args
+ #'(lambda (glist)
+ (map-glist 'list #'identity glist element-type))))
+
+(defmethod cleanup-form (glist (type (eql 'glist)) &rest args)
+ (declare (ignore type))
+ (destructuring-bind (element-type) args
+ `(destroy-glist ,glist ',element-type)))
+
+(defmethod cleanup-function ((type (eql 'glist)) &rest args)
+ (declare (ignore type args))
+ (destructuring-bind (element-type) args
+ #'(lambda (glist)
+ (destroy-glist glist element-type))))
+
+
+;;;; Single linked list (GSList)
+
+(deftype gslist (type) `(or (null (cons ,type list))))
+
+(defbinding (%gslist-prepend "g_slist_prepend") () pointer
+ (gslist pointer)
+ (nil null))
+
+(defun make-gslist (type list)
+ (loop
+ with writer = (writer-function type)
+ for element in (reverse list)
+ as gslist = (%gslist-prepend (or gslist (make-pointer 0)))
+ do (funcall writer element gslist)
+ finally (return gslist)))
+
+(defbinding (gslist-free "g_slist_free") () nil
+ (gslist pointer))
+
+(defun destroy-gslist (gslist element-type)
+ (loop
+ with destroy = (destroy-function element-type)
+ as tmp = gslist then (glist-next tmp)
+ until (null-pointer-p tmp)
+ do (funcall destroy tmp 0))
+ (gslist-free gslist))
+
+(defmethod alien-type ((type (eql 'gslist)) &rest args)
+ (declare (ignore type args))
+ (alien-type 'pointer))
+
+(defmethod size-of ((type (eql 'gslist)) &rest args)
+ (declare (ignore type args))
+ (size-of 'pointer))