pub struct Bitset<const N: usize, Z = u8>(pub Z)
where
Z: PosInt;Expand description
A set of bitflags representing positive integers in the range 1..=N.
For the rationale behind how this struct works, please visit the crate root.
§Type Parameters
N(required): The maximum integer represented by the set.- A
Bitset<N, _>represents integers1..=N, and will ignore integers outside this range.
- A
Z(optional): The unsigned integer type used to store the bitflags (e.g.u8,u16,usize).- Defaults to
u8, which allows the set to represent integers1..=256, which should be more than enough to cover most use cases.
- Defaults to
§Notes
- A subtle distinction is that
Zdictates how many integers the bitset could represent, whileNtells the struct and programmer how many it actually does represent. - To optimise space efficiency, you should make
Zas small as possible for your use caseN.- However, if you make it too small such that it can’t represent integers up to
N, you’ll likely encounter overflow errors caused by bitshifting.1
- However, if you make it too small such that it can’t represent integers up to
§Usage
Bitset is designed to be as ergonomic as possible. It does everything a HashSet<usize> could, while feeling like a 0b_xxxx_xxxx bitflag integer.
§Instantiation
When instantiating a Bitset, you’ll need to specify N.2
// A bitset representing numbers 1..=3
let bitset = Bitset::<3>::from([1,2,3]);
// A bitset representing numbers 1..=8
let bitset = Bitset::<8>::from([1,2,3,4,5,6,7,8]);
// or more conveniently:
let bitset = Bitset::<8>::all();
// or even more conveniently:
let bitset = byteset![1;8];
// A bitset representing numbers 1..=1000 (need a larger `Z`!)
let bitset = Bitset::<1000, u16>::none();
// Or instantiate manually, passing the bit representation directly:
let bitset = Bitset::<4>(0b_0101);
let equiv = Bitset::<4>::from([1,3]);
assert_eq!(bitset, equiv);§Access
To retrieve the integers the bitset represents, use .members():
use std::collections::HashSet;
let bitset = Bitset::<7>::from([1,3,7]);
let digits = bitset.members();
assert_eq!(digits, HashSet::from([1,3,7]));Bitset<Z> implements Deref<Z>, so the underlying bits can easily be accessed by dereferencing through *bitset.
let mut bitset = Bitset::<8>(0b_0100_1010);
assert_eq!(*bitset, 0b_0100_1010);
*bitset += 1;
assert_eq!(*bitset, 0b_0100_1011)§Operations
The union, intersection, difference set operations can be accessed via the |, &, / operations, respectively.
let left = byteset![1,2,3];
let right = byteset![3,4,5];
assert_eq!(left | right, byteset![1;5]);
assert_eq!(left & right, byteset![3]);
assert_eq!(left / right, byteset![1,2]);Add and remove individual elements via the + and - operators, respectively.
let mut bitset = byteset![1,2];
bitset += 3;
assert_eq!(bitset, byteset![1,2,3]);
bitset -= 1;
assert_eq!(bitset, byteset![2,3]);Tuple Fields§
§0: ZThe underlying integer used to represent the set. When written in binary, each bit represents whether a number is present in the set (1 if present, 0 if not).
Access this integer by dereferencing a Bitset:
let bitset = Bitset::<4>(0b_1011);
let bits = *bitset;
assert_eq!(bits, 0b_1011);Implementations§
Source§impl<Z, const N: usize> Bitset<N, Z>where
Z: PosInt,
impl<Z, const N: usize> Bitset<N, Z>where
Z: PosInt,
Sourcepub fn members(&self) -> HashSet<usize>
pub fn members(&self) -> HashSet<usize>
Get the integers present in the set.
§Usage
use std::collections::HashSet;
let bitset = byteset![1,3,7];
let nums = bitset.members();
assert_eq!(nums, HashSet::from([1,3,7]));Sourcepub fn max(&self) -> Option<usize>
pub fn max(&self) -> Option<usize>
Get the maximum integer present in the set, or 0 if the set is empty.
assert_eq!(byteset![].max(), None);
assert_eq!(byteset![1,2,6].max(), Some(6));Sourcepub fn single(&self) -> Option<usize>
pub fn single(&self) -> Option<usize>
If the set contains only 1 element, return it in a Some(), else None.
This is more convenient and efficient than bitset.is_single().then_some(bitset.max().unwrap()).
§Usage
assert_eq!( byteset![].single(), None );
assert_eq!( byteset![1;8].single(), None );
assert_eq!( byteset![1].single(), Some(1) );
assert_eq!( byteset![8].single(), Some(8) );Source§impl<Z, const N: usize> Bitset<N, Z>where
Z: PosInt + Debug,
impl<Z, const N: usize> Bitset<N, Z>where
Z: PosInt + Debug,
Sourcepub fn intersect_nonempty(
&mut self,
other: impl Into<Self>,
) -> Result<(), String>
pub fn intersect_nonempty( &mut self, other: impl Into<Self>, ) -> Result<(), String>
Intersect self with other, returning an Err if the intersection is empty.
Sourcepub fn intersect_nonempty_panicking(&mut self, other: impl Into<Self>)
pub fn intersect_nonempty_panicking(&mut self, other: impl Into<Self>)
Intersect self with other, panicking with debug output if the resultant intersection is empty.
Trait Implementations§
Source§impl<Z, R, const N: usize> AddAssign<R> for Bitset<N, Z>where
Z: PosInt,
R: Into<Z>,
impl<Z, R, const N: usize> AddAssign<R> for Bitset<N, Z>where
Z: PosInt,
R: Into<Z>,
Source§fn add_assign(&mut self, other: R)
fn add_assign(&mut self, other: R)
Add an integer other to the set. Does nothing if other is not in the range 1..=N.
Source§impl<Z, const N: usize> BitAndAssign for Bitset<N, Z>where
Z: PosInt,
impl<Z, const N: usize> BitAndAssign for Bitset<N, Z>where
Z: PosInt,
Source§fn bitand_assign(&mut self, other: Self)
fn bitand_assign(&mut self, other: Self)
&= operation. Read moreSource§impl<Z, const N: usize> BitOrAssign for Bitset<N, Z>where
Z: PosInt,
impl<Z, const N: usize> BitOrAssign for Bitset<N, Z>where
Z: PosInt,
Source§fn bitor_assign(&mut self, other: Self)
fn bitor_assign(&mut self, other: Self)
|= operation. Read moreSource§impl<Z, const N: usize> DivAssign for Bitset<N, Z>where
Z: PosInt,
impl<Z, const N: usize> DivAssign for Bitset<N, Z>where
Z: PosInt,
Source§fn div_assign(&mut self, other: Self)
fn div_assign(&mut self, other: Self)
/= operation. Read moreSource§impl<Z, T, const N: usize, const M: usize> From<[T; M]> for Bitset<N, Z>where
Z: PosInt,
T: AnyInt,
impl<Z, T, const N: usize, const M: usize> From<[T; M]> for Bitset<N, Z>where
Z: PosInt,
T: AnyInt,
Source§impl<Z, T, const N: usize> FromIterator<T> for Bitset<N, Z>where
Z: PosInt,
T: AnyInt,
impl<Z, T, const N: usize> FromIterator<T> for Bitset<N, Z>where
Z: PosInt,
T: AnyInt,
Source§fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = T>,
fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = T>,
Construct a Bitset from an iterator of integers, accepting only those in 1..=N and ignoring others.
Source§impl<Z, const N: usize> IntoIterator for Bitset<N, Z>where
Z: PosInt,
impl<Z, const N: usize> IntoIterator for Bitset<N, Z>where
Z: PosInt,
Source§impl<Z, R, const N: usize> SubAssign<R> for Bitset<N, Z>where
Z: PosInt,
R: Into<Z>,
impl<Z, R, const N: usize> SubAssign<R> for Bitset<N, Z>where
Z: PosInt,
R: Into<Z>,
Source§fn sub_assign(&mut self, other: R)
fn sub_assign(&mut self, other: R)
Remove an integer other from the set. Does nothing if other is not in the range 1..=N.