- `(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)))))))
-
-
-
-;(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass %flags-value (static)
- ((value :allocation :alien :type unsigned-int)
- (name :allocation :alien :type string)
- (nickname :allocation :alien :type string))
- (:metaclass proxy-class));)
+ `(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))))
+
+(defmethod reader-function ((type (eql 'flags)) &rest args)
+ (declare (ignore type))
+ (let ((reader (reader-function 'unsigned))
+ (function (apply #'from-alien-function 'flags args)))
+ #'(lambda (location &optional (offset 0))
+ (funcall function (funcall reader location offset)))))
+
+
+
+(defclass %flags-value (struct)
+ ((value :allocation :alien :type unsigned-int)
+ (name :allocation :alien :type string)
+ (nickname :allocation :alien :type string))
+ (:metaclass static-struct-class))