bv/adapter/
bool_adapter.rs

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