Set this to the contents of ba.
Set this to the contents of ba.
Check if this has only ones.
Check if this has only zeros (is empty).
Get the i'th bit.
Find index (starting at currIx) of first bit that equals value.
Get number of bits set.
Get number of (zero) bits unset.
Get number of bits set divided by length.
Find index of first set (one) bit or typeof(return).max if no bit set.
Find index of first cleared (zero) bit or typeof(return).max if no bit set.
Support for foreach loops for StaticBitArray.
Support for binary operator & for StaticBitArray.
Support for binary operator | for StaticBitArray.
Support for binary operator ^ for StaticBitArray.
Support for binary operator - for StaticBitArray.
Convert to void[].
Convert to size_t[].
Supports comparison operators for StaticBitArray.
Complement operator.
Support for operators == and != for StaticBitArray.
Gets the i'th bit.
Get the i'th bit.
Sets the i'th bit. No range checking needed.
Support for operator &= for StaticBitArray.
Support for operator |= for StaticBitArray.
Support for operator ^= for StaticBitArray.
Support for operator -= for StaticBitArray.
Set all bits to value via slice assignment syntax.
Puts the i'th bit to b.
Reset all bits (to zero).
Get number of bits unset divided by length.
Support for hashing for StaticBitArray.
Return a string representation of this StaticBitArray.
Data as an array of unsigned bytes.
Number of bits per Block.
Number of Blocks.
Number of bits.
Gets the amount of native words backing this.
Duplicate.
Get pointer to data blocks.
Reverses the bits of the StaticBitArray in place.
Reverse block Block.
Sorts the StaticBitArray's elements.
Lazy range of the indices of set bits.
Bidirectional range into BitArray. * * TODO Provide opSliceAssign for interopability with range algorithms via * private static struct member Range. * * TODO Look at how std.container.array implements this. * * See_Also: https://dlang.org/phobos/std_bitmanip.html#bitsSet
run-time
import std.algorithm : equal; import nxt.rational : Rational; alias Q = Rational!ulong; enum m = 256; StaticBitArray!m b0; import nxt.modulo : Mod; static assert(is(typeof(b0.oneIndexes.front()) == Mod!m)); b0[1] = 1; b0[2] = 1; b0[m/2 - 11] = 1; b0[m/2 - 1] = 1; b0[m/2] = 1; b0[m/2 + 1] = 1; b0[m/2 + 11] = 1; b0[m - 3] = 1; b0[m - 2] = 1; assert(b0.oneIndexes.equal([1, 2, m/2 - 11, m/2 - 1, m/2, m/2 + 1, m/2 + 11, m - 3, m - 2].s[])); assert(b0.countOnes == 9);
run-time
import std.algorithm : equal; import nxt.rational : Rational; alias Q = Rational!ulong; enum m = 256; StaticBitArray!m b0; import nxt.modulo : Mod; static assert(is(typeof(b0.oneIndexes.front()) == Mod!m)); b0[0] = 1; b0[1] = 1; b0[m/2 - 11] = 1; b0[m/2 - 1] = 1; b0[m/2] = 1; b0[m/2 + 1] = 1; b0[m/2 + 11] = 1; b0[m - 2] = 1; b0[m - 1] = 1; assert(b0.oneIndexes.equal([0, 1, m/2 - 11, m/2 - 1, m/2, m/2 + 1, m/2 + 11, m - 2, m - 1].s[])); assert(b0.countOnes == 9);
ditto
import std.traits : isIterable; static assert(isIterable!(StaticBitArray!256));
test ubyte access
auto b8 = StaticBitArray!(8, ubyte)(); b8[0] = 1; b8[1] = 1; b8[3] = 1; b8[6] = 1; assert(b8.ubytes == [64 + 8 + 2 + 1].s[]); alias Ix = b8.Index; Ix nextIx; assert(b8.canFindIndexOf(true, Ix(0), nextIx)); assert(nextIx == 0); assert(b8.canFindIndexOf(true, Ix(1), nextIx)); assert(nextIx == 1); assert(b8.canFindIndexOf(true, Ix(2), nextIx)); assert(nextIx == 3); assert(b8.canFindIndexOf(true, Ix(3), nextIx)); assert(nextIx == 3); assert(b8.canFindIndexOf(true, Ix(4), nextIx)); assert(nextIx == 6); assert(!b8.canFindIndexOf(true, Ix(7), nextIx));
test all zero and all one predicates
static void test(size_t restBitCount)() { enum n = 8*size_t.sizeof + restBitCount; auto bs = StaticBitArray!(n, size_t)(); assert(bs.allZero); assert(!bs.allOne); foreach (immutable i; 0 .. n - 1) { bs[i] = true; assert(!bs.allZero); assert(!bs.allOne); } bs[n - 1] = true; assert(bs.allOne); } test!0; test!1; test!2; test!37; test!62; test!63;
ditto
import std.format : format; const b0_ = StaticBitArray!0([]); const b0 = b0_; assert(format("%s", b0) == "[]"); assert(format("%b", b0) is null); const b1_ = StaticBitArray!1([1]); const b1 = b1_; assert(format("%s", b1) == "[1]"); assert(format("%b", b1) == "1"); const b4 = StaticBitArray!4([0, 0, 0, 0]); assert(format("%b", b4) == "0000"); const b8 = StaticBitArray!8([0, 0, 0, 0, 1, 1, 1, 1]); assert(format("%s", b8) == "[0, 0, 0, 0, 1, 1, 1, 1]"); assert(format("%b", b8) == "00001111"); const b16 = StaticBitArray!16([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]); assert(format("%s", b16) == "[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]"); assert(format("%b", b16) == "00001111_00001111"); const b9 = StaticBitArray!9([1, 0, 0, 0, 0, 1, 1, 1, 1]); assert(format("%b", b9) == "1_00001111"); const b17 = StaticBitArray!17([1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]); assert(format("%b", b17) == "1_00001111_00001111");
test range
static testRange(Block)() { StaticBitArray!(6, Block) bs = [false, 1, 0, 0, true, 0]; bs.put(3, true); import std.algorithm : equal; assert(bs[0] == false); assert(bs[1] == true); assert(bs[2] == false); assert(bs[3] == true); assert(bs[4] == true); assert(bs[5] == false); assert(bs.at!0 == false); assert(bs.at!1 == true); assert(bs.at!2 == false); assert(bs.at!3 == true); assert(bs.at!4 == true); assert(bs.at!5 == false); // test slicing assert(bs[].equal([0, 1, 0, 1, 1, 0].s[])); assert(bs[1 .. 4].equal([1, 0, 1].s[])); auto rs = bs[1 .. 6 - 1]; // TODO Use opDollar assert(rs.length == 4); assert(rs.front == 1); assert(rs.back == 1); rs.popFront(); assert(rs.front == 0); assert(rs.back == 1); rs.popBack(); assert(rs.front == 1); assert(rs.back == 1); rs.popFront(); rs.popBack(); assert(rs.length == 0); assert(rs.empty); } import std.meta : AliasSeq; foreach (Block; AliasSeq!(ubyte, ushort, uint, ulong, size_t)) { testRange!Block; }
alias Block = size_t; enum blockCount = 2; enum n = blockCount * 8*Block.sizeof - 1; StaticBitArray!(n) x; static assert(x.blockCount == blockCount); assert(x.indexOfFirstOne == n); x[n - 1] = true; assert(x.indexOfFirstOne == x.length - 1); x[n - 2] = true; assert(x.indexOfFirstOne == x.length - 2); x[n/2 + 1] = true; assert(x.indexOfFirstOne == x.length/2 + 1); x[n/2] = true; assert(x.indexOfFirstOne == x.length/2); x[n/2 - 1] = true; assert(x.indexOfFirstOne == x.length/2 - 1); x[0] = true; assert(x.indexOfFirstOne == 0); assert(x[0]); assert(!x[1]); x[1] = true; assert(x[1]); x[1] = false; assert(!x[1]);
Test opSliceAssign.
alias Block = size_t; enum blockCount = 2; enum n = blockCount * 8*Block.sizeof - 1; StaticBitArray!(n) x; assert(x.countOnes == 0); x[] = true; assert(x.countOnes == n); x[] = false; assert(x.countOnes == 0);
A statically sized std.bitmanip.BitArray.
TODO Infer Block from len as is done for Bound and Mod.
TODO Optimize allOne, allZero using intrinsic?