- `(or
- null
- (cons
- (member ,@(%map-mappings args :symbols))
- list)))
-
-(deftype-method translate-type-spec flags (type-spec)
- (let ((args (cdr (type-expand-to 'flags type-spec))))
- (if (integerp (first args))
- (translate-type-spec `(unsigned ,(first args)))
- (translate-type-spec 'unsigned))))
-
-(deftype-method size-of flags (type-spec)
- (let ((args (cdr (type-expand-to 'flags type-spec))))
- (if (integerp (first args))
- (size-of `(unsigned ,(first args)))
- (size-of 'unsigned))))
-
-(deftype-method translate-to-alien flags (type-spec expr &optional weak-ref)
- (declare (ignore weak-ref))
- (destructuring-bind (name &rest args) (type-expand-to 'flags type-spec)
- (declare (ignore name))
- (let ((mappings (%map-mappings args :flags-int))
- (value (make-symbol "VALUE")))
- `(let ((,value 0))
- (dolist (flag ,expr ,value)
- (setq ,value (logior ,value (second (assoc flag ',mappings)))))))))
-
-(deftype-method translate-from-alien flags (type-spec expr &optional weak-ref)
- (declare (ignore weak-ref))
- (destructuring-bind (name &rest args) (type-expand-to 'flags type-spec)
- (declare (ignore name))
- (let ((mappings (%map-mappings args :int-flags))
- (result (make-symbol "RESULT")))
- `(let ((,result nil))
- (dolist (mapping ',mappings ,result)
- (unless (zerop (logand ,expr (first mapping)))
- (push (second mapping) ,result)))))))
-
-(setf (alien-type-name 'flags) "GFlags")
-
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass %flags-value (alien-structure)
- ((value :allocation :alien :type unsigned-int)
- (name :allocation :alien :type string)
- (nickname :allocation :alien :type string))
- (:metaclass proxy-class)))
-
-(defbinding %flags-class-values () (glist %flags-value)
- (class pointer))
-
-(defun %query-flags-values (type-number)
- (mapcar
- #'(lambda (flags-value)
- (list
- (intern
- (substitute
- #\- #\_ (string-upcase (slot-value flags-value 'nickname))) "KEYWORD")
- (slot-value flags-value 'value)))
- (%flags-class-values (type-class-peek type-number))))
-
-(defun define-flags-by-query (init-fname &optional name)
- (let ((type-number (type-init nil init-fname)))
- (unless (= (type-parent type-number) (find-type-number 'flags))
- (error "~A is not a flags type" (alien-type-name type-number)))
+ `(or null (cons (member ,@(%map-enum args :symbols)) list)))
+
+(defmethod alien-type ((type (eql 'flags)) &rest args)
+ (declare (ignore type args))
+ (alien-type 'unsigned))
+
+(defmethod size-of ((type (eql 'flags)) &rest args)
+ (declare (ignore type args))
+ (size-of 'unsigned))
+
+(defmethod to-alien-form (flags (type (eql 'flags)) &rest args)
+ `(loop
+ with value = 0
+ with flags = ,flags
+ for flag in (mklist flags)
+ do (let ((flagval
+ (or
+ (second (assoc flag ',(%map-enum args :flags-int)))
+ (error "~S is not of type ~S" flags '(,type ,@args)))))
+ (setq value (logior value flagval)))
+ finally (return value)))
+
+(defmethod from-alien-form (int (type (eql 'flags)) &rest args)
+ (declare (ignore type))
+ `(loop
+ for mapping in ',(%map-enum args :int-flags)
+ unless (zerop (logand ,int (first mapping)))
+ collect (second mapping)))
+
+(defmethod to-alien-function ((type (eql 'flags)) &rest args)
+ (let ((mappings (%map-enum args :flags-int)))
+ #'(lambda (flags)
+ (loop
+ with value = 0
+ for flag in (mklist flags)
+ do (let ((flagval (or
+ (second (assoc flag mappings))
+ (error "~S is not of type ~S" flags (cons type args)))))
+ (setq value (logior value flagval)))
+ finally (return value)))))
+
+(defmethod from-alien-function ((type (eql 'flags)) &rest args)
+ (declare (ignore type))
+ (let ((mappings (%map-enum args :int-flags)))
+ #'(lambda (int)
+ (loop
+ for mapping in mappings
+ unless (zerop (logand int (first mapping)))
+ collect (second mapping)))))
+
+(defmethod writer-function ((type (eql 'flags)) &rest args)
+ (declare (ignore type))
+ (let ((writer (writer-function 'unsigned))
+ (function (apply #'to-alien-function 'flags args)))
+ #'(lambda (flags location &optional (offset 0))
+ (funcall writer (funcall function flags) location offset))))