const MaxBits
MaxBits bounds a BitSet so allocation and iteration stay predictable.
Package bitset is a dense, fixed-capacity bit vector as a pure, reusable package: a compact set of small non-negative...
gno.land/p/moul/x/daily/bitset/v0Dense fixed-capacity bit vector — New, FromSlice, Set, Clear, Flip,
Has, Count, Slice, Clone, Union, Intersect, Difference,
SymmetricDifference, Equal, MaxBits.
A compact set of small non-negative integers. Storage is []uint64 of
ceil(n/64) words, so 1024 bits cost 16 words instead of 1024 booleans — the
reason to reach for this on chain, where every byte is paid for.
1import "gno.land/p/moul/x/daily/bitset/v0"
2
3b := bitset.FromSlice(20, []int{1, 2, 3})
4c := bitset.FromSlice(20, []int{3, 4})
5bitset.Union(b, c).Slice() // [1 2 3 4]
6bitset.Intersect(b, c).Slice() // [3]
7b.Count() // 3
Capacity is fixed at construction: operations are bounds-checked and return
false out of range rather than growing, because silent growth would make gas
unpredictable. Has on an out-of-range index is simply false — something that
cannot be a member is not a member.
Combining two sets of different capacities returns nil rather than padding
one silently; a size mismatch is a caller error worth surfacing.
MaxBits (65536) caps allocation. Note String() prints bit 0 first, so it
reads in index order — the reverse of binary notation.
Live demo: r/moul/x/daily/bitsetdemo
· render it at /r/moul/x/daily/bitsetdemo/v0.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package bitset is a dense, fixed-capacity bit vector as a pure, reusable package: a compact set of small non-negative integers with the usual set algebra (union, intersection, difference).
Storage is a []uint64 of ceil(n/64) words, so 1024 bits cost 16 words rather than 1024 booleans — the reason to reach for this on chain, where every byte is paid for.
Capacity is fixed at construction and every operation is bounds-checked rather than growing: an out-of-range index is a caller bug, and silently growing would make gas unpredictable.
A live demo of this package is at r/moul/x/daily/bitsetdemo(/r/moul/x/daily/bitsetdemo/v0).
Equal reports whether two sets have the same capacity and the same bits.
Difference returns a \ b, or nil when the capacities differ.
FromSlice builds a BitSet of capacity n containing the given indices. Out-of-range indices are ignored.
Intersect returns a ∩ b, or nil when the capacities differ.
New returns a BitSet holding bits [0, n). n is clamped to [0, MaxBits].
SymmetricDifference returns a △ b, or nil when the capacities differ.
Union returns a ∪ b, or nil when the capacities differ. Mismatched capacities are a caller error rather than something to silently pad.
BitSet is a fixed-capacity set of integers in [0, n).
Cap returns the capacity in bits.
Clear turns bit i off and reports whether i was in range.
Clone returns an independent copy.
Count returns the number of set bits (popcount).
Flip inverts bit i and reports whether i was in range.
Has reports whether bit i is set. Out of range is false, never a panic: membership of something that cannot be a member is simply false.
InRange reports whether i is a valid index.
Set turns bit i on and reports whether i was in range.
Slice returns the set bits in ascending order.
String renders the set as '0'/'1' from bit 0 upward, which reads left-to-right in index order (note this is the reverse of binary notation).