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