core/range/
iter.rs

1use crate::iter::{
2    FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
3};
4use crate::num::NonZero;
5use crate::range::{Range, RangeFrom, RangeInclusive, legacy};
6
7/// By-value [`Range`] iterator.
8#[unstable(feature = "new_range_api", issue = "125687")]
9#[derive(Debug, Clone)]
10pub struct IterRange<A>(legacy::Range<A>);
11
12impl<A> IterRange<A> {
13    /// Returns the remainder of the range being iterated over.
14    pub fn remainder(self) -> Range<A> {
15        Range { start: self.0.start, end: self.0.end }
16    }
17}
18
19/// Safety: This macro must only be used on types that are `Copy` and result in ranges
20/// which have an exact `size_hint()` where the upper bound must not be `None`.
21macro_rules! unsafe_range_trusted_random_access_impl {
22    ($($t:ty)*) => ($(
23        #[doc(hidden)]
24        #[unstable(feature = "trusted_random_access", issue = "none")]
25        unsafe impl TrustedRandomAccess for IterRange<$t> {}
26
27        #[doc(hidden)]
28        #[unstable(feature = "trusted_random_access", issue = "none")]
29        unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> {
30            const MAY_HAVE_SIDE_EFFECT: bool = false;
31        }
32    )*)
33}
34
35unsafe_range_trusted_random_access_impl! {
36    usize u8 u16
37    isize i8 i16
38}
39
40#[cfg(target_pointer_width = "32")]
41unsafe_range_trusted_random_access_impl! {
42    u32 i32
43}
44
45#[cfg(target_pointer_width = "64")]
46unsafe_range_trusted_random_access_impl! {
47    u32 i32
48    u64 i64
49}
50
51#[unstable(feature = "new_range_api", issue = "125687")]
52impl<A: Step> Iterator for IterRange<A> {
53    type Item = A;
54
55    #[inline]
56    fn next(&mut self) -> Option<A> {
57        self.0.next()
58    }
59
60    #[inline]
61    fn size_hint(&self) -> (usize, Option<usize>) {
62        self.0.size_hint()
63    }
64
65    #[inline]
66    fn count(self) -> usize {
67        self.0.count()
68    }
69
70    #[inline]
71    fn nth(&mut self, n: usize) -> Option<A> {
72        self.0.nth(n)
73    }
74
75    #[inline]
76    fn last(self) -> Option<A> {
77        self.0.last()
78    }
79
80    #[inline]
81    fn min(self) -> Option<A>
82    where
83        A: Ord,
84    {
85        self.0.min()
86    }
87
88    #[inline]
89    fn max(self) -> Option<A>
90    where
91        A: Ord,
92    {
93        self.0.max()
94    }
95
96    #[inline]
97    fn is_sorted(self) -> bool {
98        true
99    }
100
101    #[inline]
102    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
103        self.0.advance_by(n)
104    }
105
106    #[inline]
107    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
108    where
109        Self: TrustedRandomAccessNoCoerce,
110    {
111        // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
112        // that is in bounds.
113        // Additionally Self: TrustedRandomAccess is only implemented for Copy types
114        // which means even repeated reads of the same index would be safe.
115        unsafe { Step::forward_unchecked(self.0.start.clone(), idx) }
116    }
117}
118
119#[unstable(feature = "new_range_api", issue = "125687")]
120impl<A: Step> DoubleEndedIterator for IterRange<A> {
121    #[inline]
122    fn next_back(&mut self) -> Option<A> {
123        self.0.next_back()
124    }
125
126    #[inline]
127    fn nth_back(&mut self, n: usize) -> Option<A> {
128        self.0.nth_back(n)
129    }
130
131    #[inline]
132    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
133        self.0.advance_back_by(n)
134    }
135}
136
137#[unstable(feature = "trusted_len", issue = "37572")]
138unsafe impl<A: TrustedStep> TrustedLen for IterRange<A> {}
139
140#[unstable(feature = "new_range_api", issue = "125687")]
141impl<A: Step> FusedIterator for IterRange<A> {}
142
143#[unstable(feature = "new_range_api", issue = "125687")]
144impl<A: Step> IntoIterator for Range<A> {
145    type Item = A;
146    type IntoIter = IterRange<A>;
147
148    fn into_iter(self) -> Self::IntoIter {
149        IterRange(self.into())
150    }
151}
152
153/// By-value [`RangeInclusive`] iterator.
154#[unstable(feature = "new_range_api", issue = "125687")]
155#[derive(Debug, Clone)]
156pub struct IterRangeInclusive<A>(legacy::RangeInclusive<A>);
157
158impl<A: Step> IterRangeInclusive<A> {
159    /// Returns the remainder of the range being iterated over.
160    ///
161    /// If the iterator is exhausted or empty, returns `None`.
162    pub fn remainder(self) -> Option<RangeInclusive<A>> {
163        if self.0.is_empty() {
164            return None;
165        }
166
167        Some(RangeInclusive { start: self.0.start, end: self.0.end })
168    }
169}
170
171#[unstable(feature = "trusted_random_access", issue = "none")]
172impl<A: Step> Iterator for IterRangeInclusive<A> {
173    type Item = A;
174
175    #[inline]
176    fn next(&mut self) -> Option<A> {
177        self.0.next()
178    }
179
180    #[inline]
181    fn size_hint(&self) -> (usize, Option<usize>) {
182        self.0.size_hint()
183    }
184
185    #[inline]
186    fn count(self) -> usize {
187        self.0.count()
188    }
189
190    #[inline]
191    fn nth(&mut self, n: usize) -> Option<A> {
192        self.0.nth(n)
193    }
194
195    #[inline]
196    fn last(self) -> Option<A> {
197        self.0.last()
198    }
199
200    #[inline]
201    fn min(self) -> Option<A>
202    where
203        A: Ord,
204    {
205        self.0.min()
206    }
207
208    #[inline]
209    fn max(self) -> Option<A>
210    where
211        A: Ord,
212    {
213        self.0.max()
214    }
215
216    #[inline]
217    fn is_sorted(self) -> bool {
218        true
219    }
220
221    #[inline]
222    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
223        self.0.advance_by(n)
224    }
225}
226
227#[unstable(feature = "new_range_api", issue = "125687")]
228impl<A: Step> DoubleEndedIterator for IterRangeInclusive<A> {
229    #[inline]
230    fn next_back(&mut self) -> Option<A> {
231        self.0.next_back()
232    }
233
234    #[inline]
235    fn nth_back(&mut self, n: usize) -> Option<A> {
236        self.0.nth_back(n)
237    }
238
239    #[inline]
240    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
241        self.0.advance_back_by(n)
242    }
243}
244
245#[unstable(feature = "trusted_len", issue = "37572")]
246unsafe impl<A: TrustedStep> TrustedLen for IterRangeInclusive<A> {}
247
248#[unstable(feature = "new_range_api", issue = "125687")]
249impl<A: Step> FusedIterator for IterRangeInclusive<A> {}
250
251#[unstable(feature = "new_range_api", issue = "125687")]
252impl<A: Step> IntoIterator for RangeInclusive<A> {
253    type Item = A;
254    type IntoIter = IterRangeInclusive<A>;
255
256    fn into_iter(self) -> Self::IntoIter {
257        IterRangeInclusive(self.into())
258    }
259}
260
261// These macros generate `ExactSizeIterator` impls for various range types.
262//
263// * `ExactSizeIterator::len` is required to always return an exact `usize`,
264//   so no range can be longer than `usize::MAX`.
265// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
266//   For integer types in `RangeInclusive<_>`
267//   this is the case for types *strictly narrower* than `usize`
268//   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
269macro_rules! range_exact_iter_impl {
270    ($($t:ty)*) => ($(
271        #[unstable(feature = "new_range_api", issue = "125687")]
272        impl ExactSizeIterator for IterRange<$t> { }
273    )*)
274}
275
276macro_rules! range_incl_exact_iter_impl {
277    ($($t:ty)*) => ($(
278        #[unstable(feature = "new_range_api", issue = "125687")]
279        impl ExactSizeIterator for IterRangeInclusive<$t> { }
280    )*)
281}
282
283range_exact_iter_impl! {
284    usize u8 u16
285    isize i8 i16
286}
287
288range_incl_exact_iter_impl! {
289    u8
290    i8
291}
292
293/// By-value [`RangeFrom`] iterator.
294#[unstable(feature = "new_range_api", issue = "125687")]
295#[derive(Debug, Clone)]
296pub struct IterRangeFrom<A>(legacy::RangeFrom<A>);
297
298impl<A> IterRangeFrom<A> {
299    /// Returns the remainder of the range being iterated over.
300    pub fn remainder(self) -> RangeFrom<A> {
301        RangeFrom { start: self.0.start }
302    }
303}
304
305#[unstable(feature = "trusted_random_access", issue = "none")]
306impl<A: Step> Iterator for IterRangeFrom<A> {
307    type Item = A;
308
309    #[inline]
310    fn next(&mut self) -> Option<A> {
311        self.0.next()
312    }
313
314    #[inline]
315    fn size_hint(&self) -> (usize, Option<usize>) {
316        self.0.size_hint()
317    }
318
319    #[inline]
320    fn nth(&mut self, n: usize) -> Option<A> {
321        self.0.nth(n)
322    }
323}
324
325#[unstable(feature = "trusted_len", issue = "37572")]
326unsafe impl<A: TrustedStep> TrustedLen for IterRangeFrom<A> {}
327
328#[unstable(feature = "new_range_api", issue = "125687")]
329impl<A: Step> FusedIterator for IterRangeFrom<A> {}
330
331#[unstable(feature = "new_range_api", issue = "125687")]
332impl<A: Step> IntoIterator for RangeFrom<A> {
333    type Item = A;
334    type IntoIter = IterRangeFrom<A>;
335
336    fn into_iter(self) -> Self::IntoIter {
337        IterRangeFrom(self.into())
338    }
339}