type
AuthenticationMethod* = enum
NO_AUTHENTICATION_REQUIRED = 0x00.byte
GSSAPI = 0x01.byte
USERNAME_PASSWORD = 0x02.byte
NO_ACCEPTABLE_METHODS = 0xFF.byte
proc `in`*(bytesMethod: seq[byte], authMethods: set[AuthenticationMethod]): bool =
for byteMethod in bytesMethod:
if byteMethod.AuthenticationMethod in authMethods: return true
return false
#fails with Error: ordinal type expected
A set is a packed bitfield that uses the enum values as index.
I.e. your set would use bit 0, bit 1, bit 2 and bit 255. But this is not packed anymore since bit: 3..254 are unused.
This would prevent iterating over the set as items rely on the packed dense representation.
In conclusion i think this is not a bug, and it would be a heavy feature to implement see #7699 #8132 #8264 .
As a workaround:
@mratsim I don't think that using non ordinal types in sets should be a problem. Most sets operations work just fine. In order to iterate, you can just iterate over the set as if it was packed (e.g a set if uint8) and then filter only these integer values that correspond to valid enum values. Alternatively, items could have the signature
iterator items[T: Ordinal](s: set[T])
Other valid uses of sets (e.g. as option masks) do not need a contiguous enum
i think this is a regression, this is part of old (once working) code
@enthus1ast Enums with holes have recently been changed to become non ordinal types (so, for instance you cannot inc such a value). The discussion is whether this should prevent to put them in a bitset - I personally see no good reason for this (at most we could require an ordinal type for items)
I have an application I'm working on where I get pressed keyboard scancodes from the OS and relay that to a set for convenience - of which my scancode enum has a few holes (as not every value is defined by the standard defined by the USB spec), so having enums with holes work with set[T] is useful to me.
If we do formally allow enums with holes in sets, instead of the internal array's "length in bits" being T.high() + padding or whatever, maybe the internal array's length in bits should be equivalent to just the number of discrete enum fields (again, + any necessary padding), from which we can create some sort of mapping from a bit index to the enum field's real value as a special case for holed enums.
If the restriction is not loosened, then it would be a good idea to also have a flag type.
For the time being, set should continue to accept enums with holes. Working on it.
Still an issue with literals
type Foo = enum
Foo1 = 0
Foo2 = 1
Foo3 = 3
let x = { Foo1, Foo2 } # Error: ordinal type expected
By the way, this is a problem for NimPNG which uses this form here
Most helpful comment
For the time being,
setshould continue to accept enums with holes. Working on it.