Bit Sets

  • 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 to A | B )

    • A - B  - difference of two sets (A without B’s elements) (equivalent to A &~ B )

    • A & B  - intersection of two sets

    • A | B  - union of two sets (equivalent to A + B )

    • A &~ B  - difference of two sets (A without B’s elements) (equivalent to A - 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 many 1 s there are in the bit_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_RESIZABLE  and .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 setting my_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. AccessFlags2  is effectively an integer ( Flags64 , specifically), where its bits are used to indicate the presence of the enum values. The numeric value of the enum  variants correspond to which bit in that integer is used to represent them. So bit 0 ( 1 << 0 == 1 ) is used to indicate whether INDIRECT_COMMAND_READ  is set, bit 1 ( 1 << 1 == 2 ) is used to indicate whether INDEX_READ  is set, and so on. So {}  is an integer 0  internally, {.INDIRECT_COMMAND_READ}  would be an integer 1  internally

  • 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 that INDEX_READ  and VERTEX_ATTRIBUTE_READ  were 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_READ  occupies 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 AccessFlag2  enum is just a bit index , not a mask

    • The bit_set  handles turning it into a mask.