1use crate::fixed::{
84 slice::FixedVecSlice,
85 traits::{Storable, Word},
86 FixedVec,
87};
88use dsi_bitstream::prelude::Endianness;
89use std::{marker::PhantomData, ops::Deref};
90
91use std::cmp::min;
92
93#[derive(Debug)]
127pub struct FixedVecIter<'a, T, W, E, B>
128where
129 T: Storable<W>,
130 W: Word,
131 E: Endianness,
132 B: AsRef<[W]>,
133{
134 vec: &'a FixedVec<T, W, E, B>,
135 front_index: usize,
136 back_index: usize,
137
138 front_window: W,
140 front_bits_in_window: usize,
141 front_word_index: usize,
142
143 back_window: W,
145 back_bits_in_window: usize,
146 back_word_index: usize,
147 _phantom: PhantomData<T>,
148}
149
150#[derive(Debug)]
154pub struct Chunks<'a, T, W, E, B>
155where
156 T: Storable<W>,
157 W: Word,
158 E: Endianness,
159 B: AsRef<[W]>,
160{
161 vec: &'a FixedVec<T, W, E, B>,
162 chunk_size: usize,
163 current_pos: usize,
164}
165
166impl<'a, T, W, E, B> FixedVecIter<'a, T, W, E, B>
167where
168 T: Storable<W>,
169 W: Word,
170 E: Endianness,
171 B: AsRef<[W]>,
172{
173 pub(super) fn new(vec: &'a FixedVec<T, W, E, B>) -> Self {
175 if vec.is_empty() {
176 return Self {
177 vec,
178 front_index: 0,
179 back_index: 0,
180 front_window: W::ZERO,
181 front_bits_in_window: 0,
182 front_word_index: 0,
183 back_window: W::ZERO,
184 back_bits_in_window: 0,
185 back_word_index: 0,
186 _phantom: PhantomData,
187 };
188 }
189
190 let limbs = vec.as_limbs();
191 let bits_per_word: usize = <W as Word>::BITS;
192
193 let front_word_index = 1;
195 let front_window = unsafe { *limbs.get_unchecked(0) };
197 let front_bits_in_window = bits_per_word;
198
199 let total_bits = vec.len() * vec.bit_width();
201 let back_word_index = (total_bits.saturating_sub(1)) / bits_per_word;
202 let back_window = unsafe { *limbs.get_unchecked(back_word_index) };
204 let back_bits_in_window = total_bits % bits_per_word;
206 let back_bits_in_window = if back_bits_in_window == 0 {
207 bits_per_word
208 } else {
209 back_bits_in_window
210 };
211
212 Self {
213 vec,
214 front_index: 0,
215 back_index: vec.len(),
216 front_window,
217 front_bits_in_window,
218 front_word_index,
219 back_window,
220 back_bits_in_window,
221 back_word_index,
222 _phantom: PhantomData,
223 }
224 }
225}
226
227impl<T, W, E, B> Iterator for FixedVecIter<'_, T, W, E, B>
228where
229 T: Storable<W>,
230 W: Word,
231 E: Endianness,
232 B: AsRef<[W]>,
233{
234 type Item = T;
235
236 #[inline]
237 fn next(&mut self) -> Option<Self::Item> {
238 if self.front_index >= self.back_index {
239 return None;
240 }
241 let index = self.front_index;
242 self.front_index += 1;
243
244 let bit_width = self.vec.bit_width();
245 if bit_width == <W as Word>::BITS {
247 let val = unsafe { *self.vec.as_limbs().get_unchecked(index) };
248 let final_val = if E::IS_BIG { W::from_be(val) } else { val };
249 return Some(<T as Storable<W>>::from_word(final_val));
250 }
251
252 if E::IS_BIG {
254 return Some(unsafe { self.vec.get_unchecked(index) });
255 }
256
257 let mask = self.vec.mask;
258 if self.front_bits_in_window >= bit_width {
260 let value = self.front_window & mask;
261 self.front_window >>= bit_width;
262 self.front_bits_in_window -= bit_width;
263 return Some(<T as Storable<W>>::from_word(value));
264 }
265
266 unsafe {
268 let limbs = self.vec.as_limbs();
269 let bits_from_old = self.front_bits_in_window;
270 let mut result = self.front_window;
271
272 self.front_window = *limbs.get_unchecked(self.front_word_index);
273 self.front_word_index += 1;
274 result |= self.front_window << bits_from_old;
275 let value = result & mask;
276
277 let bits_from_new = bit_width - bits_from_old;
278 self.front_window >>= bits_from_new;
279 self.front_bits_in_window = <W as Word>::BITS - bits_from_new;
280
281 Some(<T as Storable<W>>::from_word(value))
282 }
283 }
284
285 fn size_hint(&self) -> (usize, Option<usize>) {
286 let remaining = self.back_index.saturating_sub(self.front_index);
287 (remaining, Some(remaining))
288 }
289}
290
291impl<T, W, E, B> DoubleEndedIterator for FixedVecIter<'_, T, W, E, B>
292where
293 T: Storable<W>,
294 W: Word,
295 E: Endianness,
296 B: AsRef<[W]>,
297{
298 #[inline]
299 fn next_back(&mut self) -> Option<Self::Item> {
300 if self.front_index >= self.back_index {
301 return None;
302 }
303 self.back_index -= 1;
304 let index = self.back_index;
305
306 if E::IS_BIG || self.vec.bit_width() == <W as Word>::BITS {
307 return Some(unsafe { self.vec.get_unchecked(index) });
308 }
309
310 let bit_width = self.vec.bit_width();
311 let bits_per_word: usize = <W as Word>::BITS;
312
313 if self.back_bits_in_window >= bit_width {
314 self.back_bits_in_window -= bit_width;
315 let value = (self.back_window >> self.back_bits_in_window) & self.vec.mask;
316 return Some(<T as Storable<W>>::from_word(value));
317 }
318
319 unsafe {
320 let limbs = self.vec.as_limbs();
321 let bits_from_old = self.back_bits_in_window;
322 let mut result = self.back_window;
323
324 self.back_word_index -= 1;
325 self.back_window = *limbs.get_unchecked(self.back_word_index);
326
327 result &= (W::ONE << bits_from_old).wrapping_sub(W::ONE);
328 let bits_from_new = bit_width - bits_from_old;
329 result <<= bits_from_new;
330 result |= self.back_window >> (bits_per_word - bits_from_new);
331
332 self.back_bits_in_window = bits_per_word - bits_from_new;
333 Some(<T as Storable<W>>::from_word(result))
334 }
335 }
336}
337
338impl<T, W, E, B> ExactSizeIterator for FixedVecIter<'_, T, W, E, B>
339where
340 T: Storable<W>,
341 W: Word,
342 E: Endianness,
343 B: AsRef<[W]>,
344{
345 fn len(&self) -> usize {
346 self.back_index.saturating_sub(self.front_index)
347 }
348}
349
350pub struct FixedVecIntoIter<'a, T, W, E, B = Vec<W>>
354where
355 T: Storable<W>,
356 W: Word,
357 E: Endianness,
358 B: AsRef<[W]>,
359{
360 _vec_owner: B,
361 iter: FixedVecIter<'a, T, W, E, B>,
362 _phantom: PhantomData<T>,
363}
364
365impl<T, W, E> FixedVecIntoIter<'static, T, W, E, Vec<W>>
366where
367 T: Storable<W>,
368 W: Word,
369 E: Endianness,
370{
371 pub(super) fn new(vec: FixedVec<T, W, E, Vec<W>>) -> Self {
373 let iter = unsafe {
377 let vec_ref: &'static FixedVec<T, W, E, Vec<W>> =
378 std::mem::transmute(&vec as &FixedVec<T, W, E, Vec<W>>);
379 FixedVecIter::new(vec_ref)
380 };
381 Self {
382 _vec_owner: vec.bits,
383 iter,
384 _phantom: PhantomData,
385 }
386 }
387}
388
389impl<T, W, E, B> Iterator for FixedVecIntoIter<'_, T, W, E, B>
390where
391 T: Storable<W>,
392 W: Word,
393 E: Endianness,
394 B: AsRef<[W]>,
395{
396 type Item = T;
397
398 #[inline]
399 fn next(&mut self) -> Option<Self::Item> {
400 self.iter.next()
401 }
402
403 fn size_hint(&self) -> (usize, Option<usize>) {
404 self.iter.size_hint()
405 }
406}
407
408impl<T, W, E, B> DoubleEndedIterator for FixedVecIntoIter<'_, T, W, E, B>
409where
410 T: Storable<W>,
411 W: Word,
412 E: Endianness,
413 B: AsRef<[W]>,
414{
415 #[inline]
416 fn next_back(&mut self) -> Option<Self::Item> {
417 self.iter.next_back()
418 }
419}
420
421impl<T, W, E, B> ExactSizeIterator for FixedVecIntoIter<'_, T, W, E, B>
422where
423 T: Storable<W>,
424 W: Word,
425 E: Endianness,
426 B: AsRef<[W]>,
427{
428 fn len(&self) -> usize {
429 self.iter.len()
430 }
431}
432
433pub struct FixedVecSliceIter<'s, T, W, E, B, V>
439where
440 T: Storable<W>,
441 W: Word,
442 E: Endianness,
443 B: AsRef<[W]>,
444 V: Deref<Target = FixedVec<T, W, E, B>>,
445{
446 slice: &'s FixedVecSlice<V>,
447 front_index: usize, back_index: usize, front_window: W,
452 front_bits_in_window: usize,
453 front_word_index: usize,
454
455 back_window: W,
457 back_bits_in_window: usize,
458 back_word_index: usize,
459
460 _phantom: PhantomData<(T, W, E, B)>,
461}
462
463impl<'s, T, W, E, B, V> FixedVecSliceIter<'s, T, W, E, B, V>
464where
465 T: Storable<W>,
466 W: Word,
467 E: Endianness,
468 B: AsRef<[W]>,
469 V: Deref<Target = FixedVec<T, W, E, B>>,
470{
471 pub(super) fn new(slice: &'s FixedVecSlice<V>) -> Self {
473 let parent_vec = &slice.parent;
474 if slice.is_empty() {
475 return Self {
476 slice,
477 front_index: 0,
478 back_index: 0,
479 front_window: W::ZERO,
480 front_bits_in_window: 0,
481 front_word_index: 0,
482 back_window: W::ZERO,
483 back_bits_in_window: 0,
484 back_word_index: 0,
485 _phantom: PhantomData,
486 };
487 }
488
489 let bits_per_word: usize = <W as Word>::BITS;
490 let bit_width: usize = parent_vec.bit_width();
491 let limbs: &[W] = parent_vec.as_limbs();
492 let slice_start_abs: usize = slice.range.start;
493 let slice_end_abs: usize = slice.range.end;
494
495 let start_bit_pos: usize = slice_start_abs * bit_width;
497 let start_word_index: usize = start_bit_pos / bits_per_word;
498 let start_bit_offset: usize = start_bit_pos % bits_per_word;
499
500 let front_window_raw: W = unsafe { *limbs.get_unchecked(start_word_index) };
501 let front_window: W = front_window_raw >> start_bit_offset;
502 let front_bits_in_window: usize = bits_per_word - start_bit_offset;
503 let front_word_index: usize = start_word_index + 1;
504
505 let end_bit_pos: usize = slice_end_abs * bit_width;
507 let back_word_index: usize = (end_bit_pos.saturating_sub(1)) / bits_per_word;
508 let back_window: W = unsafe { *limbs.get_unchecked(back_word_index) };
509
510 let back_bits_in_window = end_bit_pos % bits_per_word;
511 let back_bits_in_window = if back_bits_in_window == 0 && end_bit_pos > 0 {
512 bits_per_word
513 } else {
514 back_bits_in_window
515 };
516
517 Self {
518 slice,
519 front_index: 0,
520 back_index: slice.len(),
521 front_window,
522 front_bits_in_window,
523 front_word_index,
524 back_window,
525 back_bits_in_window,
526 back_word_index,
527 _phantom: PhantomData,
528 }
529 }
530}
531
532impl<T, W, E, B, V> Iterator for FixedVecSliceIter<'_, T, W, E, B, V>
533where
534 T: Storable<W>,
535 W: Word,
536 E: Endianness,
537 B: AsRef<[W]>,
538 V: Deref<Target = FixedVec<T, W, E, B>>,
539{
540 type Item = T;
541
542 #[inline]
543 fn next(&mut self) -> Option<Self::Item> {
544 if self.front_index >= self.back_index {
545 return None;
546 }
547
548 let parent_vec = &self.slice.parent;
549 let bit_width = parent_vec.bit_width();
550 let mask = parent_vec.mask;
551
552 let abs_index = self.slice.range.start + self.front_index;
553 self.front_index += 1;
554
555 if bit_width == <W as Word>::BITS {
556 let val = unsafe { *parent_vec.as_limbs().get_unchecked(abs_index) };
557 let final_val = if E::IS_BIG { W::from_be(val) } else { val };
558 return Some(<T as Storable<W>>::from_word(final_val));
559 }
560
561 if E::IS_BIG {
562 return Some(unsafe { parent_vec.get_unchecked(abs_index) });
563 }
564
565 if self.front_bits_in_window >= bit_width {
566 let value = self.front_window & mask;
567 self.front_window >>= bit_width;
568 self.front_bits_in_window -= bit_width;
569 return Some(<T as Storable<W>>::from_word(value));
570 }
571
572 unsafe {
573 let limbs = parent_vec.as_limbs();
574 let bits_from_old = self.front_bits_in_window;
575 let mut result = self.front_window;
576
577 self.front_window = *limbs.get_unchecked(self.front_word_index);
578 self.front_word_index += 1;
579 result |= self.front_window << bits_from_old;
580 let value = result & mask;
581
582 let bits_from_new = bit_width - bits_from_old;
583 self.front_window >>= bits_from_new;
584 self.front_bits_in_window = <W as Word>::BITS - bits_from_new;
585
586 Some(<T as Storable<W>>::from_word(value))
587 }
588 }
589
590 fn size_hint(&self) -> (usize, Option<usize>) {
591 let remaining = self.back_index.saturating_sub(self.front_index);
592 (remaining, Some(remaining))
593 }
594}
595
596impl<T, W, E, B, V> DoubleEndedIterator for FixedVecSliceIter<'_, T, W, E, B, V>
597where
598 T: Storable<W>,
599 W: Word,
600 E: Endianness,
601 B: AsRef<[W]>,
602 V: Deref<Target = FixedVec<T, W, E, B>>,
603{
604 #[inline]
605 fn next_back(&mut self) -> Option<Self::Item> {
606 if self.front_index >= self.back_index {
607 return None;
608 }
609 self.back_index -= 1;
610 let abs_index = self.slice.range.start + self.back_index;
611 let parent_vec = &self.slice.parent;
612
613 if E::IS_BIG || parent_vec.bit_width() == <W as Word>::BITS {
614 return Some(unsafe { parent_vec.get_unchecked(abs_index) });
615 }
616
617 let bit_width = parent_vec.bit_width();
618 let bits_per_word: usize = <W as Word>::BITS;
619
620 if self.back_bits_in_window >= bit_width {
621 self.back_bits_in_window -= bit_width;
622 let value = (self.back_window >> self.back_bits_in_window) & parent_vec.mask;
623 return Some(<T as Storable<W>>::from_word(value));
624 }
625
626 unsafe {
627 let limbs = parent_vec.as_limbs();
628 let bits_from_old = self.back_bits_in_window;
629 let mut result = self.back_window;
630
631 self.back_word_index -= 1;
632 self.back_window = *limbs.get_unchecked(self.back_word_index);
633
634 result &= (W::ONE << bits_from_old).wrapping_sub(W::ONE);
635 let bits_from_new = bit_width - bits_from_old;
636 result <<= bits_from_new;
637 result |= self.back_window >> (bits_per_word - bits_from_new);
638
639 self.back_bits_in_window = bits_per_word - bits_from_new;
640 Some(<T as Storable<W>>::from_word(result))
641 }
642 }
643}
644
645impl<T, W, E, B, V> ExactSizeIterator for FixedVecSliceIter<'_, T, W, E, B, V>
646where
647 T: Storable<W>,
648 W: Word,
649 E: Endianness,
650 B: AsRef<[W]>,
651 V: Deref<Target = FixedVec<T, W, E, B>>,
652{
653 fn len(&self) -> usize {
654 self.back_index.saturating_sub(self.front_index)
655 }
656}
657
658impl<'a, T, W, E, B> Chunks<'a, T, W, E, B>
659where
660 T: Storable<W>,
661 W: Word,
662 E: Endianness,
663 B: AsRef<[W]>,
664{
665 pub(super) fn new(vec: &'a FixedVec<T, W, E, B>, chunk_size: usize) -> Self {
667 assert!(chunk_size != 0, "chunk_size cannot be zero");
668 Self {
669 vec,
670 chunk_size,
671 current_pos: 0,
672 }
673 }
674}
675
676impl<'a, T, W, E, B> Iterator for Chunks<'a, T, W, E, B>
677where
678 T: Storable<W>,
679 W: Word,
680 E: Endianness,
681 B: AsRef<[W]>,
682{
683 type Item = FixedVecSlice<&'a FixedVec<T, W, E, B>>;
684
685 fn next(&mut self) -> Option<Self::Item> {
686 if self.current_pos >= self.vec.len() {
687 return None;
688 }
689
690 let len = min(self.chunk_size, self.vec.len() - self.current_pos);
691 let slice = FixedVecSlice::new(self.vec, self.current_pos..self.current_pos + len);
692 self.current_pos += len;
693
694 Some(slice)
695 }
696}
697
698pub struct Windows<'a, T, W, E, B>
702where
703 T: Storable<W>,
704 W: Word,
705 E: Endianness,
706 B: AsRef<[W]>,
707{
708 vec: &'a FixedVec<T, W, E, B>,
709 size: usize,
710 current_pos: usize,
711}
712
713impl<'a, T, W, E, B> Windows<'a, T, W, E, B>
714where
715 T: Storable<W>,
716 W: Word,
717 E: Endianness,
718 B: AsRef<[W]>,
719{
720 pub(super) fn new(vec: &'a FixedVec<T, W, E, B>, size: usize) -> Self {
722 Self {
723 vec,
724 size,
725 current_pos: 0,
726 }
727 }
728}
729
730impl<'a, T, W, E, B> Iterator for Windows<'a, T, W, E, B>
731where
732 T: Storable<W>,
733 W: Word,
734 E: Endianness,
735 B: AsRef<[W]>,
736{
737 type Item = FixedVecSlice<&'a FixedVec<T, W, E, B>>;
738
739 fn next(&mut self) -> Option<Self::Item> {
740 if self.current_pos + self.size > self.vec.len() {
741 return None;
742 }
743
744 let slice = FixedVecSlice::new(self.vec, self.current_pos..self.current_pos + self.size);
745 self.current_pos += 1;
746
747 Some(slice)
748 }
749}
750
751pub struct FixedVecUncheckedIter<'a, T, W, E, B>
761where
762 T: Storable<W>,
763 W: Word,
764 E: Endianness,
765 B: AsRef<[W]>,
766{
767 iter: FixedVecIter<'a, T, W, E, B>,
768}
769
770impl<'a, T, W, E, B> FixedVecUncheckedIter<'a, T, W, E, B>
771where
772 T: Storable<W>,
773 W: Word,
774 E: Endianness,
775 B: AsRef<[W]>,
776{
777 pub(super) fn new(vec: &'a FixedVec<T, W, E, B>) -> Self {
779 Self {
780 iter: FixedVecIter::new(vec),
781 }
782 }
783
784 #[inline]
790 pub unsafe fn next_unchecked(&mut self) -> T {
791 self.iter.next().unwrap_unchecked()
794 }
795
796 #[inline]
802 pub unsafe fn next_back_unchecked(&mut self) -> T {
803 self.iter.next_back().unwrap_unchecked()
804 }
805}