1use {Bits, BitSliceable};
2use BlockType;
3use iter::BlockIter;
4
5use traits::get_masked_block;
6
7use std::cmp;
8
9#[derive(Clone, Debug)]
14pub struct BitNot<T>(T);
15
16impl<T> BitNot<T> {
17 pub (crate) fn new(bits: T) -> Self {
18 BitNot(bits)
19 }
20}
21
22#[derive(Clone, Debug)]
27pub struct BitAnd<T, U>(BitBinOp<T, U>);
28
29impl<T: Bits, U: Bits<Block = T::Block>> BitAnd<T, U> {
30 pub (crate) fn new(bits1: T, bits2: U) -> Self {
31 BitAnd(BitBinOp::new(bits1, bits2))
32 }
33}
34
35#[derive(Clone, Debug)]
40pub struct BitOr<T, U>(BitBinOp<T, U>);
41
42impl<T: Bits, U: Bits<Block = T::Block>> BitOr<T, U> {
43 pub (crate) fn new(bits1: T, bits2: U) -> Self {
44 BitOr(BitBinOp::new(bits1, bits2))
45 }
46}
47
48#[derive(Clone, Debug)]
53pub struct BitXor<T, U>(BitBinOp<T, U>);
54
55impl<T: Bits, U: Bits<Block = T::Block>> BitXor<T, U> {
56 pub (crate) fn new(bits1: T, bits2: U) -> Self {
57 BitXor(BitBinOp::new(bits1, bits2))
58 }
59}
60
61#[derive(Clone, Debug)]
63pub struct BitZip<T, U, F> {
64 ops: BitBinOp<T, U>,
65 fun: F,
66}
67
68impl<T: Bits, U: Bits<Block = T::Block>, F> BitZip<T, U, F> {
69 pub (crate) fn new(bits1: T, bits2: U, fun: F) -> Self {
70 BitZip {
71 ops: BitBinOp::new(bits1, bits2),
72 fun,
73 }
74 }
75}
76
77#[derive(Clone, Debug)]
82struct BitBinOp<T, U> {
83 op1: T,
84 op2: U,
85 len: u64,
86}
87
88impl<T: Bits, U: Bits<Block = T::Block>> BitBinOp<T, U> {
89 fn new(op1: T, op2: U) -> Self {
90 let len = cmp::min(op1.bit_len(), op2.bit_len());
91 BitBinOp { op1, op2, len, }
92 }
93
94 fn bit1(&self, position: u64) -> bool {
95 self.op1.get_bit(position)
96 }
97
98 fn bit2(&self, position: u64) -> bool {
99 self.op2.get_bit(position)
100 }
101
102 fn block1(&self, position: usize) -> T::Block {
103 self.op1.get_raw_block(position)
104 }
105
106 fn block2(&self, position: usize) -> T::Block {
107 self.op2.get_raw_block(position)
108 }
109}
110
111impl<T: Bits> Bits for BitNot<T> {
112 type Block = T::Block;
113
114 fn bit_len(&self) -> u64 {
115 self.0.bit_len()
116 }
117
118 fn get_bit(&self, position: u64) -> bool {
119 !self.0.get_bit(position)
120 }
121
122 fn get_block(&self, position: usize) -> Self::Block {
123 !self.0.get_block(position)
124 }
125
126 fn get_raw_block(&self, position: usize) -> Self::Block {
127 !self.0.get_raw_block(position)
128 }
129}
130
131impl_index_from_bits! {
132 impl[T: Bits] Index<u64> for BitNot<T>;
133}
134
135impl<R, T> BitSliceable<R> for BitNot<T>
136 where T: BitSliceable<R> {
137
138 type Slice = BitNot<T::Slice>;
139
140 fn bit_slice(self, range: R) -> Self::Slice {
141 BitNot(self.0.bit_slice(range))
142 }
143}
144
145impl_bit_sliceable_adapter! {
146 impl['a, T: Bits] BitSliceable for &'a BitNot<T>;
147}
148
149impl<T, U> PartialEq<U> for BitNot<T>
150 where T: Bits,
151 U: Bits<Block = T::Block> {
152
153 fn eq(&self, other: &U) -> bool {
154 BlockIter::new(self) == BlockIter::new(other)
155 }
156}
157
158macro_rules! impl_bits_bin_op {
159 ( $target:ident as $block_op:tt $bool_op:tt ) => {
160 impl<T, U> Bits for $target<T, U>
161 where T: Bits,
162 U: Bits<Block = T::Block>
163 {
164 type Block = T::Block;
165
166 fn bit_len(&self) -> u64 {
167 self.0.len
168 }
169
170 fn get_bit(&self, position: u64) -> bool {
171 assert!( position < self.bit_len(),
172 format!("{}::get_bit: out of bounds", stringify!($target)) );
173 self.0.bit1(position) $bool_op self.0.bit2(position)
174 }
175
176 fn get_block(&self, position: usize) -> Self::Block {
177 assert!( position < self.block_len(),
178 format!("{}::get_block: out of bounds", stringify!($target)) );
179 get_masked_block(self, position)
180 }
181
182 fn get_raw_block(&self, position: usize) -> Self::Block {
183 self.0.block1(position) $block_op self.0.block2(position)
184 }
185 }
186
187 impl_index_from_bits! {
188 impl[T: Bits, U: Bits<Block = T::Block>] Index<u64> for $target<T, U>;
189 }
190
191 impl<Block, R, T, U> BitSliceable<R> for $target<T, U>
192 where Block: BlockType,
193 R: Clone,
194 T: BitSliceable<R, Block = Block>,
195 U: BitSliceable<R, Block = Block> {
196
197 type Slice = $target<T::Slice, U::Slice>;
198
199 fn bit_slice(self, range: R) -> Self::Slice {
200 $target(BitBinOp::new(self.0.op1.bit_slice(range.clone()),
201 self.0.op2.bit_slice(range)))
202 }
203 }
204
205 impl_bit_sliceable_adapter! {
206 impl['a, T: Bits, U: Bits<Block = T::Block>] BitSliceable for &'a $target<T, U>;
207 }
208
209 impl<T, U, V> PartialEq<V> for $target<T, U>
210 where T: Bits,
211 U: Bits<Block = T::Block>,
212 V: Bits<Block = T::Block> {
213
214 fn eq(&self, other: &V) -> bool {
215 BlockIter::new(self) == BlockIter::new(other)
216 }
217 }
218 };
219}
220
221impl_bits_bin_op!(BitAnd as & &&);
222impl_bits_bin_op!(BitOr as | ||);
223impl_bits_bin_op!(BitXor as ^ ^);
224
225impl<T, U, F> Bits for BitZip<T, U, F>
226 where T: Bits,
227 U: Bits<Block = T::Block>,
228 F: Fn(T::Block, T::Block) -> T::Block {
229 type Block = T::Block;
230
231 fn bit_len(&self) -> u64 {
232 self.ops.len
233 }
234
235 fn get_block(&self, position: usize) -> Self::Block {
236 assert!( position < self.block_len(), "BitZip::get_block: out of bounds" );
237 get_masked_block(self, position)
238 }
239
240 fn get_raw_block(&self, position: usize) -> Self::Block {
241 (self.fun)(self.ops.block1(position), self.ops.block2(position))
242 }
243}
244
245impl_index_from_bits! {
246 impl[T: Bits, U: Bits<Block = T::Block>,
247 F: Fn(T::Block, T::Block) -> T::Block]
248 Index<u64> for BitZip<T, U, F>;
249}
250
251impl<Block, R, T, U, F> BitSliceable<R> for BitZip<T, U, F>
252 where Block: BlockType,
253 R: Clone,
254 T: BitSliceable<R, Block = Block>,
255 U: BitSliceable<R, Block = Block>,
256 F: Fn(Block, Block) -> Block {
257
258 type Slice = BitZip<T::Slice, U::Slice, F>;
259
260 fn bit_slice(self, range: R) -> Self::Slice {
261 BitZip {
262 ops: BitBinOp::new(self.ops.op1.bit_slice(range.clone()),
263 self.ops.op2.bit_slice(range)),
264 fun: self.fun,
265 }
266 }
267}
268
269impl_bit_sliceable_adapter! {
270 impl['a, T: Bits, U: Bits<Block = T::Block>,
271 F: Fn(T::Block, T::Block) -> T::Block]
272 BitSliceable for &'a BitZip<T, U, F>;
273}
274
275impl<T, U, F, V> PartialEq<V> for BitZip<T, U, F>
276 where T: Bits,
277 U: Bits<Block = T::Block>,
278 V: Bits<Block = T::Block>,
279 F: Fn(T::Block, T::Block) -> T::Block {
280
281 fn eq(&self, other: &V) -> bool {
282 BlockIter::new(self) == BlockIter::new(other)
283 }
284}
285