closed_interval_set/
iterator_wrapper.rs

1//! Branded wrapper to mark iterators that yield normalized sequences
2//! of ranges, i.e., that are known to contain sorted and fully disjoint
3//! (not adjacent) non-empty ranges.
4use core::iter::DoubleEndedIterator;
5use core::iter::ExactSizeIterator;
6use core::iter::FusedIterator;
7use core::iter::Iterator;
8
9use crate::ClosedRange;
10use crate::NormalizedRangeIter;
11
12/// This [`crate`] uses [`NormalizedRangeIterWrapper`] internally to
13/// brand regular [`Iterator`]s that are known to yield normalized
14/// ranges.  The wrapper itself is an [`Iterator`], and preserves
15/// [`DoubleEndedIterator`] and [`ExactSizeIterator`] if the
16/// underlying iterator implements them.
17///
18/// External users may rebrand iterators with this wrapper when they
19/// are known to be normalized... but there are no guardrails here,
20/// and getting this wrong will results in all sorts of broken outputs
21/// (but not violate memory safety).
22#[repr(transparent)]
23pub struct NormalizedRangeIterWrapper<T: Iterator<Item: ClosedRange>>(T);
24
25impl<T: Iterator<Item: ClosedRange>> NormalizedRangeIterWrapper<T> {
26    /// Brands the iterator as normalized.  This is an unchecked promise!
27    ///
28    /// # Safety
29    ///
30    /// The caller must know that the iterator returns normalized ranges:
31    /// non-empty ranges that are also sorted and fully disjoint.
32    #[inline(always)]
33    pub unsafe fn new_unchecked(inner: T) -> Self {
34        Self(inner)
35    }
36}
37
38impl<T: Iterator<Item: ClosedRange>> crate::private::Sealed for NormalizedRangeIterWrapper<T> {}
39
40impl<T: Iterator<Item: ClosedRange>> NormalizedRangeIter for NormalizedRangeIterWrapper<T> {}
41
42impl<T: Iterator<Item: ClosedRange>> Iterator for NormalizedRangeIterWrapper<T> {
43    type Item = <T as Iterator>::Item;
44
45    #[inline(always)]
46    fn next(&mut self) -> Option<Self::Item> {
47        self.0.next()
48    }
49
50    #[inline(always)]
51    fn size_hint(&self) -> (usize, Option<usize>) {
52        self.0.size_hint()
53    }
54}
55
56impl<T: Iterator<Item: ClosedRange> + DoubleEndedIterator> DoubleEndedIterator
57    for NormalizedRangeIterWrapper<T>
58{
59    #[inline(always)]
60    fn next_back(&mut self) -> Option<Self::Item> {
61        self.0.next_back()
62    }
63}
64
65impl<T: Iterator<Item: ClosedRange> + ExactSizeIterator> ExactSizeIterator
66    for NormalizedRangeIterWrapper<T>
67{
68}
69
70impl<T: Iterator<Item: ClosedRange> + FusedIterator> FusedIterator
71    for NormalizedRangeIterWrapper<T>
72{
73}
74
75#[cfg_attr(coverage_nightly, coverage(off))]
76#[test]
77fn test_iterator_forwarding() {
78    use alloc::vec;
79
80    let mut iter = unsafe {
81        NormalizedRangeIterWrapper::new_unchecked(vec![(0u8, 1u8), (4u8, 10u8)].into_iter())
82    };
83
84    assert_eq!(iter.size_hint(), (2, Some(2)));
85    assert_eq!(iter.next_back(), Some((4u8, 10u8)));
86    assert_eq!(iter.next(), Some((0u8, 1u8)));
87    assert_eq!(iter.next(), None);
88}