[ANN] FlagSets.jl v0.3 - represent sets contained in a finite universe

FlagSets is based on BitFlags.jl, but with a different concept: FlagSet is a subtype of AbstractSet and implement both set and bitwise operations (each bit is associated with a flag, and so a sequence of bits is associated with a set of flags - where 1 indicates the flag is in the set and 0 indicates it is not in the set).

In the new version, flags can be of any type, which widens the usability of FlagSets. That allows one to create a type whose objects are sets contained in a finite universe.

Note: there has been a slight change in syntax, because now flags are evaluated during macroexpansion. The previous syntax is available with @symbol_flagset macro.

julia> using FlagSets

julia> @flagset PrimeNumbers 2 3 5 7 11 13 17 19 23 29

julia> PrimeNumbers([2,17,29])
PrimeNumbers with 3 elements:
  2
  17
  29

julia> PrimeNumbers([2,3,5,7,9])
ERROR: ArgumentError: invalid value for FlagSet PrimeNumbers: 9
Stacktrace:
# [...]

julia> eltype(PrimeNumbers)
Int64

julia> 2 ∈ typemax(PrimeNumbers)
true

julia> 9 ∈ typemax(PrimeNumbers)
false

The association of flags (prime numbers) and bits are printed with the type:

julia> PrimeNumbers
FlagSet PrimeNumbers:
 0x00000001 --> 2
 0x00000002 --> 3
 0x00000004 --> 5
 0x00000008 --> 7
 0x00000010 --> 11
 0x00000020 --> 13
 0x00000040 --> 17
 0x00000080 --> 19
 0x00000100 --> 23
 0x00000200 --> 29

With non-Symbol flag sets, to create objects, you need to provide an iterable, just like you would construct Set (that avoids ambiguities). If you construct from an integer, by default, it interprets the value as a bit mask. E.g.:

julia> PrimeNumbers(0x00000004)
PrimeNumbers with 1 element:
  5

julia> Integer(PrimeNumbers([2,3,5,7,11]))
0x0000001f

julia> PrimeNumbers(0x0000001f)
PrimeNumbers with 5 elements:
  2
  3
  5
  7
  11

To avoid confusion, in this case, it makes sense to override the method of construction with integer arguments:

julia> PrimeNumbers(ints::Integer...) = PrimeNumbers(ints);

julia> PrimeNumbers(11)
PrimeNumbers with 1 element:
  11

# Interpret 11 as a bitmask 
julia> PrimeNumbers(FlagSets.BitMask(11))
PrimeNumbers with 3 elements:
  2
  3
  7

Comments, critics, suggestions are welcome, as always.

6 Likes