Skip to content

Instantly share code, notes, and snippets.

@oskarnp
Created February 11, 2024 08:29
Show Gist options
  • Save oskarnp/af6cdada5e408c31db4a1609ca377f4b to your computer and use it in GitHub Desktop.
Save oskarnp/af6cdada5e408c31db4a1609ca377f4b to your computer and use it in GitHub Desktop.
bit_set_iterator.odin
package main
import "core:fmt"
import "base:intrinsics"
main :: proc() {
X :: enum { A, B, C }
Y :: bit_set[X];
values := Y{.A, .C};
Bit_Set_Iterator :: struct {
i: int,
v: u128,
}
bit_set_iterator :: proc(itr: ^Bit_Set_Iterator, set: $S/bit_set[$E]) -> ^Bit_Set_Iterator {
when size_of(set) == 1 { itr.v = u128(transmute(u8)(set)) }
else when size_of(set) == 2 { itr.v = u128(transmute(u16)(set)) }
else when size_of(set) == 4 { itr.v = u128(transmute(u32)(set)) }
else when size_of(set) == 8 { itr.v = u128(transmute(u64)(set)) }
else when size_of(set) == 16 { itr.v = u128(transmute(u128)(set)) }
else do #panic("unhandled size")
return itr
}
bit_set_next :: proc(itr: ^Bit_Set_Iterator, set: $S/bit_set[$E]) -> (E, int, bool) {
if itr.v != 0 {
k := intrinsics.count_trailing_zeros(itr.v)
itr.v &= itr.v - 1
defer itr.i += 1
return cast(E) k, itr.i, true
}
return {}, -1, false
}
itr := bit_set_iterator(&Bit_Set_Iterator{}, values)
for x, y in bit_set_next(itr, values) {
fmt.println(x, y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment