bv/traits/
bits_ext.rs

1use super::Bits;
2use adapter::*;
3
4/// Extension trait for adapter operations on bit slices.
5///
6/// The methods return lazy adapter objects that query the underlying bit vectors
7/// and perform operations as needed. To eagerly evaluate a result, copy
8/// it into a vector using the [`Bits::to_bit_vec`] method, as in the example below.
9///
10/// This trait is currently `pub use`d from the [`adapter`] module, but that alias
11/// is deprecated.
12///
13/// [`Bits::to_bit_vec`]: trait.Bits.html#method.to_bit_vec
14/// [`adapter`]: adapter/index.html
15///
16/// # Examples
17///
18/// ```
19/// use bv::*;
20///
21/// let bv1: BitVec = bit_vec![false, false, true, true];
22/// let bv2: BitVec = bit_vec![false, true, false, true];
23///
24/// let and_bv = bv1.bit_and(&bv2);
25///
26/// assert_eq!( and_bv[0], false );
27/// assert_eq!( and_bv[1], false );
28/// assert_eq!( and_bv[2], false );
29/// assert_eq!( and_bv[3], true );
30///
31/// let bv3 = and_bv.to_bit_vec();
32/// assert_eq!( bv3, bit_vec![false, false, false, true] );
33/// ```
34pub trait BitsExt: Bits {
35
36    /// Concatenates two bit vectors, with the bits of `self` followed by the bits
37    /// of `other`.
38    fn bit_concat<Other>(&self, other: Other) -> BitConcat<&Self, Other>
39        where Other: Bits<Block = Self::Block> {
40
41        BitConcat::new(self, other)
42    }
43
44    /// Concatenates two bit vectors, with the bits of `self` followed by the bits
45    /// of `other`.
46    ///
47    /// Consumes `self`.
48    fn into_bit_concat<Other>(self, other: Other) -> BitConcat<Self, Other>
49        where Self: Sized,
50              Other: Bits<Block = Self::Block> {
51
52        BitConcat::new(self, other)
53    }
54
55    /// Pads `self` with 0s on the right to reach at least `len` bits in length.
56    ///
57    /// If `self` is already long enough, the length is unchanged.
58    fn bit_pad(&self, len: u64) -> BitConcat<&Self, BitFill<Self::Block>> {
59        self.into_bit_pad(len)
60    }
61
62    /// Pads `self` with 0s on the right to reach at least `len` bits in length.
63    ///
64    /// If `self` is already long enough, the length is unchanged.
65    ///
66    /// Consumes `self`.
67    fn into_bit_pad(self, len: u64) -> BitConcat<Self, BitFill<Self::Block>>
68        where Self: Sized {
69
70        let have = self.bit_len();
71        let need = if len > have {len - have} else {0};
72        self.into_bit_concat(BitFill::zeroes(need))
73    }
74
75    /// Returns an object that inverts the values of all the bits in `self`.
76    fn bit_not(&self) -> BitNot<&Self> {
77        BitNot::new(self)
78    }
79
80    /// Returns an object that inverts the values of all the bits in `self`.
81    ///
82    /// Consumes `self`.
83    fn into_bit_not(self) -> BitNot<Self>
84        where Self: Sized
85    {
86        BitNot::new(self)
87    }
88
89    /// Returns an object that lazily computes the bit-wise conjunction
90    /// of two bit-vector-likes.
91    ///
92    /// If the lengths of the operands differ, the result will have
93    /// the minimum of the two.
94    fn bit_and<Other>(&self, other: Other) -> BitAnd<&Self, Other>
95        where Other: Bits<Block = Self::Block> {
96
97        BitAnd::new(self, other)
98    }
99
100    /// Returns an object that lazily computes the bit-wise conjunction
101    /// of two bit-vector-likes.
102    ///
103    /// If the lengths of the operands differ, the result will have
104    /// the minimum of the two.
105    ///
106    /// Consumes `self`.
107    fn into_bit_and<Other>(self, other: Other) -> BitAnd<Self, Other>
108        where Self: Sized,
109              Other: Bits<Block = Self::Block> {
110        BitAnd::new(self, other)
111    }
112
113    /// Returns an object that lazily computes the bit-wise disjunction
114    /// of two bit-vector-likes.
115    ///
116    /// If the lengths of the operands differ, the result will have
117    /// the minimum of the two.
118    fn bit_or<Other>(&self, other: Other) -> BitOr<&Self, Other>
119        where Other: Bits<Block = Self::Block> {
120
121        BitOr::new(self, other)
122    }
123
124    /// Returns an object that lazily computes the bit-wise disjunction
125    /// of two bit-vector-likes.
126    ///
127    /// If the lengths of the operands differ, the result will have
128    /// the minimum of the two.
129    ///
130    /// Consumes `self`.
131    fn into_bit_or<Other>(self, other: Other) -> BitOr<Self, Other>
132        where Self: Sized,
133              Other: Bits<Block = Self::Block> {
134
135        BitOr::new(self, other)
136    }
137
138    /// Returns an object that lazily computes the bit-wise xor of two
139    /// bit-vector-likes.
140    ///
141    /// If the lengths of the operands differ, the result will have
142    /// the minimum of the two.
143    fn bit_xor<Other>(&self, other: Other) -> BitXor<&Self, Other>
144        where Other: Bits<Block = Self::Block> {
145
146        BitXor::new(self, other)
147    }
148
149    /// Returns an object that lazily computes the bit-wise xor of two
150    /// bit-vector-likes.
151    ///
152    /// If the lengths of the operands differ, the result will have
153    /// the minimum of the two.
154    ///
155    /// Consumes `self`.
156    fn into_bit_xor<Other>(self, other: Other) -> BitXor<Self, Other>
157        where Self: Sized,
158              Other: Bits<Block = Self::Block> {
159
160        BitXor::new(self, other)
161    }
162
163    /// Returns an object that lazily zips a function over the blocks of
164    /// two bit-vector-like.
165    ///
166    /// The third parameter to the zipping function `fun` is the number of
167    /// bits in the block currently being processed. (This will be
168    /// `Self::Block::nbits()` for all but the last block.)
169    ///
170    /// If the lengths of the operands differ, the result will have
171    /// the minimum of the two.
172    fn bit_zip<Other, F>(&self, other: Other, fun: F) -> BitZip<&Self, Other, F>
173        where Other: Bits<Block = Self::Block>,
174              F: Fn(Self::Block, Self::Block, usize) -> Self::Block {
175
176        BitZip::new(self, other, fun)
177    }
178
179    /// Returns an object that lazily zips a function over the blocks of
180    /// two bit-vector-like.
181    ///
182    /// The third parameter to the zipping function `fun` is the number of
183    /// bits in the block currently being processed. (This will be
184    /// `Self::Block::nbits()` for all but the last block.)
185    ///
186    /// If the lengths of the operands differ, the result will have
187    /// the minimum of the two.
188    ///
189    /// Consumes `self`.
190    fn into_bit_zip<Other, F>(self, other: Other, fun: F) -> BitZip<Self, Other, F>
191        where Self: Sized,
192              Other: Bits<Block = Self::Block>,
193              F: Fn(Self::Block, Self::Block, usize) -> Self::Block {
194
195        BitZip::new(self, other, fun)
196    }
197}
198
199impl<T: Bits> BitsExt for T {}
200