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