<style>
.math {
font-size: larger;
}
</style>
Small, fixed-size bitsets for storing integers/indices.
Provides up to six bitset types, one for each primitive unsigned integer. These types are:
| [`BitSet8`] | [`u8`] | b8 | **✓** |
| [`BitSet16`] | [`u16`] | b16 | **✓** |
| [`BitSet32`] | [`u32`] | b32 | **✓** |
| [`BitSet64`] | [`u64`] | b64 | **✓** |
| [`BitSet128`] | [`u128`] | b128 | **✗** |
| [`BitSetSize`] | [`usize`] | bsize | **✗** |
# Operations
All the following operations are designed to be...
- **fast:** 𝒪(1) time complexity
- **memory-efficient:** 𝒪(1) space complexity
- **intuitive:** similar interface to [`std::collections::HashSet`]
- **`const`-friendly:** usable inside `const` contexts
- **safe:** no `unsafe` code
## The Fundamentals
The following operators are fundamental enough to
[set theory] that they warrant operator overloads.
<table>
<tr>
<th>Math</th>
<th>Method Call</th>
<th>Overloaded Operators</th>
</tr>
<tr>
<td class="math">𝐴<sup>𝑐</sup></td>
<td><code>a.complement()</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/ops/trait.Neg.html#tymethod.neg">Neg::neg</a></code>
(<code>-a</code>)
<br/>
<code><a href="https://doc.rust-lang.org/core/ops/trait.Not.html#tymethod.not">Not::not</a></code>
(<code>!a</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 ∩ 𝐵</td>
<td><code>a.intersection(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/ops/trait.BitAnd.html#tymethod.bitand">BitAnd::bitand</a></code>
(<code>a & b</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 ∪ 𝐵</td>
<td><code>a.union(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/ops/trait.BitOr.html#tymethod.bitor">BitOr::bitor</a></code>
(<code>a | b</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 ∖ 𝐵</td>
<td><code>a.difference(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/ops/trait.Sub.html#tymethod.sub">Sub::sub</a></code>
(<code>a - b</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 Δ 𝐵</td>
<td><code>a.symmetric_difference(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/ops/trait.BitXor.html#tymethod.bitxor">BitXor::bitxor</a></code>
(<code>a ^ b</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 = 𝐵</td>
<td><code>a.is(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/cmp/trait.PartialEq.html#tymethod.eq">PartialEq::eq</a></code>
(<code>a == b</code>)
</td>
</tr>
<tr>
<td class="math">𝐴 ≠ 𝐵</td>
<td><code>a.is_not(b)</code></td>
<td>
<code><a href="https://doc.rust-lang.org/core/cmp/trait.PartialEq.html#tymethod.ne">PartialEq::ne</a></code>
(<code>a != b</code>)
</td>
</tr>
</table>
## Comparisons and Bitset Metadata
Bitsets support a variety of comparison operators. Though they aren't similar enough to methods in
[`core::cmp::PartialOrd`] to warrant operator overloads, they are still very useful tools for
working with sets.
Metadata-like methods (e.g., `len`) are lumped in with the comparisons because it is sometimes hard
to draw a line between them.
<table>
<tr>
<th>Math</th>
<th>Method Calls</th>
</tr>
<tr>
<td class="math">𝐴 ∩ 𝐵 = ∅</td>
<td><code>a.is_disjoint(b)</code></td>
</tr>
<tr>
<td class="math">𝐴 ⊆ 𝐵</td>
<td><code>a.is_subset(b)</code></td>
</tr>
<tr>
<td class="math">𝐴 ⊂ 𝐵</td>
<td><code>a.is_strict_subset(b)</code></td>
</tr>
<tr>
<td class="math">𝐴 ⊇ 𝐵</td>
<td><code>a.is_superset(b)</code></td>
</tr>
<tr>
<td class="math">𝐴 ⊃ 𝐵</td>
<td><code>a.is_strict_superset(b)</code></td>
</tr>
<tr>
<td class="math">𝐴 = ∅</td>
<td><code>a.is_empty()</code></td>
</tr>
<tr>
<td class="math">𝐴 = 𝑈</td>
<td><code>a.is_full()</code></td>
</tr>
<tr>
<td class="math">|𝐴|</td>
<td><code>a.len()</code></td>
</tr>
<tr>
<td class="math">𝑥 ∈ 𝐴</td>
<td><code>a.contains(x)</code></td>
</tr>
<tr>
<td class="math">min(𝐴)</td>
<td><code>a.min_index()</code></td>
</tr>
<tr>
<td class="math">max(𝐴)</td>
<td>
<code>a.max_index()</code>
<br/>
<code>a.max_index_checked()</code>
</td>
</tr>
</table>
## Miscellaneous
These don't have a direct connection to [set theory], but they are nice to have when working with
bitsets.
<table>
<tr>
<th>Math</th>
<th>Method Calls</th>
</tr>
<tr>
<td class="math">{ 𝑥 ∈ 𝐴 | 𝑥 < 𝑖 }</td>
<td>
<code>a.masked_0_to_i(i)</code>
<br/>
<code>a.cleared_i_to_N(i)</code>
<sup id="fnref2"><a href="#fn2">2</a></sup>
</td>
</tr>
<tr>
<td class="math">{ 𝑥 ∈ 𝐴 | 𝑥 ≥ 𝑖 }</td>
<td>
<code>a.masked_i_to_N(i)</code>
<sup id="fnref2"><a href="#fn2">2</a></sup>
<br/>
<code>a.cleared_0_to_i(i)</code>
</td>
</tr>
</table>
## Modification Methods
Because bitsets are meant to act like sets, they share many methods with
[`std::collections::HashSet`]. Some have been added as well for those who like to aggressively
optimize their code.
- `clear`
- `clear_0_to_i`
- `clear_i_to_N`
- `mask_0_to_i`
- `mask_i_to_N`
- `insert`
- `insert_quiet`
- `replace`
- `replace_quiet`
- `remove`
- `remove_quiet`
# Iteration
Each bitset also comes with two kinds of iterators:
- `BitSetIndices`: Iterates over the **indices** of the **enabled** bits.
- `BitSetIter`: Iterates over the **values** of **all** bits.
Both iterators can be used to traverse a set in either direction[^3]. For example, the following
code would iterate over the indices in ascending order:
```rust
use rose_bitsets::{Ascending, BitSet8};
let set = BitSet8::from_bits(0b00101110);
let mut indices = set.iter_indices::<Ascending>();
assert_eq!(indices.next(), Some(1));
assert_eq!(indices.next(), Some(2));
assert_eq!(indices.next(), Some(3));
assert_eq!(indices.next(), Some(5));
assert_eq!(indices.next(), None);
```
overloads inside `const` contexts.
progresses. The `Ascending` mode iterates starting from the least significant end and works towards
the most significant, whereas the `Descending` mode iterates starting from the most
significant end and works towards the least significant.
[`u8`]: https://doc.rust-lang.org/core/primitive.u8.html
[`u16`]: https://doc.rust-lang.org/core/primitive.u16.html
[`u32`]: https://doc.rust-lang.org/core/primitive.u32.html
[`u64`]: https://doc.rust-lang.org/core/primitive.u64.html
[`u128`]: https://doc.rust-lang.org/core/primitive.u128.html
[`usize`]: https://doc.rust-lang.org/core/primitive.usize.html
[`BitSet8`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSet8.html
[`BitSet16`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSet16.html
[`BitSet32`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSet32.html
[`BitSet64`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSet64.html
[`BitSet128`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSet128.html
[`BitSetSize`]: https://docs.rs/rose-bitsets/latest/rose_bitsets/struct.BitSetSize.html
[`core::cmp::PartialOrd`]: https://doc.rust-lang.org/core/cmp/trait.PartialOrd.html
[`std::collections::HashSet`]: https://doc.rust-lang.org/std/collections/struct.HashSet.html
[set theory]: https://en.wikipedia.org/wiki/Set_(mathematics)