blob: 9e7055a370c9d6c7a76ded520199164e89f311f6 [file] [log] [blame]
Thiébaud Weksteene40e7362020-10-28 15:03:00 +01001use crate::char;
2use crate::convert::TryFrom;
3use crate::mem;
4use crate::ops::{self, Add, Sub, Try};
5
6use super::{FusedIterator, TrustedLen};
7
8/// Objects that have a notion of *successor* and *predecessor* operations.
9///
10/// The *successor* operation moves towards values that compare greater.
11/// The *predecessor* operation moves towards values that compare lesser.
12///
13/// # Safety
14///
15/// This trait is `unsafe` because its implementation must be correct for
16/// the safety of `unsafe trait TrustedLen` implementations, and the results
17/// of using this trait can otherwise be trusted by `unsafe` code to be correct
18/// and fulfill the listed obligations.
19#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
20pub unsafe trait Step: Clone + PartialOrd + Sized {
21 /// Returns the number of *successor* steps required to get from `start` to `end`.
22 ///
23 /// Returns `None` if the number of steps would overflow `usize`
24 /// (or is infinite, or if `end` would never be reached).
25 ///
26 /// # Invariants
27 ///
28 /// For any `a`, `b`, and `n`:
29 ///
30 /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)`
31 /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&a, n) == Some(a)`
32 /// * `steps_between(&a, &b) == Some(n)` only if `a <= b`
33 /// * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b`
34 /// * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
35 /// this is the case when it would require more than `usize::MAX` steps to get to `b`
36 /// * `steps_between(&a, &b) == None` if `a > b`
37 fn steps_between(start: &Self, end: &Self) -> Option<usize>;
38
39 /// Returns the value that would be obtained by taking the *successor*
40 /// of `self` `count` times.
41 ///
42 /// If this would overflow the range of values supported by `Self`, returns `None`.
43 ///
44 /// # Invariants
45 ///
46 /// For any `a`, `n`, and `m`:
47 ///
48 /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, m).and_then(|x| Step::forward_checked(x, n))`
49 ///
50 /// For any `a`, `n`, and `m` where `n + m` does not overflow:
51 ///
52 /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, n + m)`
53 ///
54 /// For any `a` and `n`:
55 ///
56 /// * `Step::forward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::forward_checked(&x, 1))`
57 /// * Corollary: `Step::forward_checked(&a, 0) == Some(a)`
58 #[unstable(feature = "step_trait_ext", reason = "recently added", issue = "42168")]
59 fn forward_checked(start: Self, count: usize) -> Option<Self>;
60
61 /// Returns the value that would be obtained by taking the *successor*
62 /// of `self` `count` times.
63 ///
64 /// If this would overflow the range of values supported by `Self`,
65 /// this function is allowed to panic, wrap, or saturate.
66 /// The suggested behavior is to panic when debug assertions are enabled,
67 /// and to wrap or saturate otherwise.
68 ///
69 /// Unsafe code should not rely on the correctness of behavior after overflow.
70 ///
71 /// # Invariants
72 ///
73 /// For any `a`, `n`, and `m`, where no overflow occurs:
74 ///
75 /// * `Step::forward(Step::forward(a, n), m) == Step::forward(a, n + m)`
76 ///
77 /// For any `a` and `n`, where no overflow occurs:
78 ///
79 /// * `Step::forward_checked(a, n) == Some(Step::forward(a, n))`
80 /// * `Step::forward(a, n) == (0..n).fold(a, |x, _| Step::forward(x, 1))`
81 /// * Corollary: `Step::forward(a, 0) == a`
82 /// * `Step::forward(a, n) >= a`
83 /// * `Step::backward(Step::forward(a, n), n) == a`
84 #[unstable(feature = "step_trait_ext", reason = "recently added", issue = "42168")]
85 fn forward(start: Self, count: usize) -> Self {
86 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
87 }
88
89 /// Returns the value that would be obtained by taking the *successor*
90 /// of `self` `count` times.
91 ///
92 /// # Safety
93 ///
94 /// It is undefined behavior for this operation to overflow the
95 /// range of values supported by `Self`. If you cannot guarantee that this
96 /// will not overflow, use `forward` or `forward_checked` instead.
97 ///
98 /// # Invariants
99 ///
100 /// For any `a`:
101 ///
102 /// * if there exists `b` such that `b > a`, it is safe to call `Step::forward_unchecked(a, 1)`
103 /// * if there exists `b`, `n` such that `steps_between(&a, &b) == Some(n)`,
104 /// it is safe to call `Step::forward_unchecked(a, m)` for any `m <= n`.
105 ///
106 /// For any `a` and `n`, where no overflow occurs:
107 ///
108 /// * `Step::forward_unchecked(a, n)` is equivalent to `Step::forward(a, n)`
109 #[unstable(feature = "unchecked_math", reason = "niche optimization path", issue = "none")]
110 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
111 Step::forward(start, count)
112 }
113
Jeff Vander Stoep59fbe182021-03-29 10:17:52 +0200114 /// Returns the value that would be obtained by taking the *predecessor*
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100115 /// of `self` `count` times.
116 ///
117 /// If this would overflow the range of values supported by `Self`, returns `None`.
118 ///
119 /// # Invariants
120 ///
121 /// For any `a`, `n`, and `m`:
122 ///
123 /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == n.checked_add(m).and_then(|x| Step::backward_checked(a, x))`
124 /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == try { Step::backward_checked(a, n.checked_add(m)?) }`
125 ///
126 /// For any `a` and `n`:
127 ///
128 /// * `Step::backward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::backward_checked(&x, 1))`
129 /// * Corollary: `Step::backward_checked(&a, 0) == Some(a)`
130 #[unstable(feature = "step_trait_ext", reason = "recently added", issue = "42168")]
131 fn backward_checked(start: Self, count: usize) -> Option<Self>;
132
133 /// Returns the value that would be obtained by taking the *predecessor*
134 /// of `self` `count` times.
135 ///
136 /// If this would overflow the range of values supported by `Self`,
137 /// this function is allowed to panic, wrap, or saturate.
138 /// The suggested behavior is to panic when debug assertions are enabled,
139 /// and to wrap or saturate otherwise.
140 ///
141 /// Unsafe code should not rely on the correctness of behavior after overflow.
142 ///
143 /// # Invariants
144 ///
145 /// For any `a`, `n`, and `m`, where no overflow occurs:
146 ///
147 /// * `Step::backward(Step::backward(a, n), m) == Step::backward(a, n + m)`
148 ///
149 /// For any `a` and `n`, where no overflow occurs:
150 ///
151 /// * `Step::backward_checked(a, n) == Some(Step::backward(a, n))`
152 /// * `Step::backward(a, n) == (0..n).fold(a, |x, _| Step::backward(x, 1))`
153 /// * Corollary: `Step::backward(a, 0) == a`
154 /// * `Step::backward(a, n) <= a`
155 /// * `Step::forward(Step::backward(a, n), n) == a`
156 #[unstable(feature = "step_trait_ext", reason = "recently added", issue = "42168")]
157 fn backward(start: Self, count: usize) -> Self {
158 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
159 }
160
161 /// Returns the value that would be obtained by taking the *predecessor*
162 /// of `self` `count` times.
163 ///
164 /// # Safety
165 ///
166 /// It is undefined behavior for this operation to overflow the
167 /// range of values supported by `Self`. If you cannot guarantee that this
168 /// will not overflow, use `backward` or `backward_checked` instead.
169 ///
170 /// # Invariants
171 ///
172 /// For any `a`:
173 ///
174 /// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)`
175 /// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`,
176 /// it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`.
177 ///
178 /// For any `a` and `n`, where no overflow occurs:
179 ///
180 /// * `Step::backward_unchecked(a, n)` is equivalent to `Step::backward(a, n)`
181 #[unstable(feature = "unchecked_math", reason = "niche optimization path", issue = "none")]
182 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
183 Step::backward(start, count)
184 }
185}
186
187// These are still macro-generated because the integer literals resolve to different types.
188macro_rules! step_identical_methods {
189 () => {
190 #[inline]
191 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
192 // SAFETY: the caller has to guarantee that `start + n` doesn't overflow.
193 unsafe { start.unchecked_add(n as Self) }
194 }
195
196 #[inline]
197 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
198 // SAFETY: the caller has to guarantee that `start - n` doesn't overflow.
199 unsafe { start.unchecked_sub(n as Self) }
200 }
201
202 #[inline]
Jeff Vander Stoep59fbe182021-03-29 10:17:52 +0200203 #[allow(arithmetic_overflow)]
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100204 fn forward(start: Self, n: usize) -> Self {
205 // In debug builds, trigger a panic on overflow.
206 // This should optimize completely out in release builds.
207 if Self::forward_checked(start, n).is_none() {
208 let _ = Add::add(Self::MAX, 1);
209 }
210 // Do wrapping math to allow e.g. `Step::forward(-128i8, 255)`.
211 start.wrapping_add(n as Self)
212 }
213
214 #[inline]
Jeff Vander Stoep59fbe182021-03-29 10:17:52 +0200215 #[allow(arithmetic_overflow)]
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100216 fn backward(start: Self, n: usize) -> Self {
217 // In debug builds, trigger a panic on overflow.
218 // This should optimize completely out in release builds.
219 if Self::backward_checked(start, n).is_none() {
220 let _ = Sub::sub(Self::MIN, 1);
221 }
222 // Do wrapping math to allow e.g. `Step::backward(127i8, 255)`.
223 start.wrapping_sub(n as Self)
224 }
225 };
226}
227
228macro_rules! step_integer_impls {
229 {
230 narrower than or same width as usize:
231 $( [ $u_narrower:ident $i_narrower:ident ] ),+;
232 wider than usize:
233 $( [ $u_wider:ident $i_wider:ident ] ),+;
234 } => {
235 $(
236 #[allow(unreachable_patterns)]
237 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
238 unsafe impl Step for $u_narrower {
239 step_identical_methods!();
240
241 #[inline]
242 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
243 if *start <= *end {
244 // This relies on $u_narrower <= usize
245 Some((*end - *start) as usize)
246 } else {
247 None
248 }
249 }
250
251 #[inline]
252 fn forward_checked(start: Self, n: usize) -> Option<Self> {
253 match Self::try_from(n) {
254 Ok(n) => start.checked_add(n),
255 Err(_) => None, // if n is out of range, `unsigned_start + n` is too
256 }
257 }
258
259 #[inline]
260 fn backward_checked(start: Self, n: usize) -> Option<Self> {
261 match Self::try_from(n) {
262 Ok(n) => start.checked_sub(n),
263 Err(_) => None, // if n is out of range, `unsigned_start - n` is too
264 }
265 }
266 }
267
268 #[allow(unreachable_patterns)]
269 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
270 unsafe impl Step for $i_narrower {
271 step_identical_methods!();
272
273 #[inline]
274 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
275 if *start <= *end {
276 // This relies on $i_narrower <= usize
277 //
278 // Casting to isize extends the width but preserves the sign.
279 // Use wrapping_sub in isize space and cast to usize to compute
280 // the difference that may not fit inside the range of isize.
281 Some((*end as isize).wrapping_sub(*start as isize) as usize)
282 } else {
283 None
284 }
285 }
286
287 #[inline]
288 fn forward_checked(start: Self, n: usize) -> Option<Self> {
289 match $u_narrower::try_from(n) {
290 Ok(n) => {
291 // Wrapping handles cases like
292 // `Step::forward(-120_i8, 200) == Some(80_i8)`,
293 // even though 200 is out of range for i8.
294 let wrapped = start.wrapping_add(n as Self);
295 if wrapped >= start {
296 Some(wrapped)
297 } else {
298 None // Addition overflowed
299 }
300 }
301 // If n is out of range of e.g. u8,
302 // then it is bigger than the entire range for i8 is wide
303 // so `any_i8 + n` necessarily overflows i8.
304 Err(_) => None,
305 }
306 }
307
308 #[inline]
309 fn backward_checked(start: Self, n: usize) -> Option<Self> {
310 match $u_narrower::try_from(n) {
311 Ok(n) => {
312 // Wrapping handles cases like
313 // `Step::forward(-120_i8, 200) == Some(80_i8)`,
314 // even though 200 is out of range for i8.
315 let wrapped = start.wrapping_sub(n as Self);
316 if wrapped <= start {
317 Some(wrapped)
318 } else {
319 None // Subtraction overflowed
320 }
321 }
322 // If n is out of range of e.g. u8,
323 // then it is bigger than the entire range for i8 is wide
324 // so `any_i8 - n` necessarily overflows i8.
325 Err(_) => None,
326 }
327 }
328 }
329 )+
330
331 $(
332 #[allow(unreachable_patterns)]
333 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
334 unsafe impl Step for $u_wider {
335 step_identical_methods!();
336
337 #[inline]
338 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
339 if *start <= *end {
340 usize::try_from(*end - *start).ok()
341 } else {
342 None
343 }
344 }
345
346 #[inline]
347 fn forward_checked(start: Self, n: usize) -> Option<Self> {
348 start.checked_add(n as Self)
349 }
350
351 #[inline]
352 fn backward_checked(start: Self, n: usize) -> Option<Self> {
353 start.checked_sub(n as Self)
354 }
355 }
356
357 #[allow(unreachable_patterns)]
358 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
359 unsafe impl Step for $i_wider {
360 step_identical_methods!();
361
362 #[inline]
363 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
364 if *start <= *end {
365 match end.checked_sub(*start) {
366 Some(result) => usize::try_from(result).ok(),
367 // If the difference is too big for e.g. i128,
368 // it's also gonna be too big for usize with fewer bits.
369 None => None,
370 }
371 } else {
372 None
373 }
374 }
375
376 #[inline]
377 fn forward_checked(start: Self, n: usize) -> Option<Self> {
378 start.checked_add(n as Self)
379 }
380
381 #[inline]
382 fn backward_checked(start: Self, n: usize) -> Option<Self> {
383 start.checked_sub(n as Self)
384 }
385 }
386 )+
387 };
388}
389
390#[cfg(target_pointer_width = "64")]
391step_integer_impls! {
392 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize];
393 wider than usize: [u128 i128];
394}
395
396#[cfg(target_pointer_width = "32")]
397step_integer_impls! {
398 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize];
399 wider than usize: [u64 i64], [u128 i128];
400}
401
402#[cfg(target_pointer_width = "16")]
403step_integer_impls! {
404 narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize];
405 wider than usize: [u32 i32], [u64 i64], [u128 i128];
406}
407
408#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
409unsafe impl Step for char {
410 #[inline]
411 fn steps_between(&start: &char, &end: &char) -> Option<usize> {
412 let start = start as u32;
413 let end = end as u32;
414 if start <= end {
415 let count = end - start;
416 if start < 0xD800 && 0xE000 <= end {
417 usize::try_from(count - 0x800).ok()
418 } else {
419 usize::try_from(count).ok()
420 }
421 } else {
422 None
423 }
424 }
425
426 #[inline]
427 fn forward_checked(start: char, count: usize) -> Option<char> {
428 let start = start as u32;
429 let mut res = Step::forward_checked(start, count)?;
430 if start < 0xD800 && 0xD800 <= res {
431 res = Step::forward_checked(res, 0x800)?;
432 }
433 if res <= char::MAX as u32 {
434 // SAFETY: res is a valid unicode scalar
435 // (below 0x110000 and not in 0xD800..0xE000)
436 Some(unsafe { char::from_u32_unchecked(res) })
437 } else {
438 None
439 }
440 }
441
442 #[inline]
443 fn backward_checked(start: char, count: usize) -> Option<char> {
444 let start = start as u32;
445 let mut res = Step::backward_checked(start, count)?;
446 if start >= 0xE000 && 0xE000 > res {
447 res = Step::backward_checked(res, 0x800)?;
448 }
449 // SAFETY: res is a valid unicode scalar
450 // (below 0x110000 and not in 0xD800..0xE000)
451 Some(unsafe { char::from_u32_unchecked(res) })
452 }
453
454 #[inline]
455 unsafe fn forward_unchecked(start: char, count: usize) -> char {
456 let start = start as u32;
457 // SAFETY: the caller must guarantee that this doesn't overflow
458 // the range of values for a char.
459 let mut res = unsafe { Step::forward_unchecked(start, count) };
460 if start < 0xD800 && 0xD800 <= res {
461 // SAFETY: the caller must guarantee that this doesn't overflow
462 // the range of values for a char.
463 res = unsafe { Step::forward_unchecked(res, 0x800) };
464 }
465 // SAFETY: because of the previous contract, this is guaranteed
466 // by the caller to be a valid char.
467 unsafe { char::from_u32_unchecked(res) }
468 }
469
470 #[inline]
471 unsafe fn backward_unchecked(start: char, count: usize) -> char {
472 let start = start as u32;
473 // SAFETY: the caller must guarantee that this doesn't overflow
474 // the range of values for a char.
475 let mut res = unsafe { Step::backward_unchecked(start, count) };
476 if start >= 0xE000 && 0xE000 > res {
477 // SAFETY: the caller must guarantee that this doesn't overflow
478 // the range of values for a char.
479 res = unsafe { Step::backward_unchecked(res, 0x800) };
480 }
481 // SAFETY: because of the previous contract, this is guaranteed
482 // by the caller to be a valid char.
483 unsafe { char::from_u32_unchecked(res) }
484 }
485}
486
487macro_rules! range_exact_iter_impl {
488 ($($t:ty)*) => ($(
489 #[stable(feature = "rust1", since = "1.0.0")]
490 impl ExactSizeIterator for ops::Range<$t> { }
491 )*)
492}
493
494macro_rules! range_incl_exact_iter_impl {
495 ($($t:ty)*) => ($(
496 #[stable(feature = "inclusive_range", since = "1.26.0")]
497 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
498 )*)
499}
500
501#[stable(feature = "rust1", since = "1.0.0")]
502impl<A: Step> Iterator for ops::Range<A> {
503 type Item = A;
504
505 #[inline]
506 fn next(&mut self) -> Option<A> {
507 if self.start < self.end {
508 // SAFETY: just checked precondition
509 let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
510 Some(mem::replace(&mut self.start, n))
511 } else {
512 None
513 }
514 }
515
516 #[inline]
517 fn size_hint(&self) -> (usize, Option<usize>) {
518 if self.start < self.end {
519 let hint = Step::steps_between(&self.start, &self.end);
520 (hint.unwrap_or(usize::MAX), hint)
521 } else {
522 (0, Some(0))
523 }
524 }
525
526 #[inline]
527 fn nth(&mut self, n: usize) -> Option<A> {
528 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
529 if plus_n < self.end {
530 // SAFETY: just checked precondition
531 self.start = unsafe { Step::forward_unchecked(plus_n.clone(), 1) };
532 return Some(plus_n);
533 }
534 }
535
536 self.start = self.end.clone();
537 None
538 }
539
540 #[inline]
541 fn last(mut self) -> Option<A> {
542 self.next_back()
543 }
544
545 #[inline]
546 fn min(mut self) -> Option<A> {
547 self.next()
548 }
549
550 #[inline]
551 fn max(mut self) -> Option<A> {
552 self.next_back()
553 }
554}
555
556// These macros generate `ExactSizeIterator` impls for various range types.
557//
558// * `ExactSizeIterator::len` is required to always return an exact `usize`,
559// so no range can be longer than `usize::MAX`.
560// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
561// For integer types in `RangeInclusive<_>`
562// this is the case for types *strictly narrower* than `usize`
563// since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
564range_exact_iter_impl! {
565 usize u8 u16
566 isize i8 i16
567
568 // These are incorect per the reasoning above,
569 // but removing them would be a breaking change as they were stabilized in Rust 1.0.0.
570 // So e.g. `(0..66_000_u32).len()` for example will compile without error or warnings
571 // on 16-bit platforms, but continue to give a wrong result.
572 u32
573 i32
574}
575range_incl_exact_iter_impl! {
576 u8
577 i8
578
579 // These are incorect per the reasoning above,
580 // but removing them would be a breaking change as they were stabilized in Rust 1.26.0.
581 // So e.g. `(0..=u16::MAX).len()` for example will compile without error or warnings
582 // on 16-bit platforms, but continue to give a wrong result.
583 u16
584 i16
585}
586
587#[stable(feature = "rust1", since = "1.0.0")]
588impl<A: Step> DoubleEndedIterator for ops::Range<A> {
589 #[inline]
590 fn next_back(&mut self) -> Option<A> {
591 if self.start < self.end {
592 // SAFETY: just checked precondition
593 self.end = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
594 Some(self.end.clone())
595 } else {
596 None
597 }
598 }
599
600 #[inline]
601 fn nth_back(&mut self, n: usize) -> Option<A> {
602 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
603 if minus_n > self.start {
604 // SAFETY: just checked precondition
605 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
606 return Some(self.end.clone());
607 }
608 }
609
610 self.end = self.start.clone();
611 None
612 }
613}
614
615#[unstable(feature = "trusted_len", issue = "37572")]
616unsafe impl<A: Step> TrustedLen for ops::Range<A> {}
617
618#[stable(feature = "fused", since = "1.26.0")]
619impl<A: Step> FusedIterator for ops::Range<A> {}
620
621#[stable(feature = "rust1", since = "1.0.0")]
622impl<A: Step> Iterator for ops::RangeFrom<A> {
623 type Item = A;
624
625 #[inline]
626 fn next(&mut self) -> Option<A> {
627 let n = Step::forward(self.start.clone(), 1);
628 Some(mem::replace(&mut self.start, n))
629 }
630
631 #[inline]
632 fn size_hint(&self) -> (usize, Option<usize>) {
633 (usize::MAX, None)
634 }
635
636 #[inline]
637 fn nth(&mut self, n: usize) -> Option<A> {
638 let plus_n = Step::forward(self.start.clone(), n);
639 self.start = Step::forward(plus_n.clone(), 1);
640 Some(plus_n)
641 }
642}
643
644#[stable(feature = "fused", since = "1.26.0")]
645impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
646
647#[unstable(feature = "trusted_len", issue = "37572")]
648unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
649
650#[stable(feature = "inclusive_range", since = "1.26.0")]
651impl<A: Step> Iterator for ops::RangeInclusive<A> {
652 type Item = A;
653
654 #[inline]
655 fn next(&mut self) -> Option<A> {
656 if self.is_empty() {
657 return None;
658 }
659 let is_iterating = self.start < self.end;
660 Some(if is_iterating {
661 // SAFETY: just checked precondition
662 let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
663 mem::replace(&mut self.start, n)
664 } else {
665 self.exhausted = true;
666 self.start.clone()
667 })
668 }
669
670 #[inline]
671 fn size_hint(&self) -> (usize, Option<usize>) {
672 if self.is_empty() {
673 return (0, Some(0));
674 }
675
676 match Step::steps_between(&self.start, &self.end) {
677 Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
678 None => (usize::MAX, None),
679 }
680 }
681
682 #[inline]
683 fn nth(&mut self, n: usize) -> Option<A> {
684 if self.is_empty() {
685 return None;
686 }
687
688 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
689 use crate::cmp::Ordering::*;
690
691 match plus_n.partial_cmp(&self.end) {
692 Some(Less) => {
693 self.start = Step::forward(plus_n.clone(), 1);
694 return Some(plus_n);
695 }
696 Some(Equal) => {
697 self.start = plus_n.clone();
698 self.exhausted = true;
699 return Some(plus_n);
700 }
701 _ => {}
702 }
703 }
704
705 self.start = self.end.clone();
706 self.exhausted = true;
707 None
708 }
709
710 #[inline]
711 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
712 where
713 Self: Sized,
714 F: FnMut(B, Self::Item) -> R,
715 R: Try<Ok = B>,
716 {
717 if self.is_empty() {
Thiébaud Weksteen5bd94c12021-01-06 15:18:42 +0100718 return try { init };
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100719 }
720
721 let mut accum = init;
722
723 while self.start < self.end {
724 // SAFETY: just checked precondition
725 let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
726 let n = mem::replace(&mut self.start, n);
727 accum = f(accum, n)?;
728 }
729
730 self.exhausted = true;
731
732 if self.start == self.end {
733 accum = f(accum, self.start.clone())?;
734 }
735
Thiébaud Weksteen5bd94c12021-01-06 15:18:42 +0100736 try { accum }
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100737 }
738
739 #[inline]
740 fn fold<B, F>(mut self, init: B, f: F) -> B
741 where
742 Self: Sized,
743 F: FnMut(B, Self::Item) -> B,
744 {
745 #[inline]
746 fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
747 move |acc, x| Ok(f(acc, x))
748 }
749
750 self.try_fold(init, ok(f)).unwrap()
751 }
752
753 #[inline]
754 fn last(mut self) -> Option<A> {
755 self.next_back()
756 }
757
758 #[inline]
759 fn min(mut self) -> Option<A> {
760 self.next()
761 }
762
763 #[inline]
764 fn max(mut self) -> Option<A> {
765 self.next_back()
766 }
767}
768
769#[stable(feature = "inclusive_range", since = "1.26.0")]
770impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
771 #[inline]
772 fn next_back(&mut self) -> Option<A> {
773 if self.is_empty() {
774 return None;
775 }
776 let is_iterating = self.start < self.end;
777 Some(if is_iterating {
778 // SAFETY: just checked precondition
779 let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
780 mem::replace(&mut self.end, n)
781 } else {
782 self.exhausted = true;
783 self.end.clone()
784 })
785 }
786
787 #[inline]
788 fn nth_back(&mut self, n: usize) -> Option<A> {
789 if self.is_empty() {
790 return None;
791 }
792
793 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
794 use crate::cmp::Ordering::*;
795
796 match minus_n.partial_cmp(&self.start) {
797 Some(Greater) => {
798 self.end = Step::backward(minus_n.clone(), 1);
799 return Some(minus_n);
800 }
801 Some(Equal) => {
802 self.end = minus_n.clone();
803 self.exhausted = true;
804 return Some(minus_n);
805 }
806 _ => {}
807 }
808 }
809
810 self.end = self.start.clone();
811 self.exhausted = true;
812 None
813 }
814
815 #[inline]
816 fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
817 where
818 Self: Sized,
819 F: FnMut(B, Self::Item) -> R,
820 R: Try<Ok = B>,
821 {
822 if self.is_empty() {
Thiébaud Weksteen5bd94c12021-01-06 15:18:42 +0100823 return try { init };
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100824 }
825
826 let mut accum = init;
827
828 while self.start < self.end {
829 // SAFETY: just checked precondition
830 let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
831 let n = mem::replace(&mut self.end, n);
832 accum = f(accum, n)?;
833 }
834
835 self.exhausted = true;
836
837 if self.start == self.end {
838 accum = f(accum, self.start.clone())?;
839 }
840
Thiébaud Weksteen5bd94c12021-01-06 15:18:42 +0100841 try { accum }
Thiébaud Weksteene40e7362020-10-28 15:03:00 +0100842 }
843
844 #[inline]
845 fn rfold<B, F>(mut self, init: B, f: F) -> B
846 where
847 Self: Sized,
848 F: FnMut(B, Self::Item) -> B,
849 {
850 #[inline]
851 fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
852 move |acc, x| Ok(f(acc, x))
853 }
854
855 self.try_rfold(init, ok(f)).unwrap()
856 }
857}
858
859#[unstable(feature = "trusted_len", issue = "37572")]
860unsafe impl<A: Step> TrustedLen for ops::RangeInclusive<A> {}
861
862#[stable(feature = "fused", since = "1.26.0")]
863impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}