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