bittle

github crates.io docs.rs build status

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:


toml [dependencies] bittle = "0.5.1"


Guide

A bit is always identified by a [u32] by its index, and the exact location for a bit in a primitive numbers is defined by its endianness, which is [BigEndian] by default.

[BigEndian] indexing grows from right to left, such as the following [u8] literal:

text 0b0010_0010u8 ^ ^- index 1 '------ index 5


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]:

```rust use bittle::Bits;

let array: [u32; 4] = [0, 1, 2, 3]; assert!(array.iter_ones().eq([32, 65, 96, 97]));

let n = 0b00000000000000000000000000010001u32; assert!(n.iterones().eq([0, 4]));

let arrayofarrays: [[u8; 4]; 2] = [[16, 0, 0, 0], [0, 0, 1, 0]]; assert!(arrayofarrays.iter_ones().eq([4, 48]));

let mut vec: Vec = vec![0, 1, 2, 3]; assert!(vec.iter_ones().eq([32, 65, 96, 97])); ```


We also provide the [set!] macro, which is a zero-cost convenience method for constructing primitive forms of bit sets:

```rust use bittle::Bits;

let array: [u32; 4] = bittle::set![32, 65, 96, 97]; assert!(array.iter_ones().eq([32, 65, 96, 97]));

let n: u32 = bittle::set![0, 4]; assert!(n.iter_ones().eq([0, 4]));

let arrayofarrays: [[u8; 4]; 2] = bittle::set![4, 48]; assert!(arrayofarrays.iter_ones().eq([4, 48])); ```


Since a vector is not a primitive bit set, it could instead make use of [BitsMut] directly:

```rust use bittle::{Bits, BitsMut};

let mut vec: Vec = vec![0u32; 4]; vec.setbit(32); vec.setbit(65); vec.setbit(96); vec.setbit(97); assert!(vec.iterones().eq([32, 65, 96, 97])); asserteq!(vec, [0, 1, 2, 3]); ```


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:

```rust use bittle::{Bits, BitsMut};

let mut set = [0u16; 2];

set.setbit(15); assert!(set.testbit(15));

set.unionassign(&bittle::set![31, 7]); assert!(set.testbit(31) && set.test_bit(7));

set.clearbit(31); assert!(!set.testbit(31));

set.clearbits(); assert!(set.allzeros()); ```


Some other interesting operations, such as [Bits::join_ones] are available, allowing bitsets to act like masks over other iterators:

```rust use bittle::{Bits, BitsMut};

let elements = vec![10, 48, 101]; let mut m = 0u128;

m.setbit(0); assert!(m.joinones(&elements).eq([&10])); m.setbit(2); assert!(m.joinones(&elements).eq([&10, &101])); ```