Skip to main content

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};
6use crate::{intrinsics, mem};
7
8/// By-value [`Range`] iterator.
9#[stable(feature = "new_range_api", since = "1.96.0")]
10#[derive(Debug, Clone)]
11pub struct RangeIter<A>(pub(crate) legacy::Range<A>);
12
13impl<A> RangeIter<A> {
14    #[unstable(feature = "new_range_remainder", issue = "154458")]
15    /// Returns the remainder of the range being iterated over.
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// #![feature(new_range_remainder)]
21    ///
22    /// let range = core::range::Range::from(3..11);
23    /// let mut iter = range.into_iter();
24    /// assert_eq!(iter.clone().remainder(), range);
25    /// iter.next();
26    /// assert_eq!(iter.clone().remainder(), core::range::Range::from(4..11));
27    /// iter.by_ref().for_each(drop);
28    /// assert!(iter.remainder().is_empty());
29    /// ```
30    pub fn remainder(self) -> Range<A> {
31        Range { start: self.0.start, end: self.0.end }
32    }
33}
34
35/// Safety: This macro must only be used on types that are `Copy` and result in ranges
36/// which have an exact `size_hint()` where the upper bound must not be `None`.
37macro_rules! unsafe_range_trusted_random_access_impl {
38    ($($t:ty)*) => ($(
39        #[doc(hidden)]
40        #[unstable(feature = "trusted_random_access", issue = "none")]
41        unsafe impl TrustedRandomAccess for RangeIter<$t> {}
42
43        #[doc(hidden)]
44        #[unstable(feature = "trusted_random_access", issue = "none")]
45        unsafe impl TrustedRandomAccessNoCoerce for RangeIter<$t> {
46            const MAY_HAVE_SIDE_EFFECT: bool = false;
47        }
48    )*)
49}
50
51unsafe_range_trusted_random_access_impl! {
52    usize u8 u16
53    isize i8 i16
54}
55
56#[cfg(target_pointer_width = "32")]
57unsafe_range_trusted_random_access_impl! {
58    u32 i32
59}
60
61#[cfg(target_pointer_width = "64")]
62unsafe_range_trusted_random_access_impl! {
63    u32 i32
64    u64 i64
65}
66
67#[stable(feature = "new_range_api", since = "1.96.0")]
68impl<A: Step> Iterator for RangeIter<A> {
69    type Item = A;
70
71    #[inline]
72    #[ferrocene::prevalidated]
73    fn next(&mut self) -> Option<A> {
74        self.0.next()
75    }
76
77    #[inline]
78    #[ferrocene::prevalidated]
79    fn size_hint(&self) -> (usize, Option<usize>) {
80        self.0.size_hint()
81    }
82
83    #[inline]
84    #[ferrocene::prevalidated]
85    fn count(self) -> usize {
86        self.0.count()
87    }
88
89    #[inline]
90    #[ferrocene::prevalidated]
91    fn nth(&mut self, n: usize) -> Option<A> {
92        self.0.nth(n)
93    }
94
95    #[inline]
96    #[ferrocene::prevalidated]
97    fn last(self) -> Option<A> {
98        self.0.last()
99    }
100
101    #[inline]
102    fn min(self) -> Option<A>
103    where
104        A: Ord,
105    {
106        self.0.min()
107    }
108
109    #[inline]
110    fn max(self) -> Option<A>
111    where
112        A: Ord,
113    {
114        self.0.max()
115    }
116
117    #[inline]
118    fn is_sorted(self) -> bool {
119        true
120    }
121
122    #[inline]
123    #[ferrocene::prevalidated]
124    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
125        self.0.advance_by(n)
126    }
127
128    #[inline]
129    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
130    where
131        Self: TrustedRandomAccessNoCoerce,
132    {
133        // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
134        // that is in bounds.
135        // Additionally Self: TrustedRandomAccess is only implemented for Copy types
136        // which means even repeated reads of the same index would be safe.
137        unsafe { Step::forward_unchecked(self.0.start.clone(), idx) }
138    }
139}
140
141#[stable(feature = "new_range_api", since = "1.96.0")]
142impl<A: Step> DoubleEndedIterator for RangeIter<A> {
143    #[inline]
144    #[ferrocene::prevalidated]
145    fn next_back(&mut self) -> Option<A> {
146        self.0.next_back()
147    }
148
149    #[inline]
150    #[ferrocene::prevalidated]
151    fn nth_back(&mut self, n: usize) -> Option<A> {
152        self.0.nth_back(n)
153    }
154
155    #[inline]
156    #[ferrocene::prevalidated]
157    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
158        self.0.advance_back_by(n)
159    }
160}
161
162#[unstable(feature = "trusted_len", issue = "37572")]
163unsafe impl<A: TrustedStep> TrustedLen for RangeIter<A> {}
164
165#[stable(feature = "new_range_api", since = "1.96.0")]
166impl<A: Step> FusedIterator for RangeIter<A> {}
167
168#[stable(feature = "new_range_api", since = "1.96.0")]
169impl<A: Step> IntoIterator for Range<A> {
170    type Item = A;
171    type IntoIter = RangeIter<A>;
172
173    fn into_iter(self) -> Self::IntoIter {
174        RangeIter(self.into())
175    }
176}
177
178/// By-value [`RangeInclusive`] iterator.
179#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
180#[derive(Debug, Clone)]
181pub struct RangeInclusiveIter<A>(legacy::RangeInclusive<A>);
182
183impl<A: Step> RangeInclusiveIter<A> {
184    /// Returns the remainder of the range being iterated over.
185    ///
186    /// If the iterator is exhausted or empty, returns `None`.
187    ///
188    /// # Examples
189    ///
190    /// ```
191    /// #![feature(new_range_remainder)]
192    ///
193    /// let range = core::range::RangeInclusive::from(3..=11);
194    /// let mut iter = range.into_iter();
195    /// assert_eq!(iter.clone().remainder().unwrap(), range);
196    /// iter.next();
197    /// assert_eq!(iter.clone().remainder().unwrap(), core::range::RangeInclusive::from(4..=11));
198    /// iter.by_ref().for_each(drop);
199    /// assert!(iter.remainder().is_none());
200    /// ```
201    #[unstable(feature = "new_range_remainder", issue = "154458")]
202    pub fn remainder(self) -> Option<RangeInclusive<A>> {
203        if self.0.is_empty() {
204            return None;
205        }
206
207        Some(RangeInclusive { start: self.0.start, last: self.0.end })
208    }
209}
210
211#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
212impl<A: Step> Iterator for RangeInclusiveIter<A> {
213    type Item = A;
214
215    #[inline]
216    #[ferrocene::prevalidated]
217    fn next(&mut self) -> Option<A> {
218        self.0.next()
219    }
220
221    #[inline]
222    #[ferrocene::prevalidated]
223    fn size_hint(&self) -> (usize, Option<usize>) {
224        self.0.size_hint()
225    }
226
227    #[inline]
228    #[ferrocene::prevalidated]
229    fn count(self) -> usize {
230        self.0.count()
231    }
232
233    #[inline]
234    #[ferrocene::prevalidated]
235    fn nth(&mut self, n: usize) -> Option<A> {
236        self.0.nth(n)
237    }
238
239    #[inline]
240    #[ferrocene::prevalidated]
241    fn last(self) -> Option<A> {
242        self.0.last()
243    }
244
245    #[inline]
246    fn min(self) -> Option<A>
247    where
248        A: Ord,
249    {
250        self.0.min()
251    }
252
253    #[inline]
254    fn max(self) -> Option<A>
255    where
256        A: Ord,
257    {
258        self.0.max()
259    }
260
261    #[inline]
262    fn is_sorted(self) -> bool {
263        true
264    }
265
266    #[inline]
267    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
268        self.0.advance_by(n)
269    }
270}
271
272#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
273impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> {
274    #[inline]
275    #[ferrocene::prevalidated]
276    fn next_back(&mut self) -> Option<A> {
277        self.0.next_back()
278    }
279
280    #[inline]
281    #[ferrocene::prevalidated]
282    fn nth_back(&mut self, n: usize) -> Option<A> {
283        self.0.nth_back(n)
284    }
285
286    #[inline]
287    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
288        self.0.advance_back_by(n)
289    }
290}
291
292#[unstable(feature = "trusted_len", issue = "37572")]
293unsafe impl<A: TrustedStep> TrustedLen for RangeInclusiveIter<A> {}
294
295#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
296impl<A: Step> FusedIterator for RangeInclusiveIter<A> {}
297
298#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
299impl<A: Step> IntoIterator for RangeInclusive<A> {
300    type Item = A;
301    type IntoIter = RangeInclusiveIter<A>;
302
303    fn into_iter(self) -> Self::IntoIter {
304        RangeInclusiveIter(self.into())
305    }
306}
307
308// These macros generate `ExactSizeIterator` impls for various range types.
309//
310// * `ExactSizeIterator::len` is required to always return an exact `usize`,
311//   so no range can be longer than `usize::MAX`.
312// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
313//   For integer types in `RangeInclusive<_>`
314//   this is the case for types *strictly narrower* than `usize`
315//   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
316macro_rules! range_exact_iter_impl {
317    ($($t:ty)*) => ($(
318        #[stable(feature = "new_range_api", since = "1.96.0")]
319        impl ExactSizeIterator for RangeIter<$t> { }
320    )*)
321}
322
323macro_rules! range_incl_exact_iter_impl {
324    ($($t:ty)*) => ($(
325        #[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
326        impl ExactSizeIterator for RangeInclusiveIter<$t> { }
327    )*)
328}
329
330range_exact_iter_impl! {
331    usize u8 u16
332    isize i8 i16
333}
334
335range_incl_exact_iter_impl! {
336    u8
337    i8
338}
339
340/// By-value [`RangeFrom`] iterator.
341#[stable(feature = "new_range_from_api", since = "1.96.0")]
342#[derive(Debug, Clone)]
343pub struct RangeFromIter<A> {
344    start: A,
345    /// Whether the maximum value of the iterator has yielded.
346    /// Only used when overflow checks are enabled.
347    exhausted: bool,
348}
349
350impl<A: Step> RangeFromIter<A> {
351    /// Returns the remainder of the range being iterated over.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// #![feature(new_range_remainder)]
357    ///
358    /// let range = core::range::RangeFrom::from(3..);
359    /// let mut iter = range.into_iter();
360    /// assert_eq!(iter.clone().remainder(), range);
361    /// iter.next();
362    /// assert_eq!(iter.remainder(), core::range::RangeFrom::from(4..));
363    /// ```
364    #[inline]
365    #[rustc_inherit_overflow_checks]
366    #[unstable(feature = "new_range_remainder", issue = "154458")]
367    pub fn remainder(self) -> RangeFrom<A> {
368        // Need to handle this case even if overflow-checks are disabled,
369        // because a `RangeFromIter` could be exhausted in a crate with
370        // overflow-checks enabled, but then passed to a crate with them
371        // disabled before this is called.
372        if self.exhausted {
373            return RangeFrom { start: Step::forward(self.start, 1) };
374        }
375
376        RangeFrom { start: self.start }
377    }
378}
379
380#[stable(feature = "new_range_from_api", since = "1.96.0")]
381impl<A: Step> Iterator for RangeFromIter<A> {
382    type Item = A;
383
384    #[inline]
385    #[rustc_inherit_overflow_checks]
386    fn next(&mut self) -> Option<A> {
387        if self.exhausted {
388            // This should panic if overflow checks are enabled, since
389            // `forward_checked` returned `None` in prior iteration.
390            self.start = Step::forward(self.start.clone(), 1);
391
392            // If we get here, if means this iterator was exhausted by a crate
393            // with overflow-checks enabled, but now we're iterating in a crate with
394            // overflow-checks disabled. Since we successfully incremented `self.start`
395            // above (in many cases this will wrap around to MIN), we now unset
396            // the flag so we don't repeat this process in the next iteration.
397            //
398            // This could also happen if `forward_checked` returned None but
399            // (for whatever reason, not applicable to any std implementors)
400            // `forward` doesn't panic when overflow-checks are enabled. In that
401            // case, this is also the correct behavior.
402            self.exhausted = false;
403        }
404        if intrinsics::overflow_checks() {
405            let Some(n) = Step::forward_checked(self.start.clone(), 1) else {
406                self.exhausted = true;
407                return Some(self.start.clone());
408            };
409            return Some(mem::replace(&mut self.start, n));
410        }
411
412        let n = Step::forward(self.start.clone(), 1);
413        Some(mem::replace(&mut self.start, n))
414    }
415
416    #[inline]
417    fn size_hint(&self) -> (usize, Option<usize>) {
418        (usize::MAX, None)
419    }
420
421    #[inline]
422    #[rustc_inherit_overflow_checks]
423    fn nth(&mut self, n: usize) -> Option<A> {
424        // Typically `forward` will cause an overflow-check panic here,
425        // but unset the exhausted flag to handle the uncommon cases.
426        // See the comments in `next` for more details.
427        if self.exhausted {
428            self.start = Step::forward(self.start.clone(), 1);
429            self.exhausted = false;
430        }
431        if intrinsics::overflow_checks() {
432            let plus_n = Step::forward(self.start.clone(), n);
433            if let Some(plus_n1) = Step::forward_checked(plus_n.clone(), 1) {
434                self.start = plus_n1;
435            } else {
436                self.start = plus_n.clone();
437                self.exhausted = true;
438            }
439            return Some(plus_n);
440        }
441
442        let plus_n = Step::forward(self.start.clone(), n);
443        self.start = Step::forward(plus_n.clone(), 1);
444        Some(plus_n)
445    }
446}
447
448#[unstable(feature = "trusted_len", issue = "37572")]
449unsafe impl<A: TrustedStep> TrustedLen for RangeFromIter<A> {}
450
451#[stable(feature = "new_range_from_api", since = "1.96.0")]
452impl<A: Step> FusedIterator for RangeFromIter<A> {}
453
454#[stable(feature = "new_range_from_api", since = "1.96.0")]
455impl<A: Step> IntoIterator for RangeFrom<A> {
456    type Item = A;
457    type IntoIter = RangeFromIter<A>;
458
459    fn into_iter(self) -> Self::IntoIter {
460        RangeFromIter { start: self.start, exhausted: false }
461    }
462}