fixed_bitmaps/primitives/
bitmap128.rs

1use super::BitmapSize;
2use core::fmt::Formatter;
3use serde::{Deserialize, Serialize};
4use std::{
5    fmt::{Debug, Display},
6    mem,
7    ops::{
8        Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, Div,
9        DivAssign, Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
10    },
11};
12
13/// A bitmap of length 128.
14///
15/// # Examples
16/// ```rust
17/// // Creates an empty bitmap
18/// use fixed_bitmaps::Bitmap128;
19///
20/// let mut bitmap = Bitmap128::default();
21///
22/// // Bitmaps implement Display so you can view what the map looks like
23/// println!("Default bitmap: {}", bitmap);
24///
25/// // Bitmaps also convert to their respective unsigned int versions and back again easily
26/// // Will show 0 as the value of the bitmap
27/// println!("Value of bitmap: {}", bitmap.to_u128());
28///
29/// // Let's do the same as above, but actually setting the values in the bitmap to something
30/// bitmap |= Bitmap128::from(101);
31///
32/// println!("Bitmap after OR-ing with 101: {}", bitmap);
33///
34/// // Set the 4th index (the 5th bit) to true. Can simply unwrap the result to ignore the warning,
35/// //as we know for certain that 4 < 128
36/// bitmap.set(4, true).unwrap();
37///
38/// // Will show that 117 (101 + 2^4) is the value of the bitmap
39/// println!("Bitmap value: {}", bitmap.to_u128());
40///
41/// // Or you could use the deref operator for an even easier conversion
42/// println!("Bitmap value: {}", *bitmap);
43/// ```
44#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Default, Serialize, Deserialize)]
45pub struct Bitmap128(u128);
46
47impl Bitmap128 {
48    pub fn capacity() -> usize {
49        Bitmap128::MAP_LENGTH
50    }
51
52    pub fn to_u128(&self) -> u128 {
53        self.0
54    }
55
56    /// Creates a new bitmap with all bits set to the given value.
57    ///
58    /// ## Example
59    ///
60    /// ```rust
61    /// use fixed_bitmaps::Bitmap128;
62    ///
63    /// let a = Bitmap128::new(true);
64    /// assert_eq!(*a, u128::MAX);
65    ///
66    /// let b = Bitmap128::new(false);
67    /// assert_eq!(*b, 0);
68    /// ```
69    pub fn new(value: bool) -> Bitmap128 {
70        Bitmap128(if value { u128::MAX } else { 0 })
71    }
72
73    /// Create a new bitmap that has its bits set from `begin` (inclusive) to `end` (exclusive).
74    /// If begin is greater than the map length or end is 0, will return a bitmap with all bits set to
75    /// the opposite of value.
76    ///
77    /// ## Example
78    ///
79    /// ```rust
80    /// use fixed_bitmaps::Bitmap128;
81    ///
82    /// let a = Bitmap128::create_bit_mask(3, 7, true);
83    /// assert_eq!(*a, 0b1111000);
84    ///
85    /// let b = Bitmap128::create_bit_mask(3, 6, false); // Results in 1..1000111
86    /// assert_eq!(b, Bitmap128::new(true) ^ 0b111000);
87    /// ```
88    pub fn create_bit_mask(begin: usize, end: usize, value: bool) -> Bitmap128 {
89        if value {
90            if begin >= Bitmap128::MAP_LENGTH || end < 1 {
91                Bitmap128(0)
92            } else if end >= Bitmap128::MAP_LENGTH {
93                Bitmap128(u128::MAX << begin)
94            } else {
95                Bitmap128(u128::MAX << begin & u128::MAX >> Bitmap128::MAP_LENGTH - end)
96            }
97        } else {
98            !Bitmap128::create_bit_mask(begin, end, true)
99        }
100    }
101
102    /// Creates a new, empty `Bitmap128`, and sets the desired index before returning.
103    ///
104    /// ```rust
105    /// use fixed_bitmaps::Bitmap128;
106    ///
107    /// let a = Bitmap128::from_set(5).unwrap();
108    ///
109    /// // The above is equivalent to:
110    ///
111    /// let mut b = Bitmap128::from(0);
112    /// b.set(5, true);
113    ///
114    /// assert_eq!(a, b);
115    /// ```
116    pub fn from_set(index: usize) -> Option<Bitmap128> {
117        if index >= Bitmap128::MAP_LENGTH {
118            return None;
119        }
120
121        let mut bitmap = Bitmap128::default();
122        bitmap.set(index, true).unwrap();
123        Some(bitmap)
124    }
125
126    /// Sets the desired index, to the value provided. Note that indexing starts
127    /// at 0.
128    ///
129    /// ## Returns
130    ///
131    /// Returns a `Result` based on the outcome. If an `Err<String>` was returned,
132    /// it was because an out-of-bounds index was attempted to be set. In that
133    /// case the bitmap's state remains unchanged.
134    ///
135    /// ## Example
136    ///
137    /// ```rust
138    /// use fixed_bitmaps::Bitmap128;
139    ///
140    /// let mut bitmap = Bitmap128::default();
141    /// assert_eq!(*bitmap, 0);
142    ///
143    /// bitmap.set(4, true);
144    /// assert_eq!(*bitmap, 16);
145    /// ```
146    pub fn set(&mut self, index: usize, value: bool) -> Result<(), String> {
147        if index >= Bitmap128::MAP_LENGTH {
148            return Err(String::from(
149                "Tried to set bit that's out of range of the bitmap (range: ",
150            ) + &Bitmap128::MAP_LENGTH.to_string()
151                + ", index: "
152                + &index.to_string()
153                + ")");
154        }
155
156        if value {
157            let mask = 1 << index;
158            self.0 |= mask;
159        } else {
160            let mask = u128::MAX - (1 << index);
161            self.0 &= mask;
162        }
163
164        Ok(())
165    }
166
167    /// Set bits from begin (inclusive) to end (exclusive) to the given value.
168    ///
169    /// ## Example
170    ///
171    /// ```rust
172    /// use fixed_bitmaps::Bitmap128;
173    ///
174    /// let mut bitmap = Bitmap128::default();
175    /// assert_eq!(*bitmap, 0);
176    ///
177    /// bitmap.set_range(2, 7, true);
178    /// assert_eq!(*bitmap, 0b1111100);
179    ///
180    /// bitmap.set_range(3, 5, false);
181    /// assert_eq!(*bitmap, 0b1100100);
182    /// ```
183    pub fn set_range(&mut self, begin: usize, end: usize, value: bool) {
184        if value {
185            *self |= Bitmap128::create_bit_mask(begin, end, true);
186        } else {
187            *self &= Bitmap128::create_bit_mask(begin, end, false);
188        }
189    }
190
191    /// Gets the bit at the given index. Note that indexing starts at 0.
192    ///
193    /// ## Returns
194    ///
195    /// Returns a `Result` based on the outcome.
196    ///
197    /// If `Ok<bool>` is returned, then the contained value in ok is the state
198    /// of the given bit
199    ///
200    /// If an `Err<String>` was returned, it was because you tried to get
201    /// an out-of-bounds index.
202    ///
203    /// ## Example
204    ///
205    /// ```rust
206    /// use fixed_bitmaps::Bitmap128;
207    ///
208    /// let bitmap = Bitmap128::from(0b1010);
209    /// assert_eq!(bitmap.get(2).unwrap(), false);
210    /// assert_eq!(bitmap.get(3).unwrap(), true);
211    /// ```
212    pub fn get(&self, index: usize) -> Result<bool, String> {
213        if index >= Bitmap128::MAP_LENGTH {
214            return Err(String::from(
215                "Tried to get bit that's out of range of the bitmap (range: ",
216            ) + &Bitmap128::MAP_LENGTH.to_string()
217                + ", index: "
218                + &index.to_string()
219                + ")");
220        }
221
222        let mask = 1 << index;
223        Ok(self.0 & mask > 0)
224    }
225}
226
227impl Display for Bitmap128 {
228    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
229        write!(f, "{:b}", self.0)
230    }
231}
232
233impl Debug for Bitmap128 {
234    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
235        write!(f, "Bitmap128({:X})", self.0)
236    }
237}
238
239impl From<u128> for Bitmap128 {
240    fn from(value: u128) -> Self {
241        Bitmap128(value)
242    }
243}
244
245impl BitmapSize for Bitmap128 {
246    const MAP_LENGTH: usize = mem::size_of::<u128>() * 8;
247}
248
249// Traits implementing bitwise operations between Bitmaps of the same type
250
251impl BitAnd for Bitmap128 {
252    type Output = Self;
253
254    fn bitand(self, rhs: Self) -> Self::Output {
255        Self(self.0 & rhs.0)
256    }
257}
258
259impl BitAndAssign for Bitmap128 {
260    fn bitand_assign(&mut self, rhs: Self) {
261        self.0 &= rhs.0;
262    }
263}
264
265impl BitOr for Bitmap128 {
266    type Output = Self;
267
268    fn bitor(self, rhs: Self) -> Self::Output {
269        Self(self.0 | rhs.0)
270    }
271}
272
273impl BitOrAssign for Bitmap128 {
274    fn bitor_assign(&mut self, rhs: Self) {
275        self.0 |= rhs.0;
276    }
277}
278
279impl BitXor for Bitmap128 {
280    type Output = Self;
281
282    fn bitxor(self, rhs: Self) -> Self::Output {
283        Self(self.0 ^ rhs.0)
284    }
285}
286
287impl BitXorAssign for Bitmap128 {
288    fn bitxor_assign(&mut self, rhs: Self) {
289        self.0 ^= rhs.0;
290    }
291}
292
293// Traits implementing arithmetic operations between Bitmaps of the same type
294
295impl Add for Bitmap128 {
296    type Output = Self;
297
298    fn add(self, rhs: Self) -> Self::Output {
299        Self(self.0 + rhs.0)
300    }
301}
302
303impl AddAssign for Bitmap128 {
304    fn add_assign(&mut self, rhs: Self) {
305        self.0 += rhs.0;
306    }
307}
308
309impl Sub for Bitmap128 {
310    type Output = Self;
311
312    fn sub(self, rhs: Self) -> Self::Output {
313        Self(self.0 - rhs.0)
314    }
315}
316
317impl SubAssign for Bitmap128 {
318    fn sub_assign(&mut self, rhs: Self) {
319        self.0 -= rhs.0;
320    }
321}
322
323impl Mul for Bitmap128 {
324    type Output = Self;
325
326    fn mul(self, rhs: Self) -> Self::Output {
327        Self(self.0 * rhs.0)
328    }
329}
330
331impl MulAssign for Bitmap128 {
332    fn mul_assign(&mut self, rhs: Self) {
333        self.0 *= rhs.0;
334    }
335}
336
337impl Div for Bitmap128 {
338    type Output = Self;
339
340    fn div(self, rhs: Self) -> Self::Output {
341        Self(self.0 / rhs.0)
342    }
343}
344
345impl DivAssign for Bitmap128 {
346    fn div_assign(&mut self, rhs: Self) {
347        self.0 /= rhs.0;
348    }
349}
350
351// Traits implementing bitwise operations between Bitmaps and their respective integer types.
352
353impl BitAnd<u128> for Bitmap128 {
354    type Output = Self;
355
356    fn bitand(self, rhs: u128) -> Self::Output {
357        Self(self.0 & rhs)
358    }
359}
360
361impl BitAndAssign<u128> for Bitmap128 {
362    fn bitand_assign(&mut self, rhs: u128) {
363        self.0 &= rhs;
364    }
365}
366
367impl BitOr<u128> for Bitmap128 {
368    type Output = Self;
369
370    fn bitor(self, rhs: u128) -> Self::Output {
371        Self(self.0 | rhs)
372    }
373}
374
375impl BitOrAssign<u128> for Bitmap128 {
376    fn bitor_assign(&mut self, rhs: u128) {
377        self.0 |= rhs;
378    }
379}
380
381impl BitXor<u128> for Bitmap128 {
382    type Output = Self;
383
384    fn bitxor(self, rhs: u128) -> Self::Output {
385        Self(self.0 ^ rhs)
386    }
387}
388
389impl BitXorAssign<u128> for Bitmap128 {
390    fn bitxor_assign(&mut self, rhs: u128) {
391        self.0 ^= rhs;
392    }
393}
394
395// Traits implementing arithmetic operations between Bitmaps and their respective integer types.
396
397impl Add<u128> for Bitmap128 {
398    type Output = Self;
399
400    fn add(self, rhs: u128) -> Self::Output {
401        Self(self.0 + rhs)
402    }
403}
404
405impl AddAssign<u128> for Bitmap128 {
406    fn add_assign(&mut self, rhs: u128) {
407        self.0 += rhs;
408    }
409}
410
411impl Sub<u128> for Bitmap128 {
412    type Output = Self;
413
414    fn sub(self, rhs: u128) -> Self::Output {
415        Self(self.0 - rhs)
416    }
417}
418
419impl SubAssign<u128> for Bitmap128 {
420    fn sub_assign(&mut self, rhs: u128) {
421        self.0 -= rhs;
422    }
423}
424
425impl Mul<u128> for Bitmap128 {
426    type Output = Self;
427
428    fn mul(self, rhs: u128) -> Self::Output {
429        Self(self.0 * rhs)
430    }
431}
432
433impl MulAssign<u128> for Bitmap128 {
434    fn mul_assign(&mut self, rhs: u128) {
435        self.0 *= rhs;
436    }
437}
438
439impl Div<u128> for Bitmap128 {
440    type Output = Self;
441
442    fn div(self, rhs: u128) -> Self::Output {
443        Self(self.0 / rhs)
444    }
445}
446
447impl DivAssign<u128> for Bitmap128 {
448    fn div_assign(&mut self, rhs: u128) {
449        self.0 /= rhs;
450    }
451}
452
453// Traits for left and right bitwise shifts. These really only make sense when working
454// with integers, rather than other bitmaps
455
456impl Shl<usize> for Bitmap128 {
457    type Output = Self;
458
459    fn shl(self, rhs: usize) -> Self::Output {
460        Self(self.0 << rhs)
461    }
462}
463
464impl ShlAssign<usize> for Bitmap128 {
465    fn shl_assign(&mut self, rhs: usize) {
466        self.0 <<= rhs;
467    }
468}
469
470impl Shr<usize> for Bitmap128 {
471    type Output = Self;
472
473    fn shr(self, rhs: usize) -> Self::Output {
474        Self(self.0 >> rhs)
475    }
476}
477
478impl ShrAssign<usize> for Bitmap128 {
479    fn shr_assign(&mut self, rhs: usize) {
480        self.0 >>= rhs;
481    }
482}
483
484// The Not trait, flipping 1's to 0's and 0's to 1's
485
486impl Not for Bitmap128 {
487    type Output = Self;
488
489    fn not(self) -> Self::Output {
490        Self(self.0 ^ u128::MAX)
491    }
492}
493
494// Dereference
495
496impl Deref for Bitmap128 {
497    type Target = u128;
498
499    fn deref(&self) -> &Self::Target {
500        &self.0
501    }
502}