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