nostd_bv/adapter/
bool_adapter.rs

1use crate::iter::BlockIter;
2use crate::BlockType;
3use crate::{Bits, BitsMut, BitsPush};
4
5use alloc::vec::Vec;
6use core::marker::PhantomData;
7use core::ops;
8
9/// Adapts a sequence of `bool`s (*e.g.,* `&[bool]`) to emulate a bit
10/// vector.
11///
12/// In particular, this adapter implements [`Bits`], [`BitsMut`], and
13/// [`BitsPush`] as appropriate. It implement `PartialEq<T>` for all
14/// `T: Bits<Block=Block>`. It does not, however, implement slicing, so
15/// slice before you adapt.
16///
17/// Note that a bare `Vec<bool>` or `&[bool]` already implements [`Bits`],
18/// etc., with a `Block` type of `u8`. This means that it is only
19/// compatible with other `u8`-based bit vectors. `BoolAdapter` is instead
20/// parametrized by the block type, so it works with bit vectors, slices,
21/// and adapters of any uniform block type.
22///
23/// [`Bits`]: ../trait.Bits.html
24/// [`BitsMut`]: ../trait.BitsMut.html
25/// [`BitsPush`]: ../trait.BitsPush.html
26#[derive(Debug, Clone)]
27pub struct BoolAdapter<Block, T> {
28    bits: T,
29    _marker: PhantomData<Block>,
30}
31
32impl<Block: BlockType, T> BoolAdapter<Block, T> {
33    /// Creates a new `BoolAdapter` from an underlying sequence of `bool`s.
34    ///
35    /// Note that the `BoolAdapter` derefs to the underlying `bool` sequence.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use nostd_bv::BitSliceable;
41    /// use nostd_bv::adapter::BoolAdapter;
42    ///
43    /// let array = [0b101usize];
44    /// let bv1 = BoolAdapter::new(vec![true, false, true]);
45    /// let bv2 = array.bit_slice(0..3);
46    /// assert_eq!( bv1, bv2 );
47    /// ```
48    pub fn new(bits: T) -> Self {
49        BoolAdapter {
50            bits,
51            _marker: PhantomData,
52        }
53    }
54
55    /// Gets the underlying `bool` sequence object back out of a `BoolAdapter`.
56    pub fn into_inner(self) -> T {
57        self.bits
58    }
59}
60
61impl<Block, T> ops::Deref for BoolAdapter<Block, T> {
62    type Target = T;
63
64    fn deref(&self) -> &T {
65        &self.bits
66    }
67}
68
69impl<Block, T> ops::DerefMut for BoolAdapter<Block, T> {
70    fn deref_mut(&mut self) -> &mut T {
71        &mut self.bits
72    }
73}
74
75macro_rules! impl_for_bool_adapter {
76    () => {};
77
78    (
79        impl[$($param:tt)*] Bits for BoolAdapter<$block:ty, $target:ty>;
80        $( $rest:tt )*
81    ) => {
82        impl<$($param)*> Bits for BoolAdapter<$block, $target> {
83            type Block = $block;
84
85            fn bit_len(&self) -> u64 {
86                self.bits.len() as u64
87            }
88
89            fn get_bit(&self, position: u64) -> bool {
90                self.bits[position as usize]
91            }
92        }
93
94        impl_for_bool_adapter! { $($rest)* }
95    };
96
97    (
98        impl[$($param:tt)*] BitsMut for BoolAdapter<$block:ty, $target:ty>;
99        $( $rest:tt )*
100    ) => {
101        impl<$($param)*> BitsMut for BoolAdapter<$block, $target> {
102            fn set_bit(&mut self, position: u64, value: bool) {
103                self.bits[position as usize] = value
104            }
105        }
106
107        impl_for_bool_adapter! { $($rest)* }
108    };
109
110    (
111        impl[$($param:tt)*] BitsPush for BoolAdapter<$block:ty, $target:ty>;
112        $( $rest:tt )*
113    ) => {
114        impl<$($param)*> BitsPush for BoolAdapter<$block, $target> {
115            fn push_bit(&mut self, value: bool) {
116                self.bits.push(value);
117            }
118
119            fn pop_bit(&mut self) -> Option<bool> {
120                self.bits.pop()
121            }
122        }
123
124        impl_for_bool_adapter! { $($rest)* }
125    };
126}
127
128impl_for_bool_adapter! {
129    impl[    Block: BlockType] Bits     for BoolAdapter<Block, Vec<bool>>;
130    impl[    Block: BlockType] BitsMut  for BoolAdapter<Block, Vec<bool>>;
131    impl[    Block: BlockType] BitsPush for BoolAdapter<Block, Vec<bool>>;
132
133    impl['a, Block: BlockType] Bits     for BoolAdapter<Block, &'a mut Vec<bool>>;
134    impl['a, Block: BlockType] BitsMut  for BoolAdapter<Block, &'a mut Vec<bool>>;
135    impl['a, Block: BlockType] BitsPush for BoolAdapter<Block, &'a mut Vec<bool>>;
136
137    impl['a, Block: BlockType] Bits     for BoolAdapter<Block, &'a mut [bool]>;
138    impl['a, Block: BlockType] BitsMut  for BoolAdapter<Block, &'a mut [bool]>;
139
140    impl['a, Block: BlockType] Bits     for BoolAdapter<Block, &'a [bool]>;
141}
142
143impl<Block, T, U> PartialEq<U> for BoolAdapter<Block, T>
144where
145    Block: BlockType,
146    U: Bits<Block = Block>,
147    Self: Bits<Block = Block>,
148{
149    fn eq(&self, other: &U) -> bool {
150        BlockIter::new(self) == BlockIter::new(other)
151    }
152}