bittle
Zero-cost bitsets over native Rust types.
The name bittle comes from bit and little. Small bitsets!
Usage
Add bittle as a dependency in your Cargo.toml:
[]
= "0.4.3"
Guide
A bit is always identified by a [u32] by its index, and the exact location
for primitive numbers is that the least significant bit corresponds to the
lowest index, and the most significant bit is the highest (see issue #2).
This is called "shift left indexing" and doesn't correspond with what
literals look like when reading them left-to-right:
0b0010_0010u8
^ ^- index 1
'------ index 5
It gets a bit more confusing when considering arrays, since each element in the array defines a span of bits which does increase left-to-right:
0 --------- 8 8 -------- 15
[0b0010_0010u8, 0b1000_0000u8]
^ ^ ^- index 15
| '--------- index 1
'-------------- index 5
Note: shift right indexing is available experimentally under the
--cfg bittle_shrflag for benchmarking.
To interact with these bits we define the Bits, BitsMut, and
BitsOwned traits. These traits are implemented for primitive types such
as u32, [u32; 4], or &[u32]:
use Bits;
let array: = ;
assert!;
let n = 0b00000000_00000000_00000000_00010001u32;
assert!;
let array_of_arrays: = ;
assert!;
let mut vec: = vec!;
assert!;
We also provide the set! macro, which is a zero-cost convenience method
for constructing primitive forms of bit sets:
use Bits;
let array: = set!;
assert!;
let n: u32 = set!;
assert!;
let array_of_arrays: = set!;
assert!;
Since a vector is not a primitive bit set, it could instead make use of
BitsMut directly:
use ;
let mut vec: = vec!;
vec.set_bit;
vec.set_bit;
vec.set_bit;
vec.set_bit;
assert!;
assert_eq!;
Due to how broadly these traits are implemented, we also try to avoid using names which are commonly used in other APIs, instead opt for bit-specific terminology such as:
- Something like
is_emptybecomesall_zeros- since with bits you're thinking about "ones and zeros". - Testing if a bit is set is
test_bit, or in general adding the*_bitsuffix to operations over individual bits. - Clearing all bits becomes
clear_bits, or in general adding the*_bitssuffix when operating over all bits.
use ;
let mut set = ;
set.set_bit;
assert!;
set.union_assign;
assert!;
set.clear_bit;
assert!;
set.clear_bits;
assert!;
Some other interesting operations, such as Bits::join_ones are available,
allowing bitsets to act like masks over other iterators:
use ;
let elements = vec!;
let mut m = 0u128;
m.set_bit;
assert!;
m.set_bit;
assert!;