1use crate::bit_chunk_iterator::{UnalignedBitChunk, UnalignedBitChunkIterator};
21use crate::bit_util::{ceil, get_bit_raw};
22
23#[derive(Clone)]
27pub struct BitIterator<'a> {
28 buffer: &'a [u8],
29 current_offset: usize,
30 end_offset: usize,
31}
32
33impl<'a> BitIterator<'a> {
34 pub fn new(buffer: &'a [u8], offset: usize, len: usize) -> Self {
41 let end_offset = offset.checked_add(len).unwrap();
42 let required_len = ceil(end_offset, 8);
43 assert!(
44 buffer.len() >= required_len,
45 "BitIterator buffer too small, expected {required_len} got {}",
46 buffer.len()
47 );
48
49 Self {
50 buffer,
51 current_offset: offset,
52 end_offset,
53 }
54 }
55}
56
57impl Iterator for BitIterator<'_> {
58 type Item = bool;
59
60 #[inline]
61 fn next(&mut self) -> Option<Self::Item> {
62 if self.current_offset == self.end_offset {
63 return None;
64 }
65 let v = unsafe { get_bit_raw(self.buffer.as_ptr(), self.current_offset) };
68 self.current_offset += 1;
69 Some(v)
70 }
71
72 fn size_hint(&self) -> (usize, Option<usize>) {
73 let remaining_bits = self.end_offset - self.current_offset;
74 (remaining_bits, Some(remaining_bits))
75 }
76
77 fn count(self) -> usize
78 where
79 Self: Sized,
80 {
81 self.len()
82 }
83
84 #[inline]
85 fn nth(&mut self, n: usize) -> Option<Self::Item> {
86 match self.current_offset.checked_add(n) {
91 Some(new_offset) if new_offset < self.end_offset => {
93 self.current_offset = new_offset;
94 }
95
96 _ => {
98 self.current_offset = self.end_offset;
99 return None;
100 }
101 }
102
103 self.next()
104 }
105
106 fn last(mut self) -> Option<Self::Item> {
107 if self.current_offset == self.end_offset {
109 return None;
110 }
111
112 self.current_offset = self.end_offset - 1;
114
115 self.next()
117 }
118
119 fn max(self) -> Option<Self::Item>
120 where
121 Self: Sized,
122 Self::Item: Ord,
123 {
124 if self.current_offset == self.end_offset {
125 return None;
126 }
127
128 let mut bit_index_iter = BitIndexIterator::new(
130 self.buffer,
131 self.current_offset,
132 self.end_offset - self.current_offset,
133 );
134
135 if bit_index_iter.next().is_some() {
136 return Some(true);
137 }
138
139 Some(false)
141 }
142}
143
144impl ExactSizeIterator for BitIterator<'_> {}
145
146impl DoubleEndedIterator for BitIterator<'_> {
147 fn next_back(&mut self) -> Option<Self::Item> {
148 if self.current_offset == self.end_offset {
149 return None;
150 }
151 self.end_offset -= 1;
152 let v = unsafe { get_bit_raw(self.buffer.as_ptr(), self.end_offset) };
155 Some(v)
156 }
157
158 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
159 match self.end_offset.checked_sub(n) {
164 Some(new_offset) if self.current_offset < new_offset => {
166 self.end_offset = new_offset;
167 }
168
169 _ => {
171 self.current_offset = self.end_offset;
172 return None;
173 }
174 }
175
176 self.next_back()
177 }
178}
179
180#[derive(Debug)]
188pub struct BitSliceIterator<'a> {
189 iter: UnalignedBitChunkIterator<'a>,
190 len: usize,
191 current_offset: i64,
192 current_chunk: u64,
193}
194
195impl<'a> BitSliceIterator<'a> {
196 #[inline]
199 pub fn new(buffer: &'a [u8], offset: usize, len: usize) -> Self {
200 let chunk = UnalignedBitChunk::new(buffer, offset, len);
201 let mut iter = chunk.iter();
202
203 let current_offset = -(chunk.lead_padding() as i64);
204 let current_chunk = iter.next().unwrap_or(0);
205
206 Self {
207 iter,
208 len,
209 current_offset,
210 current_chunk,
211 }
212 }
213
214 #[inline]
220 fn advance_to_set_bit(&mut self) -> Option<(i64, u32)> {
221 loop {
222 if self.current_chunk != 0 {
223 let bit_pos = self.current_chunk.trailing_zeros();
225 return Some((self.current_offset, bit_pos));
226 }
227
228 self.current_chunk = self.iter.next()?;
229 self.current_offset += 64;
230 }
231 }
232}
233
234impl Iterator for BitSliceIterator<'_> {
235 type Item = (usize, usize);
236
237 #[inline]
238 fn next(&mut self) -> Option<Self::Item> {
239 if self.len == 0 {
241 return None;
242 }
243
244 let (start_chunk, start_bit) = self.advance_to_set_bit()?;
245
246 self.current_chunk |= (1 << start_bit) - 1;
248
249 loop {
250 if self.current_chunk != u64::MAX {
251 let end_bit = self.current_chunk.trailing_ones();
253
254 self.current_chunk &= !((1 << end_bit) - 1);
256
257 return Some((
258 (start_chunk + start_bit as i64) as usize,
259 (self.current_offset + end_bit as i64) as usize,
260 ));
261 }
262
263 match self.iter.next() {
264 Some(next) => {
265 self.current_chunk = next;
266 self.current_offset += 64;
267 }
268 None => {
269 return Some((
270 (start_chunk + start_bit as i64) as usize,
271 std::mem::replace(&mut self.len, 0),
272 ));
273 }
274 }
275 }
276 }
277}
278
279#[derive(Debug)]
284pub struct BitIndexIterator<'a> {
285 current_chunk: u64,
286 chunk_offset: i64,
287 iter: UnalignedBitChunkIterator<'a>,
288}
289
290impl<'a> BitIndexIterator<'a> {
291 pub fn new(buffer: &'a [u8], offset: usize, len: usize) -> Self {
294 let chunks = UnalignedBitChunk::new(buffer, offset, len);
295 let mut iter = chunks.iter();
296
297 let current_chunk = iter.next().unwrap_or(0);
298 let chunk_offset = -(chunks.lead_padding() as i64);
299
300 Self {
301 current_chunk,
302 chunk_offset,
303 iter,
304 }
305 }
306}
307
308impl Iterator for BitIndexIterator<'_> {
309 type Item = usize;
310
311 #[inline(always)]
312 fn next(&mut self) -> Option<Self::Item> {
313 loop {
314 if self.current_chunk != 0 {
315 let bit_pos = self.current_chunk.trailing_zeros();
316 self.current_chunk &= self.current_chunk - 1;
317 return Some((self.chunk_offset + bit_pos as i64) as usize);
318 }
319
320 self.current_chunk = self.iter.next()?;
321 self.chunk_offset += 64;
322 }
323 }
324}
325
326#[derive(Debug)]
329pub struct BitIndexU32Iterator<'a> {
330 curr: u64,
331 chunk_offset: i64,
332 iter: UnalignedBitChunkIterator<'a>,
333}
334
335impl<'a> BitIndexU32Iterator<'a> {
336 pub fn new(buffer: &'a [u8], offset: usize, len: usize) -> Self {
339 let chunks = UnalignedBitChunk::new(buffer, offset, len);
341 let mut iter = chunks.iter();
342
343 let curr = iter.next().unwrap_or(0);
345 let chunk_offset = -(chunks.lead_padding() as i64);
347
348 Self {
349 curr,
350 chunk_offset,
351 iter,
352 }
353 }
354}
355
356impl Iterator for BitIndexU32Iterator<'_> {
357 type Item = u32;
358
359 #[inline(always)]
360 fn next(&mut self) -> Option<u32> {
361 loop {
362 if self.curr != 0 {
363 let tz = self.curr.trailing_zeros();
365 self.curr &= self.curr - 1;
367 return Some((self.chunk_offset + tz as i64) as u32);
369 }
370 let next_chunk = self.iter.next()?;
372 self.chunk_offset += 64;
374 self.curr = next_chunk;
375 }
376 }
377}
378
379#[inline]
395pub fn try_for_each_valid_idx<E, F: FnMut(usize) -> Result<(), E>>(
396 len: usize,
397 offset: usize,
398 null_count: usize,
399 nulls: Option<&[u8]>,
400 f: F,
401) -> Result<(), E> {
402 let valid_count = len - null_count;
403
404 if valid_count == len {
405 (0..len).try_for_each(f)
406 } else if null_count != len {
407 BitIndexIterator::new(nulls.unwrap(), offset, len).try_for_each(f)
408 } else {
409 Ok(())
410 }
411}
412
413#[cfg(test)]
416mod tests {
417 use super::*;
418 use crate::BooleanBuffer;
419 use rand::rngs::StdRng;
420 use rand::{RngExt, SeedableRng};
421 use std::fmt::Debug;
422 use std::iter::Copied;
423 use std::slice::Iter;
424
425 #[test]
426 fn test_bit_iterator_size_hint() {
427 let mut b = BitIterator::new(&[0b00000011], 0, 2);
428 assert_eq!(
429 b.size_hint(),
430 (2, Some(2)),
431 "Expected size_hint to be (2, Some(2))"
432 );
433
434 b.next();
435 assert_eq!(
436 b.size_hint(),
437 (1, Some(1)),
438 "Expected size_hint to be (1, Some(1)) after one bit consumed"
439 );
440
441 b.next();
442 assert_eq!(
443 b.size_hint(),
444 (0, Some(0)),
445 "Expected size_hint to be (0, Some(0)) after all bits consumed"
446 );
447 }
448
449 #[test]
450 fn test_bit_iterator() {
451 let mask = &[0b00010010, 0b00100011, 0b00000101, 0b00010001, 0b10010011];
452 let actual: Vec<_> = BitIterator::new(mask, 0, 5).collect();
453 assert_eq!(actual, &[false, true, false, false, true]);
454
455 let actual: Vec<_> = BitIterator::new(mask, 4, 5).collect();
456 assert_eq!(actual, &[true, false, false, false, true]);
457
458 let actual: Vec<_> = BitIterator::new(mask, 12, 14).collect();
459 assert_eq!(
460 actual,
461 &[
462 false, true, false, false, true, false, true, false, false, false, false, false,
463 true, false
464 ]
465 );
466
467 assert_eq!(BitIterator::new(mask, 0, 0).count(), 0);
468 assert_eq!(BitIterator::new(mask, 40, 0).count(), 0);
469 }
470
471 #[test]
472 #[should_panic(expected = "BitIterator buffer too small, expected 3 got 2")]
473 fn test_bit_iterator_bounds() {
474 let mask = &[223, 23];
475 BitIterator::new(mask, 17, 0);
476 }
477
478 #[test]
479 fn test_bit_index_u32_iterator_basic() {
480 let mask = &[0b00010010, 0b00100011];
481
482 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 0, 16).collect();
483 let expected: Vec<u32> = BitIndexIterator::new(mask, 0, 16)
484 .map(|i| i as u32)
485 .collect();
486 assert_eq!(result, expected);
487
488 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 4, 8).collect();
489 let expected: Vec<u32> = BitIndexIterator::new(mask, 4, 8)
490 .map(|i| i as u32)
491 .collect();
492 assert_eq!(result, expected);
493
494 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 10, 4).collect();
495 let expected: Vec<u32> = BitIndexIterator::new(mask, 10, 4)
496 .map(|i| i as u32)
497 .collect();
498 assert_eq!(result, expected);
499
500 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 0, 0).collect();
501 let expected: Vec<u32> = BitIndexIterator::new(mask, 0, 0)
502 .map(|i| i as u32)
503 .collect();
504 assert_eq!(result, expected);
505 }
506
507 #[test]
508 fn test_bit_index_u32_iterator_all_set() {
509 let mask = &[0xFF, 0xFF];
510 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 0, 16).collect();
511 let expected: Vec<u32> = BitIndexIterator::new(mask, 0, 16)
512 .map(|i| i as u32)
513 .collect();
514 assert_eq!(result, expected);
515 }
516
517 #[test]
518 fn test_bit_index_u32_iterator_none_set() {
519 let mask = &[0x00, 0x00];
520 let result: Vec<u32> = BitIndexU32Iterator::new(mask, 0, 16).collect();
521 let expected: Vec<u32> = BitIndexIterator::new(mask, 0, 16)
522 .map(|i| i as u32)
523 .collect();
524 assert_eq!(result, expected);
525 }
526
527 #[test]
528 fn test_bit_index_u32_cross_chunk() {
529 let mut buf = vec![0u8; 16];
530 for bit in 60..68 {
531 let byte = (bit / 8) as usize;
532 let bit_in_byte = bit % 8;
533 buf[byte] |= 1 << bit_in_byte;
534 }
535 let offset = 58;
536 let len = 10;
537
538 let result: Vec<u32> = BitIndexU32Iterator::new(&buf, offset, len).collect();
539 let expected: Vec<u32> = BitIndexIterator::new(&buf, offset, len)
540 .map(|i| i as u32)
541 .collect();
542 assert_eq!(result, expected);
543 }
544
545 #[test]
546 fn test_bit_index_u32_unaligned_offset() {
547 let mask = &[0b0110_1100, 0b1010_0000];
548 let offset = 2;
549 let len = 12;
550
551 let result: Vec<u32> = BitIndexU32Iterator::new(mask, offset, len).collect();
552 let expected: Vec<u32> = BitIndexIterator::new(mask, offset, len)
553 .map(|i| i as u32)
554 .collect();
555 assert_eq!(result, expected);
556 }
557
558 #[test]
559 fn test_bit_index_u32_long_all_set() {
560 let len = 200;
561 let num_bytes = len / 8 + usize::from(len % 8 != 0);
562 let bytes = vec![0xFFu8; num_bytes];
563
564 let result: Vec<u32> = BitIndexU32Iterator::new(&bytes, 0, len).collect();
565 let expected: Vec<u32> = BitIndexIterator::new(&bytes, 0, len)
566 .map(|i| i as u32)
567 .collect();
568 assert_eq!(result, expected);
569 }
570
571 #[test]
572 fn test_bit_index_u32_none_set() {
573 let len = 50;
574 let num_bytes = len / 8 + usize::from(len % 8 != 0);
575 let bytes = vec![0u8; num_bytes];
576
577 let result: Vec<u32> = BitIndexU32Iterator::new(&bytes, 0, len).collect();
578 let expected: Vec<u32> = BitIndexIterator::new(&bytes, 0, len)
579 .map(|i| i as u32)
580 .collect();
581 assert_eq!(result, expected);
582 }
583
584 trait SharedBetweenBitIteratorAndSliceIter:
585 ExactSizeIterator<Item = bool> + DoubleEndedIterator<Item = bool>
586 {
587 }
588 impl<T: ?Sized + ExactSizeIterator<Item = bool> + DoubleEndedIterator<Item = bool>>
589 SharedBetweenBitIteratorAndSliceIter for T
590 {
591 }
592
593 fn get_bit_iterator_cases() -> impl Iterator<Item = (BooleanBuffer, Vec<bool>)> {
594 let mut rng = StdRng::seed_from_u64(42);
595
596 [0, 1, 6, 8, 100, 164]
597 .map(|len| {
598 let source = (0..len).map(|_| rng.random_bool(0.5)).collect::<Vec<_>>();
599
600 (BooleanBuffer::from(source.as_slice()), source)
601 })
602 .into_iter()
603 }
604
605 fn setup_and_assert(
606 setup_iters: impl Fn(&mut dyn SharedBetweenBitIteratorAndSliceIter),
607 assert_fn: impl Fn(BitIterator, Copied<Iter<bool>>),
608 ) {
609 for (boolean_buffer, source) in get_bit_iterator_cases() {
610 let mut actual = BitIterator::new(boolean_buffer.values(), 0, boolean_buffer.len());
613 let mut expected = source.iter().copied();
614
615 setup_iters(&mut actual);
616 setup_iters(&mut expected);
617
618 assert_fn(actual, expected);
619 }
620 }
621
622 trait BitIteratorOp {
625 type Output: PartialEq + Debug;
627
628 const NAME: &'static str;
630
631 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(iter: T) -> Self::Output;
634 }
635
636 fn assert_bit_iterator_cases<O: BitIteratorOp>() {
640 setup_and_assert(
641 |_iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {},
642 |actual, expected| {
643 let current_iterator_values: Vec<bool> = expected.clone().collect();
644 assert_eq!(
645 O::get_value(actual),
646 O::get_value(expected),
647 "Failed on op {} for new iter (left actual, right expected) ({current_iterator_values:?})",
648 O::NAME
649 );
650 },
651 );
652
653 setup_and_assert(
654 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
655 iter.next();
656 },
657 |actual, expected| {
658 let current_iterator_values: Vec<bool> = expected.clone().collect();
659
660 assert_eq!(
661 O::get_value(actual),
662 O::get_value(expected),
663 "Failed on op {} for new iter after consuming 1 element from the start (left actual, right expected) ({current_iterator_values:?})",
664 O::NAME
665 );
666 },
667 );
668
669 setup_and_assert(
670 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
671 iter.next_back();
672 },
673 |actual, expected| {
674 let current_iterator_values: Vec<bool> = expected.clone().collect();
675
676 assert_eq!(
677 O::get_value(actual),
678 O::get_value(expected),
679 "Failed on op {} for new iter after consuming 1 element from the end (left actual, right expected) ({current_iterator_values:?})",
680 O::NAME
681 );
682 },
683 );
684
685 setup_and_assert(
686 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
687 iter.next();
688 iter.next_back();
689 },
690 |actual, expected| {
691 let current_iterator_values: Vec<bool> = expected.clone().collect();
692
693 assert_eq!(
694 O::get_value(actual),
695 O::get_value(expected),
696 "Failed on op {} for new iter after consuming 1 element from start and end (left actual, right expected) ({current_iterator_values:?})",
697 O::NAME
698 );
699 },
700 );
701
702 setup_and_assert(
703 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
704 while iter.len() > 1 {
705 iter.next();
706 }
707 },
708 |actual, expected| {
709 let current_iterator_values: Vec<bool> = expected.clone().collect();
710
711 assert_eq!(
712 O::get_value(actual),
713 O::get_value(expected),
714 "Failed on op {} for new iter after consuming all from the start but 1 (left actual, right expected) ({current_iterator_values:?})",
715 O::NAME
716 );
717 },
718 );
719
720 setup_and_assert(
721 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
722 while iter.len() > 1 {
723 iter.next_back();
724 }
725 },
726 |actual, expected| {
727 let current_iterator_values: Vec<bool> = expected.clone().collect();
728
729 assert_eq!(
730 O::get_value(actual),
731 O::get_value(expected),
732 "Failed on op {} for new iter after consuming all from the end but 1 (left actual, right expected) ({current_iterator_values:?})",
733 O::NAME
734 );
735 },
736 );
737
738 setup_and_assert(
739 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
740 while iter.next().is_some() {}
741 },
742 |actual, expected| {
743 let current_iterator_values: Vec<bool> = expected.clone().collect();
744
745 assert_eq!(
746 O::get_value(actual),
747 O::get_value(expected),
748 "Failed on op {} for new iter after consuming all from the start (left actual, right expected) ({current_iterator_values:?})",
749 O::NAME
750 );
751 },
752 );
753
754 setup_and_assert(
755 |iter: &mut dyn SharedBetweenBitIteratorAndSliceIter| {
756 while iter.next_back().is_some() {}
757 },
758 |actual, expected| {
759 let current_iterator_values: Vec<bool> = expected.clone().collect();
760
761 assert_eq!(
762 O::get_value(actual),
763 O::get_value(expected),
764 "Failed on op {} for new iter after consuming all from the end (left actual, right expected) ({current_iterator_values:?})",
765 O::NAME
766 );
767 },
768 );
769 }
770
771 #[test]
772 fn assert_bit_iterator_count() {
773 struct CountOp;
774
775 impl BitIteratorOp for CountOp {
776 type Output = usize;
777 const NAME: &'static str = "count";
778
779 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(iter: T) -> Self::Output {
780 iter.count()
781 }
782 }
783
784 assert_bit_iterator_cases::<CountOp>()
785 }
786
787 #[test]
788 fn assert_bit_iterator_last() {
789 struct LastOp;
790
791 impl BitIteratorOp for LastOp {
792 type Output = Option<bool>;
793 const NAME: &'static str = "last";
794
795 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(iter: T) -> Self::Output {
796 iter.last()
797 }
798 }
799
800 assert_bit_iterator_cases::<LastOp>()
801 }
802
803 #[test]
804 fn assert_bit_iterator_max() {
805 struct MaxOp;
806
807 impl BitIteratorOp for MaxOp {
808 type Output = Option<bool>;
809 const NAME: &'static str = "max";
810
811 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(iter: T) -> Self::Output {
812 iter.max()
813 }
814 }
815
816 assert_bit_iterator_cases::<MaxOp>()
817 }
818
819 #[test]
820 fn assert_bit_iterator_nth_0() {
821 struct NthOp<const BACK: bool>;
822
823 impl<const BACK: bool> BitIteratorOp for NthOp<BACK> {
824 type Output = Option<bool>;
825 const NAME: &'static str = if BACK { "nth_back(0)" } else { "nth(0)" };
826
827 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(mut iter: T) -> Self::Output {
828 if BACK { iter.nth_back(0) } else { iter.nth(0) }
829 }
830 }
831
832 assert_bit_iterator_cases::<NthOp<false>>();
833 assert_bit_iterator_cases::<NthOp<true>>();
834 }
835
836 #[test]
837 fn assert_bit_iterator_nth_1() {
838 struct NthOp<const BACK: bool>;
839
840 impl<const BACK: bool> BitIteratorOp for NthOp<BACK> {
841 type Output = Option<bool>;
842 const NAME: &'static str = if BACK { "nth_back(1)" } else { "nth(1)" };
843
844 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(mut iter: T) -> Self::Output {
845 if BACK { iter.nth_back(1) } else { iter.nth(1) }
846 }
847 }
848
849 assert_bit_iterator_cases::<NthOp<false>>();
850 assert_bit_iterator_cases::<NthOp<true>>();
851 }
852
853 #[test]
854 fn assert_bit_iterator_nth_after_end() {
855 struct NthOp<const BACK: bool>;
856
857 impl<const BACK: bool> BitIteratorOp for NthOp<BACK> {
858 type Output = Option<bool>;
859 const NAME: &'static str = if BACK {
860 "nth_back(iter.len() + 1)"
861 } else {
862 "nth(iter.len() + 1)"
863 };
864
865 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(mut iter: T) -> Self::Output {
866 if BACK {
867 iter.nth_back(iter.len() + 1)
868 } else {
869 iter.nth(iter.len() + 1)
870 }
871 }
872 }
873
874 assert_bit_iterator_cases::<NthOp<false>>();
875 assert_bit_iterator_cases::<NthOp<true>>();
876 }
877
878 #[test]
879 fn assert_bit_iterator_nth_len() {
880 struct NthOp<const BACK: bool>;
881
882 impl<const BACK: bool> BitIteratorOp for NthOp<BACK> {
883 type Output = Option<bool>;
884 const NAME: &'static str = if BACK {
885 "nth_back(iter.len())"
886 } else {
887 "nth(iter.len())"
888 };
889
890 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(mut iter: T) -> Self::Output {
891 if BACK {
892 iter.nth_back(iter.len())
893 } else {
894 iter.nth(iter.len())
895 }
896 }
897 }
898
899 assert_bit_iterator_cases::<NthOp<false>>();
900 assert_bit_iterator_cases::<NthOp<true>>();
901 }
902
903 #[test]
904 fn assert_bit_iterator_nth_last() {
905 struct NthOp<const BACK: bool>;
906
907 impl<const BACK: bool> BitIteratorOp for NthOp<BACK> {
908 type Output = Option<bool>;
909 const NAME: &'static str = if BACK {
910 "nth_back(iter.len().saturating_sub(1))"
911 } else {
912 "nth(iter.len().saturating_sub(1))"
913 };
914
915 fn get_value<T: SharedBetweenBitIteratorAndSliceIter>(mut iter: T) -> Self::Output {
916 if BACK {
917 iter.nth_back(iter.len().saturating_sub(1))
918 } else {
919 iter.nth(iter.len().saturating_sub(1))
920 }
921 }
922 }
923
924 assert_bit_iterator_cases::<NthOp<false>>();
925 assert_bit_iterator_cases::<NthOp<true>>();
926 }
927
928 #[test]
929 fn assert_bit_iterator_nth_and_reuse() {
930 setup_and_assert(
931 |_| {},
932 |actual, expected| {
933 {
934 let mut actual = actual.clone();
935 let mut expected = expected.clone();
936 for _ in 0..expected.len() {
937 #[expect(clippy::iter_nth_zero)]
938 let actual_val = actual.nth(0);
939 #[expect(clippy::iter_nth_zero)]
940 let expected_val = expected.nth(0);
941 assert_eq!(actual_val, expected_val, "Failed on nth(0)");
942 }
943 }
944
945 {
946 let mut actual = actual.clone();
947 let mut expected = expected.clone();
948 for _ in 0..expected.len() {
949 let actual_val = actual.nth(1);
950 let expected_val = expected.nth(1);
951 assert_eq!(actual_val, expected_val, "Failed on nth(1)");
952 }
953 }
954
955 {
956 let mut actual = actual.clone();
957 let mut expected = expected.clone();
958 for _ in 0..expected.len() {
959 let actual_val = actual.nth(2);
960 let expected_val = expected.nth(2);
961 assert_eq!(actual_val, expected_val, "Failed on nth(2)");
962 }
963 }
964 },
965 );
966 }
967
968 #[test]
969 fn assert_bit_iterator_nth_back_and_reuse() {
970 setup_and_assert(
971 |_| {},
972 |actual, expected| {
973 {
974 let mut actual = actual.clone();
975 let mut expected = expected.clone();
976 for _ in 0..expected.len() {
977 let actual_val = actual.nth_back(0);
978 let expected_val = expected.nth_back(0);
979 assert_eq!(actual_val, expected_val, "Failed on nth_back(0)");
980 }
981 }
982
983 {
984 let mut actual = actual.clone();
985 let mut expected = expected.clone();
986 for _ in 0..expected.len() {
987 let actual_val = actual.nth_back(1);
988 let expected_val = expected.nth_back(1);
989 assert_eq!(actual_val, expected_val, "Failed on nth_back(1)");
990 }
991 }
992
993 {
994 let mut actual = actual.clone();
995 let mut expected = expected.clone();
996 for _ in 0..expected.len() {
997 let actual_val = actual.nth_back(2);
998 let expected_val = expected.nth_back(2);
999 assert_eq!(actual_val, expected_val, "Failed on nth_back(2)");
1000 }
1001 }
1002 },
1003 );
1004 }
1005}