growable_bitmap/
storage.rs

1/// Named to clarify bit/byte operations.
2pub const BITS_IN_BYTE: usize = 8;
3
4/// Types implementing this trait can be used as storage for a `GrowableBitmap`.
5///
6/// Only fixed-size types should implement this: see the `BITS_IN_STORAGE`
7/// constant requirement for this trait.
8///
9/// # Safety
10///
11/// This trait exposes several methods that are `unsafe` to call.
12///
13/// The given `index` must fit in `0..<Self as BitStorage>::BITS_IN_STORAGE`
14/// for the behaviour of the `unsafe` methods to be correct.
15pub unsafe trait BitStorage: Sized {
16    /// Number of bits that can be stored in one instance of `Self`.
17    ///
18    /// This is a constant and types implementing this trait guarantee this
19    /// will always be exact.
20    const BITS_IN_STORAGE: usize = std::mem::size_of::<Self>() * BITS_IN_BYTE;
21
22    /// Construct a new, empty instance of a `BitStorage` type.
23    ///
24    /// # Examples
25    ///
26    /// ```rust
27    /// use growable_bitmap::BitStorage;
28    ///
29    /// let a = u8::empty();
30    /// assert_eq!(a, 0);
31    /// ```
32    fn empty() -> Self;
33
34    /// Returns `true` is the storage is considered empty (no `1`s anywhere).
35    ///
36    /// # Examples
37    ///
38    /// ```rust
39    /// use growable_bitmap::BitStorage;
40    ///
41    /// let a = u16::empty();
42    /// assert!(a.is_empty());
43    ///
44    /// let a = 1_u16 << 2;
45    /// assert!(!a.is_empty());
46    /// ```
47    fn is_empty(&self) -> bool;
48
49    /// Gets the bit at the given index and returns `true` when it is set
50    /// to 1, `false` when it is not.
51    ///
52    /// # Safety
53    ///
54    /// The given `index` must fit in `0..<Self as BitStorage>::BITS_IN_STORAGE`
55    /// for the behaviour of this method to be correct.
56    ///
57    /// # Examples
58    ///
59    /// ```rust
60    /// use growable_bitmap::BitStorage;
61    ///
62    /// let a = u32::empty();
63    /// assert!(unsafe { !a.get_bit(2) });
64    ///
65    /// let a = 1_u32 << 2;
66    /// assert!(unsafe { a.get_bit(2) });
67    /// ```
68    unsafe fn get_bit(&self, index: usize) -> bool;
69
70    /// Sets the bit at the given index and returns `true` when it is set
71    /// to 1 by this call, `false` when it was already 1.
72    ///
73    /// # Safety
74    ///
75    /// The given `index` must fit in `0..<Self as BitStorage>::BITS_IN_STORAGE`
76    /// for the behaviour of this method to be correct.
77    ///
78    /// # Examples
79    ///
80    /// ```rust
81    /// use growable_bitmap::BitStorage;
82    ///
83    /// let mut a = u64::empty();
84    ///
85    /// assert!(unsafe { a.set_bit(0) });
86    /// assert!(unsafe { a.get_bit(0) });
87    ///
88    /// assert!(unsafe { a.set_bit(7) });
89    /// assert!(unsafe { a.get_bit(7) });
90    ///
91    /// assert!(unsafe { !a.set_bit(0) });
92    /// ```
93    unsafe fn set_bit(&mut self, index: usize) -> bool;
94
95    /// Clears the bit at the given index and returns `true` when it is set
96    /// to 0 by this call, `false` when it was already 0.
97    ///
98    /// # Safety
99    ///
100    /// The given `index` must fit in `0..<Self as BitStorage>::BITS_IN_STORAGE`
101    /// for the behaviour of this method to be correct.
102    ///
103    /// # Examples
104    ///
105    /// ```rust
106    /// use growable_bitmap::BitStorage;
107    ///
108    /// let mut a = u64::empty();
109    ///
110    /// assert!(unsafe { !a.clear_bit(56) });
111    ///
112    /// assert!(unsafe { a.set_bit(56) });
113    /// assert!(unsafe { a.clear_bit(56) });
114    /// assert!(unsafe { !a.get_bit(56) });
115    /// ```
116    unsafe fn clear_bit(&mut self, index: usize) -> bool;
117
118    /// Clears the whole storage, setting `self` to the empty value.
119    ///
120    /// The default implementation uses `*self = Self::empty()`.
121    ///
122    /// # Examples
123    ///
124    /// ```rust
125    /// use growable_bitmap::BitStorage;
126    ///
127    /// let mut a = u128::empty();
128    ///
129    /// let mut a: u128 = 42;
130    /// a.clear_all();
131    /// assert!(a.is_empty());
132    ///
133    /// let mut a: u128 = 1 << 120;
134    /// a.clear_all();
135    /// assert!(a.is_empty());
136    /// ```
137    fn clear_all(&mut self) {
138        *self = Self::empty();
139    }
140
141    /// Returns the number of bits set to 1 in `Self`.
142    ///
143    /// # Examples
144    ///
145    /// ```rust
146    /// use growable_bitmap::BitStorage;
147    ///
148    /// let a = u8::empty();
149    /// assert_eq!(a.count_ones(), 0);
150    ///
151    /// let mut a = a;
152    /// unsafe { a.set_bit(0); }
153    /// assert_eq!(a.count_ones(), 1);
154    ///
155    /// unsafe { a.set_bit(3); }
156    /// assert_eq!(a.count_ones(), 2);
157    ///
158    /// unsafe { a.set_bit(7); }
159    /// assert_eq!(a.count_ones(), 3);
160    ///
161    /// unsafe { a.clear_bit(4); }
162    /// assert_eq!(a.count_ones(), 3);
163    ///
164    /// unsafe { a.clear_bit(7); }
165    /// assert_eq!(a.count_ones(), 2);
166    ///
167    /// a.clear_all();
168    /// assert_eq!(a.count_ones(), 0);
169    /// ```
170    fn count_ones(&self) -> usize;
171
172    /// Returns the index of the first bit set in the binary representation of
173    /// `self`, if any, else returns `None`.
174    ///
175    /// # Example
176    ///
177    /// Example on a u8 where the least significant bit is to the right:
178    ///
179    /// ```text
180    /// 0b1100_0100
181    ///         ^
182    ///         index = 3
183    /// ```
184    ///
185    /// ```rust
186    /// use growable_bitmap::BitStorage;
187    ///
188    /// let v = u16::empty();
189    /// assert_eq!(v.first_bit_set(), None);
190    ///
191    /// let mut v = v;
192    /// unsafe { v.set_bit(3); }
193    /// assert_eq!(v.first_bit_set(), Some(3));
194    ///
195    /// unsafe { v.set_bit(7); }
196    /// assert_eq!(v.first_bit_set(), Some(3));
197    ///
198    /// unsafe { v.set_bit(1); }
199    /// assert_eq!(v.first_bit_set(), Some(1));
200    /// ```
201    fn first_bit_set(&self) -> Option<usize>;
202
203    /// Returns the index of the last bit set in the binary representation of
204    /// `self`, if any, else returns `None`.
205    ///
206    /// # Example
207    ///
208    /// Example on a u8 where the least significant bit is to the right:
209    ///
210    /// ```text
211    /// 0b0010_0011
212    ///     ^
213    ///     index = 5
214    /// ```
215    ///
216    /// ```rust
217    /// use growable_bitmap::BitStorage;
218    ///
219    /// let v = u16::empty();
220    /// assert_eq!(v.last_bit_set(), None);
221    ///
222    /// let mut v = v;
223    /// unsafe { v.set_bit(3); }
224    /// assert_eq!(v.last_bit_set(), Some(3));
225    ///
226    /// unsafe { v.set_bit(1); }
227    /// assert_eq!(v.last_bit_set(), Some(3));
228    ///
229    /// unsafe { v.set_bit(7); }
230    /// assert_eq!(v.last_bit_set(), Some(7));
231    /// ```
232    fn last_bit_set(&self) -> Option<usize>;
233}
234
235macro_rules! bit_storage_integer_impl {
236    ($int: ty, $doc: expr) => {
237        #[doc = $doc]
238        unsafe impl BitStorage for $int {
239            #[inline(always)]
240            fn empty() -> Self { 0 }
241
242            #[inline(always)]
243            fn is_empty(&self) -> bool {
244                *self == Self::empty()
245            }
246
247            unsafe fn get_bit(&self, index: usize) -> bool {
248                let mask = 1 << index;
249                (*self & mask) != 0
250            }
251
252            unsafe fn set_bit(&mut self, index: usize) -> bool {
253                let mask = 1 << index;
254                let prev = *self & mask;
255
256                *self |= mask;
257                prev == 0
258            }
259
260            unsafe fn clear_bit(&mut self, index: usize) -> bool {
261                let mask = 1 << index;
262                let prev = *self & mask;
263
264                *self &= !mask;
265                prev != 0
266            }
267
268            #[inline(always)]
269            fn count_ones(&self) -> usize {
270                <$int>::count_ones(*self) as usize
271            }
272
273            fn first_bit_set(&self) -> Option<usize> {
274                if *self == Self::empty() {
275                    None
276                } else {
277                    // Example on a u8 where the least significant bit
278                    // is to the right:
279                    //
280                    // 0b1100_0100
281                    //         ^
282                    //         index = 3
283                    let mut mask = 1;
284                    for idx in 0..Self::BITS_IN_STORAGE {
285                        if *self & mask != 0 { return Some(idx); }
286                        mask <<= 1;
287                    }
288                    // Since the case for 0 has been checked for earlier,
289                    // it is guaranteed that at least one bit is set to 1.
290                    unreachable!()
291                }
292            }
293
294            fn last_bit_set(&self) -> Option<usize> {
295                if *self == Self::empty() {
296                    None
297                } else {
298                    // Example on a u8 where the least significant bit
299                    // is to the right:
300                    //
301                    // 0b0010_0011
302                    //     ^
303                    //     index = 5
304                    let mut mask = 1 << (Self::BITS_IN_STORAGE - 1);
305                    for idx in (0..=(Self::BITS_IN_STORAGE - 1)).rev() {
306                        if *self & mask != 0 { return Some(idx); }
307                        mask >>= 1;
308                    }
309                    // Since the case for 0 has been checked for earlier,
310                    // it is guaranteed that at least one bit is set to 1.
311                    unreachable!()
312                }
313            }
314        }
315    };
316    ($int: ty) => {
317        bit_storage_integer_impl! {
318            $int,
319            concat!(
320                "SAFETY: this implementation is safe because the width in ",
321                "bits of an `",
322                stringify!($int),
323                "` is fixed and equal to `std::mem::size_of::<",
324                stringify!($int),
325                ">() * 8`.",
326            )
327        }
328    };
329}
330
331bit_storage_integer_impl! { u8 }
332bit_storage_integer_impl! { u16 }
333bit_storage_integer_impl! { u32 }
334bit_storage_integer_impl! { u64 }
335bit_storage_integer_impl! { u128 }
336
337macro_rules! bit_storage_integer_tests {
338    ($(($int: ty, $mod_name: ident))*) => {
339        $(
340            #[cfg(test)]
341            mod $mod_name {
342                use super::*;
343
344                #[test]
345                fn empty() {
346                    assert_eq!(<$int>::empty(), 0);
347                }
348
349                #[test]
350                fn is_empty() {
351                    assert!(<$int>::empty().is_empty());
352                    let v: $int = 3;
353                    assert!(!v.is_empty());
354                }
355
356                #[test]
357                fn get_bit() {
358                    let v = <$int>::empty();
359                    assert!(unsafe { !v.get_bit(0) });
360                    assert!(unsafe { !v.get_bit(7) });
361
362                    let v: $int = 1 << 3;
363                    assert!(unsafe { !v.get_bit(0) });
364                    assert!(unsafe { v.get_bit(3) });
365                }
366
367                #[test]
368                fn set_bit() {
369                    let mut v = <$int>::empty();
370
371                    assert!(unsafe { v.set_bit(0) });
372                    assert!(unsafe { v.get_bit(0) });
373
374                    assert!(unsafe { v.set_bit(7) });
375                    assert!(unsafe { v.get_bit(7) });
376
377                    assert!(unsafe { !v.set_bit(0) });
378                }
379
380                #[test]
381                fn clear_bit() {
382                    let mut v = <$int>::empty();
383
384                    assert!(unsafe { !v.clear_bit(0) });
385
386                    assert!(unsafe { v.set_bit(0) });
387                    assert!(unsafe { v.clear_bit(0) });
388                    assert!(unsafe { !v.get_bit(0) });
389                }
390
391                #[test]
392                fn clear_all() {
393                    let mut v: $int = 42;
394                    v.clear_all();
395                    assert!(v.is_empty());
396
397                    let mut v: $int = 1 << 3;
398                    v.clear_all();
399                    assert!(v.is_empty());
400                }
401
402                #[test]
403                fn count_ones() {
404                    let v = <$int>::empty();
405                    assert_eq!(v.count_ones(), 0);
406
407                    let mut v = v;
408                    unsafe { v.set_bit(0); }
409                    assert_eq!(v.count_ones(), 1);
410
411                    unsafe { v.set_bit(3); }
412                    assert_eq!(v.count_ones(), 2);
413
414                    unsafe { v.set_bit(7); }
415                    assert_eq!(v.count_ones(), 3);
416
417                    unsafe { v.clear_bit(4); }
418                    assert_eq!(v.count_ones(), 3);
419
420                    unsafe { v.clear_bit(7); }
421                    assert_eq!(v.count_ones(), 2);
422
423                    v.clear_all();
424                    assert_eq!(v.count_ones(), 0);
425                }
426
427                #[test]
428                fn first_bit_set() {
429                    let v = <$int>::empty();
430                    assert_eq!(v.first_bit_set(), None);
431
432                    let mut v = v;
433                    unsafe { v.set_bit(3); }
434                    assert_eq!(v.first_bit_set(), Some(3));
435
436                    unsafe { v.set_bit(7); }
437                    assert_eq!(v.first_bit_set(), Some(3));
438
439                    unsafe { v.set_bit(1); }
440                    assert_eq!(v.first_bit_set(), Some(1));
441                }
442
443                #[test]
444                fn last_bit_set() {
445                    let v = <$int>::empty();
446                    assert_eq!(v.last_bit_set(), None);
447
448                    let mut v = v;
449                    unsafe { v.set_bit(3); }
450                    assert_eq!(v.last_bit_set(), Some(3));
451
452                    unsafe { v.set_bit(1); }
453                    assert_eq!(v.last_bit_set(), Some(3));
454
455                    unsafe { v.set_bit(7); }
456                    assert_eq!(v.last_bit_set(), Some(7));
457                }
458            }
459        )*
460    }
461}
462
463bit_storage_integer_tests! {
464    (u8, test_u8)
465    (u16, test_u16)
466    (u32, test_u32)
467    (u64, test_u64)
468    (u128, test_u128)
469}