nostd_bv/traits/bits_ext.rs
1use super::Bits;
2use crate::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 nostd_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 /// Concatenates two bit vectors, with the bits of `self` followed by the bits
36 /// of `other`.
37 fn bit_concat<Other>(&self, other: Other) -> BitConcat<&Self, Other>
38 where
39 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
50 Self: Sized,
51 Other: Bits<Block = Self::Block>,
52 {
53 BitConcat::new(self, other)
54 }
55
56 /// Pads `self` with 0s on the right to reach at least `len` bits in length.
57 ///
58 /// If `self` is already long enough, the length is unchanged.
59 fn bit_pad(&self, len: u64) -> BitConcat<&Self, BitFill<Self::Block>> {
60 self.into_bit_pad(len)
61 }
62
63 /// Pads `self` with 0s on the right to reach at least `len` bits in length.
64 ///
65 /// If `self` is already long enough, the length is unchanged.
66 ///
67 /// Consumes `self`.
68 fn into_bit_pad(self, len: u64) -> BitConcat<Self, BitFill<Self::Block>>
69 where
70 Self: Sized,
71 {
72 let have = self.bit_len();
73 let need = len.saturating_sub(have);
74 self.into_bit_concat(BitFill::zeroes(need))
75 }
76
77 /// Returns an object that inverts the values of all the bits in `self`.
78 fn bit_not(&self) -> BitNot<&Self> {
79 BitNot::new(self)
80 }
81
82 /// Returns an object that inverts the values of all the bits in `self`.
83 ///
84 /// Consumes `self`.
85 fn into_bit_not(self) -> BitNot<Self>
86 where
87 Self: Sized,
88 {
89 BitNot::new(self)
90 }
91
92 /// Returns an object that lazily computes the bit-wise conjunction
93 /// of two bit-vector-likes.
94 ///
95 /// If the lengths of the operands differ, the result will have
96 /// the minimum of the two.
97 fn bit_and<Other>(&self, other: Other) -> BitAnd<&Self, Other>
98 where
99 Other: Bits<Block = Self::Block>,
100 {
101 BitAnd::new(self, other)
102 }
103
104 /// Returns an object that lazily computes the bit-wise conjunction
105 /// of two bit-vector-likes.
106 ///
107 /// If the lengths of the operands differ, the result will have
108 /// the minimum of the two.
109 ///
110 /// Consumes `self`.
111 fn into_bit_and<Other>(self, other: Other) -> BitAnd<Self, Other>
112 where
113 Self: Sized,
114 Other: Bits<Block = Self::Block>,
115 {
116 BitAnd::new(self, other)
117 }
118
119 /// Returns an object that lazily computes the bit-wise disjunction
120 /// of two bit-vector-likes.
121 ///
122 /// If the lengths of the operands differ, the result will have
123 /// the minimum of the two.
124 fn bit_or<Other>(&self, other: Other) -> BitOr<&Self, Other>
125 where
126 Other: Bits<Block = Self::Block>,
127 {
128 BitOr::new(self, other)
129 }
130
131 /// Returns an object that lazily computes the bit-wise disjunction
132 /// of two bit-vector-likes.
133 ///
134 /// If the lengths of the operands differ, the result will have
135 /// the minimum of the two.
136 ///
137 /// Consumes `self`.
138 fn into_bit_or<Other>(self, other: Other) -> BitOr<Self, Other>
139 where
140 Self: Sized,
141 Other: Bits<Block = Self::Block>,
142 {
143 BitOr::new(self, other)
144 }
145
146 /// Returns an object that lazily computes the bit-wise xor of two
147 /// bit-vector-likes.
148 ///
149 /// If the lengths of the operands differ, the result will have
150 /// the minimum of the two.
151 fn bit_xor<Other>(&self, other: Other) -> BitXor<&Self, Other>
152 where
153 Other: Bits<Block = Self::Block>,
154 {
155 BitXor::new(self, other)
156 }
157
158 /// Returns an object that lazily computes the bit-wise xor of two
159 /// bit-vector-likes.
160 ///
161 /// If the lengths of the operands differ, the result will have
162 /// the minimum of the two.
163 ///
164 /// Consumes `self`.
165 fn into_bit_xor<Other>(self, other: Other) -> BitXor<Self, Other>
166 where
167 Self: Sized,
168 Other: Bits<Block = Self::Block>,
169 {
170 BitXor::new(self, other)
171 }
172
173 /// Returns an object that lazily zips a function over the blocks of
174 /// two bit-vector-like.
175 ///
176 /// The third parameter to the zipping function `fun` is the number of
177 /// bits in the block currently being processed. (This will be
178 /// `Self::Block::nbits()` for all but the last block.)
179 ///
180 /// If the lengths of the operands differ, the result will have
181 /// the minimum of the two.
182 fn bit_zip<Other, F>(&self, other: Other, fun: F) -> BitZip<&Self, Other, F>
183 where
184 Other: Bits<Block = Self::Block>,
185 F: Fn(Self::Block, Self::Block, usize) -> Self::Block,
186 {
187 BitZip::new(self, other, fun)
188 }
189
190 /// Returns an object that lazily zips a function over the blocks of
191 /// two bit-vector-like.
192 ///
193 /// The third parameter to the zipping function `fun` is the number of
194 /// bits in the block currently being processed. (This will be
195 /// `Self::Block::nbits()` for all but the last block.)
196 ///
197 /// If the lengths of the operands differ, the result will have
198 /// the minimum of the two.
199 ///
200 /// Consumes `self`.
201 fn into_bit_zip<Other, F>(self, other: Other, fun: F) -> BitZip<Self, Other, F>
202 where
203 Self: Sized,
204 Other: Bits<Block = Self::Block>,
205 F: Fn(Self::Block, Self::Block, usize) -> Self::Block,
206 {
207 BitZip::new(self, other, fun)
208 }
209}
210
211impl<T: Bits> BitsExt for T {}