-
bit_set[_bitset_type_; _backing_type_] -
Bit Sets .
Creation
Direction :: enum{North, East, South, West}
Direction_Set :: bit_set[Direction]
Char_set :: bit_set['A'..='Z']
Int_Set :: bit_set[0..<10] // bit_set[0..=9]
u32_set: bit_set[u32(0)..<32]
// If you don't use u32(0), the range created will be `int`, even though the backing type is `u32`.
// Weird.
Underlying type
-
If a bit set requires a specific size, the underlying integer type can be specified:
Char_Set :: bit_set['A'..='Z'; u64]
#assert(size_of(Char_Set) == size_of(u64))
-
The underlying type is not the same thing as the type of the bitset:
unique_sets: bit_set[u32(0)..<32]
// This is a u32 bit_set
unique_sets: bit_set[0..<32; u32]
// This is an int bit_set, with u32 as backing type
// Weird.
unique_sets: bit_set[u32(0)..<32; u32]
// This is a u32 bit_set, with u32 as backing type
Evaluation
-
Bit Set vs Elements :
-
e in A- set membership (A contains element e) -
e not_in A- not set membership (A does not contain element e)
-
-
Bit Set vs Bit Set :
-
A + B- union of two sets (equivalent toA | B) -
A - B- difference of two sets (A without B’s elements) (equivalent toA &~ B) -
A & B- intersection of two sets -
A | B- union of two sets (equivalent toA + B) -
A &~ B- difference of two sets (A without B’s elements) (equivalent toA - B) -
A ~ B- symmetric difference (Elements that are in A and B but not both) -
A == B- set equality -
A != B- set inequality -
A <= B- subset relation (A is a subset of B or equal to B) -
A < B- strict subset relation (A is a proper subset of B) -
A >= B- superset relation (A is a superset of B or equal to B) -
A > B- strict superset relation (A is a proper superset of B)
-
-
card.-
card(bit_set)returns how many1s there are in thebit_set. -
Cardinality = popcount = number of 1s.
-
Ex:
unique_sets: bit_set[u32(0)..<32; u32] for ubo in glsl_reflect.ubos { unique_sets += { ubo.set } } for tex in glsl_reflect.textures { unique_sets += { tex.set } } set_layouts = make([]Shaders_Set_Layout, card(unique_sets), allocator)
-
Operations
-
Union of
.WINDOW_RESIZABLEand.WINDOW_ALWAYS_RUN.rl.SetWindowState({ .WINDOW_RESIZABLE, .WINDOW_ALWAYS_RUN }) -
Toggle flag:
-
~=
-
Discussions
-
TLDR : "Bitset 0 means 'activate the first bit".
-
Caio:
-
For this bitset below, if I set
my_flags = {}, would that mean it's the same as settingmy_flags = { .INDIRECT_COMMAND_READ }?
AccessFlags2 :: distinct bit_set[AccessFlag2; Flags64] // distinct u64 AccessFlag2 :: enum Flags64 { INDIRECT_COMMAND_READ = 0, INDEX_READ = 1, VERTEX_ATTRIBUTE_READ = 2, // .. } -
-
Barinzaya:
-
No.
AccessFlags2is effectively an integer (Flags64, specifically), where its bits are used to indicate the presence of the enum values. The numeric value of theenumvariants correspond to which bit in that integer is used to represent them. So bit 0 (1 << 0 == 1) is used to indicate whetherINDIRECT_COMMAND_READis set, bit 1 (1 << 1 == 2) is used to indicate whetherINDEX_READis set, and so on. So{}is an integer0internally,{.INDIRECT_COMMAND_READ}would be an integer1internally
-
-
Caio:
-
So, in my head I had this idea of a "bit mask", so for example if I set it to
3, then it would mean thatINDEX_READandVERTEX_ATTRIBUTE_READwere active and zero, would actually be zero, with nothing active -
Is it just a different concept? bit mask != bit set? I used bit masks before, so that's the model I have in my head
-
-
Barinzaya:
-
It's the same idea, I think you just have it shifted by 1.
INDIRECT_COMMAND_READoccupies a bit too (edited) -
So in "raw" bit masks, it would be
INDIRECT_COMMAND_READ = 1 // 1 << 0 (bit 0) INDEX_READ = 2 // 1 << 1 (bit 1) VERTEX_ATTRIBUTE_READ = 4 // 1 << 2 (bit 2) FOURTH_ONE = 8 // 1 << 3 (bit 3) FIFTH_ONE = 16 // 1 << 4 (bit 4)-
The value in the
AccessFlag2enum is just a bit index , not a mask -
The
bit_sethandles turning it into a mask.
-