1use super::{
2 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
3};
4use crate::ascii::Char as AsciiChar;
5use crate::mem;
6use crate::net::{Ipv4Addr, Ipv6Addr};
7use crate::num::NonZero;
8use crate::ops::{self, Try};
9
10macro_rules! unsafe_impl_trusted_step {
12 ($($type:ty)*) => {$(
13 #[unstable(feature = "trusted_step", issue = "85731")]
14 unsafe impl TrustedStep for $type {}
15 )*};
16}
17unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];
18unsafe_impl_trusted_step![NonZero<u8> NonZero<u16> NonZero<u32> NonZero<u64> NonZero<u128> NonZero<usize>];
19
20#[rustc_diagnostic_item = "range_step"]
25#[diagnostic::on_unimplemented(
26 message = "`std::ops::Range<{Self}>` is not an iterator",
27 label = "`Range<{Self}>` is not an iterator",
28 note = "`Range` only implements `Iterator` for select types in the standard library, \
29 particularly integers; to see the full list of types, see the documentation for the \
30 unstable `Step` trait"
31)]
32#[unstable(feature = "step_trait", issue = "42168")]
33#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
34pub const trait Step: [const] Clone + [const] PartialOrd + Sized {
35 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
50
51 fn forward_checked(start: Self, count: usize) -> Option<Self>;
68
69 fn forward(start: Self, count: usize) -> Self {
93 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
94 }
95
96 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
118 Step::forward(start, count)
119 }
120
121 fn backward_checked(start: Self, count: usize) -> Option<Self>;
138
139 fn backward(start: Self, count: usize) -> Self {
163 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
164 }
165
166 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
188 Step::backward(start, count)
189 }
190}
191
192macro_rules! step_signed_methods {
195 ($unsigned: ty) => {
196 #[inline]
197 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
198 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
200 }
201
202 #[inline]
203 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
204 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
206 }
207 };
208}
209
210macro_rules! step_unsigned_methods {
211 () => {
212 #[inline]
213 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
214 unsafe { start.unchecked_add(n as Self) }
216 }
217
218 #[inline]
219 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
220 unsafe { start.unchecked_sub(n as Self) }
222 }
223 };
224}
225
226macro_rules! step_identical_methods {
228 () => {
229 #[inline]
230 #[allow(arithmetic_overflow)]
231 #[rustc_inherit_overflow_checks]
232 fn forward(start: Self, n: usize) -> Self {
233 if Self::forward_checked(start, n).is_none() {
236 let _ = Self::MAX + 1;
237 }
238 start.wrapping_add(n as Self)
240 }
241
242 #[inline]
243 #[allow(arithmetic_overflow)]
244 #[rustc_inherit_overflow_checks]
245 fn backward(start: Self, n: usize) -> Self {
246 if Self::backward_checked(start, n).is_none() {
249 let _ = Self::MIN - 1;
250 }
251 start.wrapping_sub(n as Self)
253 }
254 };
255}
256
257macro_rules! step_integer_impls {
258 {
259 [ $( [ $u_narrower:ident $i_narrower:ident ] ),+ ] <= usize <
260 [ $( [ $u_wider:ident $i_wider:ident ] ),+ ]
261 } => {
262 $(
263 #[allow(unreachable_patterns)]
264 #[unstable(feature = "step_trait", issue = "42168")]
265 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
266 impl const Step for $u_narrower {
267 step_identical_methods!();
268 step_unsigned_methods!();
269
270 #[inline]
271 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
272 if *start <= *end {
273 let steps = (*end - *start) as usize;
275 (steps, Some(steps))
276 } else {
277 (0, None)
278 }
279 }
280
281 #[inline]
282 fn forward_checked(start: Self, n: usize) -> Option<Self> {
283 match Self::try_from(n) {
284 Ok(n) => start.checked_add(n),
285 Err(_) => None, }
287 }
288
289 #[inline]
290 fn backward_checked(start: Self, n: usize) -> Option<Self> {
291 match Self::try_from(n) {
292 Ok(n) => start.checked_sub(n),
293 Err(_) => None, }
295 }
296 }
297
298 #[allow(unreachable_patterns)]
299 #[unstable(feature = "step_trait", issue = "42168")]
300 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
301 impl const Step for $i_narrower {
302 step_identical_methods!();
303 step_signed_methods!($u_narrower);
304
305 #[inline]
306 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
307 if *start <= *end {
308 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
314 (steps, Some(steps))
315 } else {
316 (0, None)
317 }
318 }
319
320 #[inline]
321 fn forward_checked(start: Self, n: usize) -> Option<Self> {
322 match $u_narrower::try_from(n) {
323 Ok(n) => {
324 let wrapped = start.wrapping_add(n as Self);
328 if wrapped >= start {
329 Some(wrapped)
330 } else {
331 None }
333 }
334 Err(_) => None,
338 }
339 }
340
341 #[inline]
342 fn backward_checked(start: Self, n: usize) -> Option<Self> {
343 match $u_narrower::try_from(n) {
344 Ok(n) => {
345 let wrapped = start.wrapping_sub(n as Self);
349 if wrapped <= start {
350 Some(wrapped)
351 } else {
352 None }
354 }
355 Err(_) => None,
359 }
360 }
361 }
362 )+
363
364 $(
365 #[allow(unreachable_patterns)]
366 #[unstable(feature = "step_trait", issue = "42168")]
367 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
368 impl const Step for $u_wider {
369 step_identical_methods!();
370 step_unsigned_methods!();
371
372 #[inline]
373 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
374 if *start <= *end {
375 if let Ok(steps) = usize::try_from(*end - *start) {
376 (steps, Some(steps))
377 } else {
378 (usize::MAX, None)
379 }
380 } else {
381 (0, None)
382 }
383 }
384
385 #[inline]
386 fn forward_checked(start: Self, n: usize) -> Option<Self> {
387 start.checked_add(n as Self)
388 }
389
390 #[inline]
391 fn backward_checked(start: Self, n: usize) -> Option<Self> {
392 start.checked_sub(n as Self)
393 }
394 }
395
396 #[allow(unreachable_patterns)]
397 #[unstable(feature = "step_trait", issue = "42168")]
398 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
399 impl const Step for $i_wider {
400 step_identical_methods!();
401 step_signed_methods!($u_wider);
402
403 #[inline]
404 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
405 if *start <= *end {
406 match end.checked_sub(*start) {
407 Some(result) => {
408 if let Ok(steps) = usize::try_from(result) {
409 (steps, Some(steps))
410 } else {
411 (usize::MAX, None)
412 }
413 }
414 None => (usize::MAX, None),
417 }
418 } else {
419 (0, None)
420 }
421 }
422
423 #[inline]
424 fn forward_checked(start: Self, n: usize) -> Option<Self> {
425 start.checked_add(n as Self)
426 }
427
428 #[inline]
429 fn backward_checked(start: Self, n: usize) -> Option<Self> {
430 start.checked_sub(n as Self)
431 }
432 }
433 )+
434 };
435}
436
437#[cfg(target_pointer_width = "64")]
438step_integer_impls! {
439 [ [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize] ] <= usize < [ [u128 i128] ]
440}
441
442#[cfg(target_pointer_width = "32")]
443step_integer_impls! {
444 [ [u8 i8], [u16 i16], [u32 i32], [usize isize] ] <= usize < [ [u64 i64], [u128 i128] ]
445}
446
447#[cfg(target_pointer_width = "16")]
448step_integer_impls! {
449 [ [u8 i8], [u16 i16], [usize isize] ] <= usize < [ [u32 i32], [u64 i64], [u128 i128] ]
450}
451
452macro_rules! step_nonzero_identical_methods {
454 ($int:ident) => {
455 #[inline]
456 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
457 unsafe { Self::new_unchecked(start.get().unchecked_add(n as $int)) }
459 }
460
461 #[inline]
462 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
463 unsafe { Self::new_unchecked(start.get().unchecked_sub(n as $int)) }
465 }
466
467 #[inline]
468 #[allow(arithmetic_overflow)]
469 #[rustc_inherit_overflow_checks]
470 fn forward(start: Self, n: usize) -> Self {
471 if Self::forward_checked(start, n).is_none() {
474 let _ = $int::MAX + 1;
475 }
476 start.saturating_add(n as $int)
478 }
479
480 #[inline]
481 #[allow(arithmetic_overflow)]
482 #[rustc_inherit_overflow_checks]
483 fn backward(start: Self, n: usize) -> Self {
484 if Self::backward_checked(start, n).is_none() {
487 let _ = $int::MIN - 1;
488 }
489 Self::new(start.get().saturating_sub(n as $int)).unwrap_or(Self::MIN)
491 }
492
493 #[inline]
494 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
495 if *start <= *end {
496 #[allow(irrefutable_let_patterns, reason = "happens on usize or narrower")]
497 if let Ok(steps) = usize::try_from(end.get() - start.get()) {
498 (steps, Some(steps))
499 } else {
500 (usize::MAX, None)
501 }
502 } else {
503 (0, None)
504 }
505 }
506 };
507}
508
509macro_rules! step_nonzero_impls {
510 {
511 [$( $narrower:ident ),+] <= usize < [$( $wider:ident ),+]
512 } => {
513 $(
514 #[allow(unreachable_patterns)]
515 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
516 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
517 impl const Step for NonZero<$narrower> {
518 step_nonzero_identical_methods!($narrower);
519
520 #[inline]
521 fn forward_checked(start: Self, n: usize) -> Option<Self> {
522 match $narrower::try_from(n) {
523 Ok(n) => start.checked_add(n),
524 Err(_) => None, }
526 }
527
528 #[inline]
529 fn backward_checked(start: Self, n: usize) -> Option<Self> {
530 match $narrower::try_from(n) {
531 Ok(n) => start.get().checked_sub(n).and_then(Self::new),
533 Err(_) => None, }
535 }
536 }
537 )+
538
539 $(
540 #[allow(unreachable_patterns)]
541 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
542 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
543 impl const Step for NonZero<$wider> {
544 step_nonzero_identical_methods!($wider);
545
546 #[inline]
547 fn forward_checked(start: Self, n: usize) -> Option<Self> {
548 start.checked_add(n as $wider)
549 }
550
551 #[inline]
552 fn backward_checked(start: Self, n: usize) -> Option<Self> {
553 start.get().checked_sub(n as $wider).and_then(Self::new)
554 }
555 }
556 )+
557 };
558}
559
560#[cfg(target_pointer_width = "64")]
561step_nonzero_impls! {
562 [u8, u16, u32, u64, usize] <= usize < [u128]
563}
564
565#[cfg(target_pointer_width = "32")]
566step_nonzero_impls! {
567 [u8, u16, u32, usize] <= usize < [u64, u128]
568}
569
570#[cfg(target_pointer_width = "16")]
571step_nonzero_impls! {
572 [u8, u16, usize] <= usize < [u32, u64, u128]
573}
574
575#[unstable(feature = "step_trait", issue = "42168")]
576#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
577impl const Step for char {
578 #[inline]
579 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
580 let start = start as u32;
581 let end = end as u32;
582 if start <= end {
583 let count = end - start;
584 if start < 0xD800 && 0xE000 <= end {
585 if let Ok(steps) = usize::try_from(count - 0x800) {
586 (steps, Some(steps))
587 } else {
588 (usize::MAX, None)
589 }
590 } else {
591 if let Ok(steps) = usize::try_from(count) {
592 (steps, Some(steps))
593 } else {
594 (usize::MAX, None)
595 }
596 }
597 } else {
598 (0, None)
599 }
600 }
601
602 #[inline]
603 fn forward_checked(start: char, count: usize) -> Option<char> {
604 let start = start as u32;
605 let mut res = Step::forward_checked(start, count)?;
606 if start < 0xD800 && 0xD800 <= res {
607 res = Step::forward_checked(res, 0x800)?;
608 }
609 if res <= char::MAX as u32 {
610 Some(unsafe { char::from_u32_unchecked(res) })
613 } else {
614 None
615 }
616 }
617
618 #[inline]
619 fn backward_checked(start: char, count: usize) -> Option<char> {
620 let start = start as u32;
621 let mut res = Step::backward_checked(start, count)?;
622 if start >= 0xE000 && 0xE000 > res {
623 res = Step::backward_checked(res, 0x800)?;
624 }
625 Some(unsafe { char::from_u32_unchecked(res) })
628 }
629
630 #[inline]
631 unsafe fn forward_unchecked(start: char, count: usize) -> char {
632 let start = start as u32;
633 let mut res = unsafe { Step::forward_unchecked(start, count) };
636 if start < 0xD800 && 0xD800 <= res {
637 res = unsafe { Step::forward_unchecked(res, 0x800) };
640 }
641 unsafe { char::from_u32_unchecked(res) }
644 }
645
646 #[inline]
647 unsafe fn backward_unchecked(start: char, count: usize) -> char {
648 let start = start as u32;
649 let mut res = unsafe { Step::backward_unchecked(start, count) };
652 if start >= 0xE000 && 0xE000 > res {
653 res = unsafe { Step::backward_unchecked(res, 0x800) };
656 }
657 unsafe { char::from_u32_unchecked(res) }
660 }
661}
662
663#[unstable(feature = "step_trait", issue = "42168")]
664#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
665impl const Step for AsciiChar {
666 #[inline]
667 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
668 Step::steps_between(&start.to_u8(), &end.to_u8())
669 }
670
671 #[inline]
672 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
673 let end = Step::forward_checked(start.to_u8(), count)?;
674 AsciiChar::from_u8(end)
675 }
676
677 #[inline]
678 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
679 let end = Step::backward_checked(start.to_u8(), count)?;
680
681 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
683 }
684
685 #[inline]
686 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
687 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
690
691 unsafe { AsciiChar::from_u8_unchecked(end) }
693 }
694
695 #[inline]
696 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
697 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
700
701 unsafe { AsciiChar::from_u8_unchecked(end) }
703 }
704}
705
706#[unstable(feature = "step_trait", issue = "42168")]
707#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
708impl const Step for Ipv4Addr {
709 #[inline]
710 fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
711 u32::steps_between(&start.to_bits(), &end.to_bits())
712 }
713
714 #[inline]
715 fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
716 u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
717 }
718
719 #[inline]
720 fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
721 u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
722 }
723
724 #[inline]
725 unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
726 Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
729 }
730
731 #[inline]
732 unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
733 Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
736 }
737}
738
739#[unstable(feature = "step_trait", issue = "42168")]
740#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
741impl const Step for Ipv6Addr {
742 #[inline]
743 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
744 u128::steps_between(&start.to_bits(), &end.to_bits())
745 }
746
747 #[inline]
748 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
749 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
750 }
751
752 #[inline]
753 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
754 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
755 }
756
757 #[inline]
758 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
759 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
762 }
763
764 #[inline]
765 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
766 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
769 }
770}
771
772macro_rules! range_exact_iter_impl {
773 ($($t:ty)*) => ($(
774 #[stable(feature = "rust1", since = "1.0.0")]
775 impl ExactSizeIterator for ops::Range<$t> { }
776 )*)
777}
778
779macro_rules! unsafe_range_trusted_random_access_impl {
782 ($($t:ty)*) => ($(
783 #[doc(hidden)]
784 #[unstable(feature = "trusted_random_access", issue = "none")]
785 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
786
787 #[doc(hidden)]
788 #[unstable(feature = "trusted_random_access", issue = "none")]
789 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
790 const MAY_HAVE_SIDE_EFFECT: bool = false;
791 }
792 )*)
793}
794
795macro_rules! range_incl_exact_iter_impl {
796 ($($t:ty)*) => ($(
797 #[stable(feature = "inclusive_range", since = "1.26.0")]
798 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
799 )*)
800}
801
802trait RangeIteratorImpl {
804 type Item;
805
806 fn spec_next(&mut self) -> Option<Self::Item>;
808 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
809 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
810
811 fn spec_next_back(&mut self) -> Option<Self::Item>;
813 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
814 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
815}
816
817impl<A: Step> RangeIteratorImpl for ops::Range<A> {
818 type Item = A;
819
820 #[inline]
821 default fn spec_next(&mut self) -> Option<A> {
822 if self.start < self.end {
823 let n =
824 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
825 Some(mem::replace(&mut self.start, n))
826 } else {
827 None
828 }
829 }
830
831 #[inline]
832 default fn spec_nth(&mut self, n: usize) -> Option<A> {
833 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
834 if plus_n < self.end {
835 self.start =
836 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
837 return Some(plus_n);
838 }
839 }
840
841 self.start = self.end.clone();
842 None
843 }
844
845 #[inline]
846 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
847 let steps = Step::steps_between(&self.start, &self.end);
848 let available = steps.1.unwrap_or(steps.0);
849
850 let taken = available.min(n);
851
852 self.start =
853 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
854
855 NonZero::new(n - taken).map_or(Ok(()), Err)
856 }
857
858 #[inline]
859 default fn spec_next_back(&mut self) -> Option<A> {
860 if self.start < self.end {
861 self.end =
862 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
863 Some(self.end.clone())
864 } else {
865 None
866 }
867 }
868
869 #[inline]
870 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
871 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
872 if minus_n > self.start {
873 self.end =
874 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
875 return Some(self.end.clone());
876 }
877 }
878
879 self.end = self.start.clone();
880 None
881 }
882
883 #[inline]
884 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
885 let steps = Step::steps_between(&self.start, &self.end);
886 let available = steps.1.unwrap_or(steps.0);
887
888 let taken = available.min(n);
889
890 self.end =
891 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
892
893 NonZero::new(n - taken).map_or(Ok(()), Err)
894 }
895}
896
897impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
898 #[inline]
899 fn spec_next(&mut self) -> Option<T> {
900 if self.start < self.end {
901 let old = self.start;
902 self.start = unsafe { Step::forward_unchecked(old, 1) };
904 Some(old)
905 } else {
906 None
907 }
908 }
909
910 #[inline]
911 fn spec_nth(&mut self, n: usize) -> Option<T> {
912 if let Some(plus_n) = Step::forward_checked(self.start, n) {
913 if plus_n < self.end {
914 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
916 return Some(plus_n);
917 }
918 }
919
920 self.start = self.end;
921 None
922 }
923
924 #[inline]
925 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
926 let steps = Step::steps_between(&self.start, &self.end);
927 let available = steps.1.unwrap_or(steps.0);
928
929 let taken = available.min(n);
930
931 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
936
937 NonZero::new(n - taken).map_or(Ok(()), Err)
938 }
939
940 #[inline]
941 fn spec_next_back(&mut self) -> Option<T> {
942 if self.start < self.end {
943 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
945 Some(self.end)
946 } else {
947 None
948 }
949 }
950
951 #[inline]
952 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
953 if let Some(minus_n) = Step::backward_checked(self.end, n) {
954 if minus_n > self.start {
955 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
957 return Some(self.end);
958 }
959 }
960
961 self.end = self.start;
962 None
963 }
964
965 #[inline]
966 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
967 let steps = Step::steps_between(&self.start, &self.end);
968 let available = steps.1.unwrap_or(steps.0);
969
970 let taken = available.min(n);
971
972 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
974
975 NonZero::new(n - taken).map_or(Ok(()), Err)
976 }
977}
978
979#[stable(feature = "rust1", since = "1.0.0")]
980impl<A: Step> Iterator for ops::Range<A> {
981 type Item = A;
982
983 #[inline]
984 fn next(&mut self) -> Option<A> {
985 self.spec_next()
986 }
987
988 #[inline]
989 fn size_hint(&self) -> (usize, Option<usize>) {
990 if self.start < self.end {
991 Step::steps_between(&self.start, &self.end)
992 } else {
993 (0, Some(0))
994 }
995 }
996
997 #[inline]
998 fn count(self) -> usize {
999 if self.start < self.end {
1000 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
1001 } else {
1002 0
1003 }
1004 }
1005
1006 #[inline]
1007 fn nth(&mut self, n: usize) -> Option<A> {
1008 self.spec_nth(n)
1009 }
1010
1011 #[inline]
1012 fn last(mut self) -> Option<A> {
1013 self.next_back()
1014 }
1015
1016 #[inline]
1017 fn min(mut self) -> Option<A>
1018 where
1019 A: Ord,
1020 {
1021 self.next()
1022 }
1023
1024 #[inline]
1025 fn max(mut self) -> Option<A>
1026 where
1027 A: Ord,
1028 {
1029 self.next_back()
1030 }
1031
1032 #[inline]
1033 fn is_sorted(self) -> bool {
1034 true
1035 }
1036
1037 #[inline]
1038 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1039 self.spec_advance_by(n)
1040 }
1041
1042 #[inline]
1043 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
1044 where
1045 Self: TrustedRandomAccessNoCoerce,
1046 {
1047 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
1052 }
1053}
1054
1055range_exact_iter_impl! {
1064 usize u8 u16
1065 isize i8 i16
1066 NonZero<usize> NonZero<u8> NonZero<u16>
1067
1068 u32
1073 i32
1074}
1075
1076unsafe_range_trusted_random_access_impl! {
1077 usize u8 u16
1078 isize i8 i16
1079 NonZero<usize> NonZero<u8> NonZero<u16>
1080}
1081
1082#[cfg(target_pointer_width = "32")]
1083unsafe_range_trusted_random_access_impl! {
1084 u32 i32
1085 NonZero<u32>
1086}
1087
1088#[cfg(target_pointer_width = "64")]
1089unsafe_range_trusted_random_access_impl! {
1090 u32 i32
1091 u64 i64
1092 NonZero<u32>
1093 NonZero<u64>
1094}
1095
1096range_incl_exact_iter_impl! {
1097 u8
1098 i8
1099 NonZero<u8>
1100 NonZero<u16> NonZero<usize>
1103
1104 u16
1109 i16
1110}
1111
1112#[stable(feature = "rust1", since = "1.0.0")]
1113impl<A: Step> DoubleEndedIterator for ops::Range<A> {
1114 #[inline]
1115 fn next_back(&mut self) -> Option<A> {
1116 self.spec_next_back()
1117 }
1118
1119 #[inline]
1120 fn nth_back(&mut self, n: usize) -> Option<A> {
1121 self.spec_nth_back(n)
1122 }
1123
1124 #[inline]
1125 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1126 self.spec_advance_back_by(n)
1127 }
1128}
1129
1130#[unstable(feature = "trusted_len", issue = "37572")]
1150unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1151
1152#[stable(feature = "fused", since = "1.26.0")]
1153impl<A: Step> FusedIterator for ops::Range<A> {}
1154
1155#[stable(feature = "rust1", since = "1.0.0")]
1156impl<A: Step> Iterator for ops::RangeFrom<A> {
1157 type Item = A;
1158
1159 #[inline]
1160 fn next(&mut self) -> Option<A> {
1161 let n = Step::forward(self.start.clone(), 1);
1162 Some(mem::replace(&mut self.start, n))
1163 }
1164
1165 #[inline]
1166 fn size_hint(&self) -> (usize, Option<usize>) {
1167 (usize::MAX, None)
1168 }
1169
1170 #[inline]
1171 fn nth(&mut self, n: usize) -> Option<A> {
1172 let plus_n = Step::forward(self.start.clone(), n);
1173 self.start = Step::forward(plus_n.clone(), 1);
1174 Some(plus_n)
1175 }
1176}
1177
1178#[unstable(feature = "trusted_len", issue = "37572")]
1180unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1181
1182#[stable(feature = "fused", since = "1.26.0")]
1183impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1184
1185trait RangeInclusiveIteratorImpl {
1186 type Item;
1187
1188 fn spec_next(&mut self) -> Option<Self::Item>;
1190 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1191 where
1192 Self: Sized,
1193 F: FnMut(B, Self::Item) -> R,
1194 R: Try<Output = B>;
1195
1196 fn spec_next_back(&mut self) -> Option<Self::Item>;
1198 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1199 where
1200 Self: Sized,
1201 F: FnMut(B, Self::Item) -> R,
1202 R: Try<Output = B>;
1203}
1204
1205impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1206 type Item = A;
1207
1208 #[inline]
1209 default fn spec_next(&mut self) -> Option<A> {
1210 if self.is_empty() {
1211 return None;
1212 }
1213 let is_iterating = self.start < self.end;
1214 Some(if is_iterating {
1215 let n =
1216 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1217 mem::replace(&mut self.start, n)
1218 } else {
1219 self.exhausted = true;
1220 self.start.clone()
1221 })
1222 }
1223
1224 #[inline]
1225 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1226 where
1227 Self: Sized,
1228 F: FnMut(B, A) -> R,
1229 R: Try<Output = B>,
1230 {
1231 if self.is_empty() {
1232 return try { init };
1233 }
1234
1235 let mut accum = init;
1236
1237 while self.start < self.end {
1238 let n =
1239 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1240 let n = mem::replace(&mut self.start, n);
1241 accum = f(accum, n)?;
1242 }
1243
1244 self.exhausted = true;
1245
1246 if self.start == self.end {
1247 accum = f(accum, self.start.clone())?;
1248 }
1249
1250 try { accum }
1251 }
1252
1253 #[inline]
1254 default fn spec_next_back(&mut self) -> Option<A> {
1255 if self.is_empty() {
1256 return None;
1257 }
1258 let is_iterating = self.start < self.end;
1259 Some(if is_iterating {
1260 let n =
1261 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1262 mem::replace(&mut self.end, n)
1263 } else {
1264 self.exhausted = true;
1265 self.end.clone()
1266 })
1267 }
1268
1269 #[inline]
1270 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1271 where
1272 Self: Sized,
1273 F: FnMut(B, A) -> R,
1274 R: Try<Output = B>,
1275 {
1276 if self.is_empty() {
1277 return try { init };
1278 }
1279
1280 let mut accum = init;
1281
1282 while self.start < self.end {
1283 let n =
1284 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1285 let n = mem::replace(&mut self.end, n);
1286 accum = f(accum, n)?;
1287 }
1288
1289 self.exhausted = true;
1290
1291 if self.start == self.end {
1292 accum = f(accum, self.start.clone())?;
1293 }
1294
1295 try { accum }
1296 }
1297}
1298
1299impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1300 #[inline]
1301 fn spec_next(&mut self) -> Option<T> {
1302 if self.is_empty() {
1303 return None;
1304 }
1305 let is_iterating = self.start < self.end;
1306 Some(if is_iterating {
1307 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1309 mem::replace(&mut self.start, n)
1310 } else {
1311 self.exhausted = true;
1312 self.start
1313 })
1314 }
1315
1316 #[inline]
1317 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1318 where
1319 Self: Sized,
1320 F: FnMut(B, T) -> R,
1321 R: Try<Output = B>,
1322 {
1323 if self.is_empty() {
1324 return try { init };
1325 }
1326
1327 let mut accum = init;
1328
1329 while self.start < self.end {
1330 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1332 let n = mem::replace(&mut self.start, n);
1333 accum = f(accum, n)?;
1334 }
1335
1336 self.exhausted = true;
1337
1338 if self.start == self.end {
1339 accum = f(accum, self.start)?;
1340 }
1341
1342 try { accum }
1343 }
1344
1345 #[inline]
1346 fn spec_next_back(&mut self) -> Option<T> {
1347 if self.is_empty() {
1348 return None;
1349 }
1350 let is_iterating = self.start < self.end;
1351 Some(if is_iterating {
1352 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1354 mem::replace(&mut self.end, n)
1355 } else {
1356 self.exhausted = true;
1357 self.end
1358 })
1359 }
1360
1361 #[inline]
1362 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1363 where
1364 Self: Sized,
1365 F: FnMut(B, T) -> R,
1366 R: Try<Output = B>,
1367 {
1368 if self.is_empty() {
1369 return try { init };
1370 }
1371
1372 let mut accum = init;
1373
1374 while self.start < self.end {
1375 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1377 let n = mem::replace(&mut self.end, n);
1378 accum = f(accum, n)?;
1379 }
1380
1381 self.exhausted = true;
1382
1383 if self.start == self.end {
1384 accum = f(accum, self.start)?;
1385 }
1386
1387 try { accum }
1388 }
1389}
1390
1391#[stable(feature = "inclusive_range", since = "1.26.0")]
1392impl<A: Step> Iterator for ops::RangeInclusive<A> {
1393 type Item = A;
1394
1395 #[inline]
1396 fn next(&mut self) -> Option<A> {
1397 self.spec_next()
1398 }
1399
1400 #[inline]
1401 fn size_hint(&self) -> (usize, Option<usize>) {
1402 if self.is_empty() {
1403 return (0, Some(0));
1404 }
1405
1406 let hint = Step::steps_between(&self.start, &self.end);
1407 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1408 }
1409
1410 #[inline]
1411 fn count(self) -> usize {
1412 if self.is_empty() {
1413 return 0;
1414 }
1415
1416 Step::steps_between(&self.start, &self.end)
1417 .1
1418 .and_then(|steps| steps.checked_add(1))
1419 .expect("count overflowed usize")
1420 }
1421
1422 #[inline]
1423 fn nth(&mut self, n: usize) -> Option<A> {
1424 if self.is_empty() {
1425 return None;
1426 }
1427
1428 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1429 use crate::cmp::Ordering::*;
1430
1431 match plus_n.partial_cmp(&self.end) {
1432 Some(Less) => {
1433 self.start = Step::forward(plus_n.clone(), 1);
1434 return Some(plus_n);
1435 }
1436 Some(Equal) => {
1437 self.start = plus_n.clone();
1438 self.exhausted = true;
1439 return Some(plus_n);
1440 }
1441 _ => {}
1442 }
1443 }
1444
1445 self.start = self.end.clone();
1446 self.exhausted = true;
1447 None
1448 }
1449
1450 #[inline]
1451 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1452 where
1453 Self: Sized,
1454 F: FnMut(B, Self::Item) -> R,
1455 R: Try<Output = B>,
1456 {
1457 self.spec_try_fold(init, f)
1458 }
1459
1460 impl_fold_via_try_fold! { fold -> try_fold }
1461
1462 #[inline]
1463 fn last(mut self) -> Option<A> {
1464 self.next_back()
1465 }
1466
1467 #[inline]
1468 fn min(mut self) -> Option<A>
1469 where
1470 A: Ord,
1471 {
1472 self.next()
1473 }
1474
1475 #[inline]
1476 fn max(mut self) -> Option<A>
1477 where
1478 A: Ord,
1479 {
1480 self.next_back()
1481 }
1482
1483 #[inline]
1484 fn is_sorted(self) -> bool {
1485 true
1486 }
1487}
1488
1489#[stable(feature = "inclusive_range", since = "1.26.0")]
1490impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1491 #[inline]
1492 fn next_back(&mut self) -> Option<A> {
1493 self.spec_next_back()
1494 }
1495
1496 #[inline]
1497 fn nth_back(&mut self, n: usize) -> Option<A> {
1498 if self.is_empty() {
1499 return None;
1500 }
1501
1502 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1503 use crate::cmp::Ordering::*;
1504
1505 match minus_n.partial_cmp(&self.start) {
1506 Some(Greater) => {
1507 self.end = Step::backward(minus_n.clone(), 1);
1508 return Some(minus_n);
1509 }
1510 Some(Equal) => {
1511 self.end = minus_n.clone();
1512 self.exhausted = true;
1513 return Some(minus_n);
1514 }
1515 _ => {}
1516 }
1517 }
1518
1519 self.end = self.start.clone();
1520 self.exhausted = true;
1521 None
1522 }
1523
1524 #[inline]
1525 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1526 where
1527 Self: Sized,
1528 F: FnMut(B, Self::Item) -> R,
1529 R: Try<Output = B>,
1530 {
1531 self.spec_try_rfold(init, f)
1532 }
1533
1534 impl_fold_via_try_fold! { rfold -> try_rfold }
1535}
1536
1537#[unstable(feature = "trusted_len", issue = "37572")]
1539unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1540
1541#[stable(feature = "fused", since = "1.26.0")]
1542impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}