1use crate::iter::BlockIter;
2use crate::{BitSliceable, Bits, BitsMut, BlockType};
3
4use crate::range_compat::*;
5
6#[derive(Copy, Clone, Debug)]
12pub struct BitSliceAdapter<T> {
13 bits: T,
14 start: u64,
15 len: u64,
16}
17
18impl<T: Bits> BitSliceAdapter<T> {
19 pub fn new(bits: T, start: u64, len: u64) -> Self {
27 assert!(
28 start + len <= bits.bit_len(),
29 "BitSliceAdapter::new: out of bounds"
30 );
31 BitSliceAdapter { bits, start, len }
32 }
33
34 fn reslice(self, start: u64, len: u64) -> Self {
43 assert!(
44 start + len <= self.bit_len(),
45 "BitSliceAdapter::reslice: out of bounds"
46 );
47 BitSliceAdapter {
48 bits: self.bits,
49 start: self.start + start,
50 len,
51 }
52 }
53
54 fn reslice_ref(&self, start: u64, len: u64) -> BitSliceAdapter<&T> {
63 assert!(
64 start + len <= self.bit_len(),
65 "BitSliceAdapter::reslice: out of bounds"
66 );
67 BitSliceAdapter {
68 bits: &self.bits,
69 start: self.start + start,
70 len,
71 }
72 }
73}
74
75impl<T, U> PartialEq<U> for BitSliceAdapter<T>
76where
77 T: Bits,
78 U: Bits<Block = T::Block>,
79{
80 fn eq(&self, other: &U) -> bool {
81 BlockIter::new(self) == BlockIter::new(other)
82 }
83}
84
85macro_rules! impl_bit_sliceable_adapter {
86 (
87 $(
88 impl[ $($param:tt)* ] BitSliceable for $target:ty ;
89 )+
90 ) => {
91 $(
92 impl<$($param)*> $crate::BitSliceable<::core::ops::Range<u64>> for $target {
93 type Slice = $crate::adapter::BitSliceAdapter<Self>;
94
95 fn bit_slice(self, range: ::core::ops::Range<u64>) -> Self::Slice {
96 assert!( range.start <= range.end,
97 "{}::slice: bad range", stringify!($target) );
98 $crate::adapter::BitSliceAdapter::new(self, range.start, range.end - range.start)
99 }
100 }
101
102 impl<$($param)*> $crate::BitSliceable<::core::ops::RangeFrom<u64>> for $target {
103 type Slice = $crate::adapter::BitSliceAdapter<Self>;
104
105 fn bit_slice(self, range: ::core::ops::RangeFrom<u64>) -> Self::Slice {
106 let len = self.bit_len();
107 self.bit_slice(range.start .. len)
108 }
109 }
110
111 impl<$($param)*> $crate::BitSliceable<::core::ops::RangeTo<u64>> for $target {
112 type Slice = $crate::adapter::BitSliceAdapter<Self>;
113
114 fn bit_slice(self, range: ::core::ops::RangeTo<u64>) -> Self::Slice {
115 $crate::adapter::BitSliceAdapter::new(self, 0, range.end)
116 }
117 }
118
119 impl<$($param)*> $crate::BitSliceable<::core::ops::RangeFull> for $target {
120 type Slice = $crate::adapter::BitSliceAdapter<Self>;
121
122 fn bit_slice(self, _range: ::core::ops::RangeFull) -> Self::Slice {
123 let len = self.bit_len();
124 $crate::adapter::BitSliceAdapter::new(self, 0, len)
125 }
126 }
127
128 impl<$($param)*> $crate::BitSliceable<::core::ops::RangeInclusive<u64>> for $target {
129 type Slice = $crate::adapter::BitSliceAdapter<Self>;
130
131 fn bit_slice(self, range: ::core::ops::RangeInclusive<u64>) -> Self::Slice {
132 let (start, end) = $crate::range_compat::get_inclusive_bounds(range)
133 .expect("BitSliceable::bit_slice: bad inclusive range");
134 $crate::adapter::BitSliceAdapter::new(self, start, end - start + 1)
135 }
136 }
137
138 impl<$($param)*> $crate::BitSliceable<::core::ops::RangeToInclusive<u64>> for $target {
139 type Slice = $crate::adapter::BitSliceAdapter<Self>;
140
141 fn bit_slice(self, range: ::core::ops::RangeToInclusive<u64>) -> Self::Slice {
142 $crate::adapter::BitSliceAdapter::new(self, 0, range.end + 1)
143 }
144 }
145 )+
146 };
147}
148
149impl<T: Bits> Bits for BitSliceAdapter<T> {
150 type Block = T::Block;
151
152 fn bit_len(&self) -> u64 {
153 self.len
154 }
155
156 fn get_bit(&self, position: u64) -> bool {
157 assert!(
158 position < self.bit_len(),
159 "BitSliceAdapter::get_bit: out of bounds"
160 );
161 self.bits.get_bit(self.start + position)
162 }
163
164 fn get_block(&self, position: usize) -> Self::Block {
165 assert!(
166 position < self.block_len(),
167 "BitSliceAdapter::get_block: out of bounds"
168 );
169 let (real_start, real_len) = get_block_addr::<T::Block>(self.start, self.len, position);
170 self.bits.get_bits(real_start, real_len)
171 }
172
173 fn get_bits(&self, start: u64, count: usize) -> Self::Block {
174 assert!(
175 start + count as u64 <= self.bit_len(),
176 "BitSliceAdapter::get_bits: out of bounds"
177 );
178 self.bits.get_bits(self.start + start, count)
179 }
180}
181
182impl<T: BitsMut> BitsMut for BitSliceAdapter<T> {
183 fn set_bit(&mut self, position: u64, value: bool) {
184 assert!(
185 position < self.bit_len(),
186 "BitSliceAdapter::set_bit: out of bounds"
187 );
188 self.bits.set_bit(self.start + position, value);
189 }
190
191 fn set_block(&mut self, position: usize, value: Self::Block) {
192 assert!(
193 position < self.block_len(),
194 "BitSliceAdapter::get_block: out of bounds"
195 );
196 let (real_start, real_len) = get_block_addr::<T::Block>(self.start, self.len, position);
197 self.bits.set_bits(real_start, real_len, value);
198 }
199
200 fn set_bits(&mut self, start: u64, count: usize, value: Self::Block) {
201 assert!(
202 start + count as u64 <= self.bit_len(),
203 "BitSliceAdapter::set_bits: out of bounds"
204 );
205 self.bits.set_bits(self.start + start, count, value);
206 }
207}
208
209fn get_block_addr<Block: BlockType>(start: u64, len: u64, position: usize) -> (u64, usize) {
213 let real_start = start + Block::mul_nbits(position);
214 let block_size = Block::nbits() as u64;
215 let real_len = if real_start + block_size < start + len {
216 block_size
217 } else {
218 start + len - real_start
219 };
220
221 (real_start, real_len as usize)
222}
223
224impl_index_from_bits! {
225 impl[T: Bits] Index<u64> for BitSliceAdapter<T>;
226}
227
228impl<T: Bits> BitSliceable<Range<u64>> for BitSliceAdapter<T> {
229 type Slice = Self;
230
231 fn bit_slice(self, range: Range<u64>) -> Self::Slice {
232 assert!(
233 range.start <= range.end,
234 "BitSliceAdapter::bit_slice: bad range"
235 );
236 self.reslice(range.start, range.end - range.start)
237 }
238}
239
240impl<T: Bits> BitSliceable<RangeTo<u64>> for BitSliceAdapter<T> {
241 type Slice = Self;
242
243 fn bit_slice(self, range: RangeTo<u64>) -> Self::Slice {
244 self.reslice(0, range.end)
245 }
246}
247
248impl<T: Bits> BitSliceable<RangeFrom<u64>> for BitSliceAdapter<T> {
249 type Slice = Self;
250
251 fn bit_slice(self, range: RangeFrom<u64>) -> Self::Slice {
252 let len = self.bit_len();
253 assert!(
254 range.start <= len,
255 "BitSliceAdapter::bit_slice: out of bounds"
256 );
257 self.reslice(range.start, len - range.start)
258 }
259}
260
261impl<T: Bits> BitSliceable<RangeFull> for BitSliceAdapter<T> {
262 type Slice = Self;
263
264 fn bit_slice(self, _range: RangeFull) -> Self::Slice {
265 self
266 }
267}
268
269impl<T: Bits> BitSliceable<RangeInclusive<u64>> for BitSliceAdapter<T> {
270 type Slice = Self;
271
272 fn bit_slice(self, range: RangeInclusive<u64>) -> Self::Slice {
273 let (start, limit) =
274 get_inclusive_bounds(range).expect("BitSliceAdapter::bit_slice: bad range");
275 self.reslice(start, limit - start + 1)
276 }
277}
278
279impl<T: Bits> BitSliceable<RangeToInclusive<u64>> for BitSliceAdapter<T> {
280 type Slice = Self;
281
282 fn bit_slice(self, range: RangeToInclusive<u64>) -> Self::Slice {
283 self.reslice(0, range.end + 1)
284 }
285}
286
287impl<'a, T: Bits> BitSliceable<Range<u64>> for &'a BitSliceAdapter<T> {
288 type Slice = BitSliceAdapter<&'a T>;
289
290 fn bit_slice(self, range: Range<u64>) -> Self::Slice {
291 assert!(
292 range.start <= range.end,
293 "BitSliceAdapter::bit_slice: bad range"
294 );
295 self.reslice_ref(range.start, range.end - range.start)
296 }
297}
298
299impl<'a, T: Bits> BitSliceable<RangeTo<u64>> for &'a BitSliceAdapter<T> {
300 type Slice = BitSliceAdapter<&'a T>;
301
302 fn bit_slice(self, range: RangeTo<u64>) -> Self::Slice {
303 self.reslice_ref(0, range.end)
304 }
305}
306
307impl<'a, T: Bits> BitSliceable<RangeFrom<u64>> for &'a BitSliceAdapter<T> {
308 type Slice = BitSliceAdapter<&'a T>;
309
310 fn bit_slice(self, range: RangeFrom<u64>) -> Self::Slice {
311 let len = self.bit_len();
312 assert!(
313 range.start <= len,
314 "BitSliceAdapter::bit_slice: out of bounds"
315 );
316 self.reslice_ref(range.start, len - range.start)
317 }
318}
319
320impl<'a, T: Bits> BitSliceable<RangeFull> for &'a BitSliceAdapter<T> {
321 type Slice = BitSliceAdapter<&'a T>;
322
323 fn bit_slice(self, _range: RangeFull) -> Self::Slice {
324 self.reslice_ref(0, self.bit_len())
325 }
326}
327
328impl<'a, T: Bits> BitSliceable<RangeInclusive<u64>> for &'a BitSliceAdapter<T> {
329 type Slice = BitSliceAdapter<&'a T>;
330
331 fn bit_slice(self, range: RangeInclusive<u64>) -> Self::Slice {
332 let (start, limit) =
333 get_inclusive_bounds(range).expect("BitSliceAdapter::bit_slice: bad range");
334 self.reslice_ref(start, limit - start + 1)
335 }
336}
337
338impl<'a, T: Bits> BitSliceable<RangeToInclusive<u64>> for &'a BitSliceAdapter<T> {
339 type Slice = BitSliceAdapter<&'a T>;
340
341 fn bit_slice(self, range: RangeToInclusive<u64>) -> Self::Slice {
342 self.reslice_ref(0, range.end + 1)
343 }
344}