Skip to content

Latest commit

 

History

History
98 lines (74 loc) · 2.28 KB

README.md

File metadata and controls

98 lines (74 loc) · 2.28 KB

bitmask

Go Reference Coverage Badge

Arbitrary size bitmask (aka bitset) with efficient Slice method.

.Slice doesn't create copies of the underlying buffer, just like Go slices

bm := bitmask.New(4)        // [4]{0000}
bm.Set(3)                   // [4]{0001}
bm.Slice(2, 4).ToggleAll()  // [4]{0010}
bm.Slice(1, 3).ToggleAll()  // [4]{0100}
bm.Slice(0, 2).ToggleAll()  // [4]{1000}
bm.ClearAll()               // [4]{0000}

It's safe to copy overlapping bitmasks, which were created by slicing the original one

base := bitmask.New(10)
base.Set(0)
base.Set(9)                 // [10]{1000000001}

src := base.Slice(0, 8)     // [8]{10000000}
dst := base.Slice(2, 10)    // [8]{00000001}

bitmask.Copy(dst, src)

fmt.Println(base)
[10]{1010000000}

Iterator

Go >=1.23 iterator is exposed by .Bits() method:

bm := bitmask.New(5)
bm.Set(0)
bm.Set(3)

for idx, isSet := range bm.Bits() {
    // use the value
    fmt.Printf("%v) %v\n", index, value)
}

There's also an old-style equivalent:

it := bm.Iterator()
for {
    ok, value, index := it.Next()
    if !ok {
        break
    }

    // use the value
    fmt.Printf("%v) %v\n", index, value)
}
0) true
1) false
2) false
3) true
4) false

.String() is O(1), it starts stripping after 512 bits

bm := bitmask.New(513)
bm.Slice(255, 321).SetAll()
fmt.Println(bm)
[513]{0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 <more 64 bits> 1000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0}

Non-copying constructor to avoid heap-allocating bit buffer

bm := bitmask.NewFromUintRawNocopy(1, 2, 3)

From go build -gcflags=-m

inlining call to bitmask.NewFromUintRawNocopy
... argument does not escape
&bitmask.BitMask{...} does not escape