An issue came up in a class I was teaching today...
There doesn't seem to be an easy way to create a type that allows a set
of enumerated bit-flags *and* all the combinations of those flags...and
nothing else.
For example:
enum Permissions ( Read => 0b0001, Write => 0b0010, Exec => 0b0100 );
my Permissions $rwx = Read +| Write; # Error
I know I could use junctions:
subset BitFlag where Read|Write|Exec;
my BitFlag $rwx = Read | Write;
but it's not easy to recover the actual bitpattern from that, except with:
$bitpattern = [+|] $rwx.eigenstates;
which is suboptimal in readability (not to mention that it requires
MONKEY_TYPING to allow access to the .eigenstates method).
Ideally, what I'd like to be able to do is something like:
enum Permissions is bitset < Read Write Exec >;
# The 'is bitset' starts numbering at 0b0001 (instead of the usual zero)
# and doubles each subsequent enumeration value (instead of the usual ++).
# It also implicitly fills in the various other bitwise-or permutations
# as valid-but-nameless enumerated values
my Permissions $rwx = Read +| Write; # Now fine
The closest I can think of at the moment is something like:
enum NamedPermissions ( Read => 0b0001, Write => 0b0010, Exec => 0b0100 );
subset Permissions of Int where 0 .. [+|]NamedPermissions.enums.values;
my Permissions $rwx = Read +| Write; # Fine
which is still a little too constructive, too explicit (you have to get the
bit values right), as well as being too obscure for such a common task.
Of course, I could always create a macro to encapsulate the explicit
constructive obscurity:
macro bitset ($typename, @value_names)
is parsed(/:s (<ident>) '<' ( <ident> )+ '>' /)
{
# [build code to implement the above trick here]
}
# and later...
bitset Permissions < Read Write Exec >;
but this is such a common requirement in engineering applications that it
would be great if this wheel didn't constantly have to be reinvented.
If anyone can think of a cleaner way to do it within the current semantics,
I'd be very happy to hear of it. I'm jetlagged and bleary from a full day of
teaching and I may well be missing an obvious answer.
Thanks,
Damian