iterator sizing lib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#![cfg_attr(
    feature = "nightly",
    feature(
        trusted_len,
        trusted_fused,
        min_specialization,
        trusted_random_access,
        inplace_iteration,
        doc_cfg,
    )
)]
#![no_std]
use core::iter::FusedIterator;
#[cfg(feature = "nightly")]
use core::iter::{
    InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
};
/// Provides a hint for an iterator.
#[derive(Clone, Debug)]
pub struct Hinted<I> {
    /// Wrapped iterator.
    iter: I,
    /// Size hint, decreased on every call to [`next()`](Iterator::next).
    hint: usize,
}

/// Set the size hint for an iterator.
pub trait HintExt: Iterator
where
    Self: Sized,
{
    /// Sets the lower bound of [`Iterator::size_hint`]. Useful for collects etc.
    fn hinted(self, hint: usize) -> Hinted<Self> {
        Hinted { iter: self, hint }
    }
    /// Implements [`ExactSizeIterator`] for any iterator, with a len provided by you.
    /// This implements [`TrustedLen`](core::iter::TrustedLen) as well, so this function is unsafe.
    ///
    /// The resulting iterator will not return after the length has been reached.
    ///
    /// # Safety
    ///
    /// number of items *must* be `len`.
    unsafe fn has(self, len: usize) -> Exactly<Self> {
        Exactly { iter: self, len }
    }
}

impl<I: Iterator> HintExt for I {}

impl<I> Iterator for Hinted<I>
where
    I: Iterator + Sized,
{
    type Item = <I as Iterator>::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.hint = self.hint.saturating_sub(1);
        self.iter.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.hint, self.iter.size_hint().1)
    }
}
impl<I: DoubleEndedIterator> DoubleEndedIterator for Hinted<I> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.hint = self.hint.saturating_sub(1);
        self.iter.next_back()
    }
}

impl<I: FusedIterator> FusedIterator for Hinted<I> {}
#[cfg(feature = "nightly")]
unsafe impl<I: TrustedRandomAccess> TrustedRandomAccess for Hinted<I> {}
#[cfg(feature = "nightly")]
unsafe impl<I: TrustedRandomAccessNoCoerce> TrustedRandomAccessNoCoerce for Hinted<I> {
    const MAY_HAVE_SIDE_EFFECT: bool = true;
}
#[cfg(feature = "nightly")]
unsafe impl<I: SourceIter> SourceIter for Hinted<I> {
    type Source = I::Source;

    #[inline]
    unsafe fn as_inner(&mut self) -> &mut I::Source {
        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
        unsafe { SourceIter::as_inner(&mut self.iter) }
    }
}
#[cfg(feature = "nightly")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Hinted<I> {
    const EXPAND_BY: Option<core::num::NonZero<usize>> = I::EXPAND_BY;
    const MERGE_BY: Option<core::num::NonZero<usize>> = I::MERGE_BY;
}

/// Provides a size for an iterator.
#[derive(Clone, Debug)]
pub struct Exactly<I> {
    /// Wrapped iterator.
    iter: I,
    /// Exact size, decreased on every call to [`next()`](Iterator::next).
    len: usize,
}

/// Set the size hint for an iterator.
impl<I> Iterator for Exactly<I>
where
    I: Iterator + Sized,
{
    type Item = <I as Iterator>::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.len = self.len.saturating_sub(1);
        self.iter.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<I: Iterator> ExactSizeIterator for Exactly<I> {
    fn len(&self) -> usize {
        self.len
    }
}
impl<I: DoubleEndedIterator> DoubleEndedIterator for Exactly<I> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.len = self.len.saturating_sub(1);
        self.iter.next_back()
    }
}
impl<I: FusedIterator> FusedIterator for Exactly<I> {}

// SAFETY: see [`HintExt::has`].
#[cfg(feature = "nightly")]
unsafe impl<I: Iterator> TrustedLen for Exactly<I> {}
#[cfg(feature = "nightly")]
unsafe impl<I: TrustedRandomAccess> TrustedRandomAccess for Exactly<I> {}
#[cfg(feature = "nightly")]
unsafe impl<I: TrustedRandomAccessNoCoerce> TrustedRandomAccessNoCoerce for Exactly<I> {
    const MAY_HAVE_SIDE_EFFECT: bool = true;
}
#[cfg(feature = "nightly")]
unsafe impl<I: SourceIter> SourceIter for Exactly<I> {
    type Source = I::Source;

    #[inline]
    unsafe fn as_inner(&mut self) -> &mut I::Source {
        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
        unsafe { SourceIter::as_inner(&mut self.iter) }
    }
}
#[cfg(feature = "nightly")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Exactly<I> {
    const EXPAND_BY: Option<core::num::NonZero<usize>> = I::EXPAND_BY;
    const MERGE_BY: Option<core::num::NonZero<usize>> = I::MERGE_BY;
}