index_set/bitset_mut.rs
1/// A trait for a mutate values in a bit set.
2pub trait BitSetMut<T> {
3 /// Clears the set
4 ///
5 /// # Example
6 ///
7 /// ```rust
8 /// use index_set::{BitSet, BitSetMut};
9 ///
10 /// let mut bitset: [u32; 4] = [0; 4];
11 /// bitset.insert(0);
12 /// assert!(!BitSet::is_empty(&bitset[..]));
13 ///
14 /// bitset.clear();
15 /// assert!(BitSet::is_empty(&bitset[..]));
16 /// ```
17 fn clear(&mut self);
18
19 /// Inserts the value into the set.
20 ///
21 /// Returns `true` if the value was already set.
22 /// Returns `None` if the set cannot hold the value.
23 ///
24 /// # Example
25 ///
26 /// ```rust
27 /// use index_set::{BitSet, BitSetMut};
28 ///
29 /// let mut bitset: [u32; 4] = [0; 4];
30 /// bitset.insert(0);
31 /// assert_eq!(bitset.has(0), true);
32 /// ```
33 fn insert(&mut self, _: T) -> Option<bool>;
34
35 /// Removes the value from the set
36 ///
37 /// Returns `Some(true)` if the value was already set.
38 /// Returns `None` if the set cannot hold the value.
39 ///
40 /// # Example
41 ///
42 /// ```rust
43 /// use index_set::{BitSet, BitSetMut};
44 ///
45 /// let mut bitset: [u32; 4] = [0; 4];
46 /// bitset.insert(42);
47 /// assert_eq!(bitset.has(42), true);
48 ///
49 /// bitset.remove(42);
50 /// assert_eq!(bitset.has(42), false);
51 /// ```
52 fn remove(&mut self, _: T) -> Option<bool>;
53}
54
55macro_rules! impl_deref_mut {
56 ($($target: ty),*) => {$(
57 impl<Set, T> BitSetMut<T> for $target
58 where
59 Set: BitSetMut<T> + ?Sized,
60 {
61 #[inline]
62 fn clear(&mut self) {
63 BitSetMut::clear(&mut **self)
64 }
65
66 #[inline]
67 fn insert(&mut self, index: T) -> Option<bool> {
68 BitSetMut::insert(&mut **self, index)
69 }
70
71 #[inline]
72 fn remove(&mut self, index: T) -> Option<bool> {
73 BitSetMut::remove(&mut **self, index)
74 }
75 }
76 )*}
77}
78
79impl_deref_mut! {
80 &mut Set, Box<Set>
81}
82
83macro_rules! impl_bit_set_mut {
84 [$($ty:tt),*] => {$(
85 impl BitSetMut<$ty> for [$ty] {
86 fn clear(&mut self) {
87 for slot in self {
88 *slot = 0;
89 }
90 }
91
92 #[inline]
93 fn insert(&mut self, index: $ty) -> Option<bool> {
94 let slot_idx = usize::try_from(index / $ty::BITS as $ty).ok()?;
95 let mask = 1 << (index % $ty::BITS as $ty);
96 let slot = self.get_mut(slot_idx)?;
97
98 let old_value = *slot & mask != 0;
99 *slot |= mask;
100 Some(old_value)
101 }
102
103 #[inline]
104 fn remove(&mut self, index: $ty) -> Option<bool> {
105 let slot_idx = usize::try_from(index / $ty::BITS as $ty).ok()?;
106 let mask = 1 << (index % $ty::BITS as $ty);
107 let slot = self.get_mut(slot_idx)?;
108
109 let old_value = *slot & mask != 0;
110 *slot &= !mask;
111 Some(old_value)
112 }
113 }
114 )*};
115}
116
117impl_bit_set_mut! {
118 u32, u64, usize, u128
119}