- (define-enum-packer ...)syntax
Defines a procedure that will "pack" a list of enums (or a single enum) into a single integer, aka a bitfield. The packer converts each enum into an integer, then combines them using bitwise-ior. This supplements define-enum-group for cases where the enums are bitmasks or flags.
See also define-enum-unpacker to go in the opposite direction, converting an integer into a list of symbols.
Usage:
(define-enum-packer PACKER (SYMBOL->INT) allow-ints: ALLOW-INTS) ; optional
PACKER is the procedure name to define as the enum packer.
SYMBOL->INT is an existing procedure that converts a symbol into an integer value, such as a procedure defined with define-enum-group. It must accept a second argument, which will be the not-found-callback procedure passed to the packer, or #f if no callback was passed to the packer.
If ALLOW-INTS is #t, the packer will accept integers as well as symbols. If the packer encounters an integer, either in the list of enums or as a single argument, the integer will be used without trying to convert it. This allows users to pack the bitfield manually, for optimization or special cases. If ALLOW-INTS is #f or the keyword clause is omitted, then the packer will always try to convert the enums using SYMBOL->INT regardless of type.
Example:
(foreign-declare " typedef enum { FOO_KMOD_NONE = 0b0000, FOO_KMOD_LCTRL = 0b0001, FOO_KMOD_RCTRL = 0b0010, FOO_KMOD_CTRL = 0b0011 } FOO_KeyMod; ") (define-enum-group type: int symbol->int: keymod->int int->symbol: int->keymod ((none FOO_KMOD_NONE) (lctrl FOO_KMOD_LCTRL) (rctrl FOO_KMOD_RCTRL) (ctrl FOO_KMOD_CTRL))) (define-enum-packer pack-keymods (keymod->int) allow-ints: #t) (pack-keymods '(lctrl)) ; ⇒ 1 (pack-keymods 'lctrl) ; ⇒ 1 (pack-keymods '(rctrl lctrl)) ; ⇒ 3 (pack-keymods '(lctrl 6)) ; ⇒ 7 (pack-keymods '()) ; ⇒ 0 (pack-keymods 42) ; ⇒ 42 (pack-keymods '(lctrl foo)) ; error! (pack-keymods '(lctrl foo) (lambda (sym) 16)) ; ⇒ 17