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