1use super::{
2 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
3};
4use crate::ascii::Char as AsciiChar;
5use crate::marker::Destruct;
6use crate::mem;
7use crate::net::{Ipv4Addr, Ipv6Addr};
8use crate::num::NonZero;
9use crate::ops::{self, Try};
10
11macro_rules! unsafe_impl_trusted_step {
13 ($($type:ty)*) => {$(
14 #[unstable(feature = "trusted_step", issue = "85731")]
15 unsafe impl TrustedStep for $type {}
16 )*};
17}
18unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];
19unsafe_impl_trusted_step![NonZero<u8> NonZero<u16> NonZero<u32> NonZero<u64> NonZero<u128> NonZero<usize>];
20
21#[rustc_diagnostic_item = "range_step"]
26#[diagnostic::on_unimplemented(
27 message = "`std::ops::Range<{Self}>` is not an iterator",
28 label = "`Range<{Self}>` is not an iterator",
29 note = "`Range` only implements `Iterator` for select types in the standard library, \
30 particularly integers; to see the full list of types, see the documentation for the \
31 unstable `Step` trait"
32)]
33#[unstable(feature = "step_trait", issue = "42168")]
34#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
35pub const trait Step: [const] Clone + [const] PartialOrd + Sized {
36 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
51
52 fn forward_checked(start: Self, count: usize) -> Option<Self>;
69
70 fn forward_overflowing(start: Self, count: usize) -> (Self, bool);
94
95 fn forward(start: Self, count: usize) -> Self {
119 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
120 }
121
122 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
144 Step::forward(start, count)
145 }
146
147 fn backward_checked(start: Self, count: usize) -> Option<Self>;
164
165 fn backward_overflowing(start: Self, count: usize) -> (Self, bool);
189
190 fn backward(start: Self, count: usize) -> Self {
214 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
215 }
216
217 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
239 Step::backward(start, count)
240 }
241}
242
243macro_rules! step_signed_methods {
246 ($unsigned: ty) => {
247 #[inline]
248 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
249 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
251 }
252
253 #[inline]
254 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
255 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
257 }
258 };
259}
260
261macro_rules! step_unsigned_methods {
262 () => {
263 #[inline]
264 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
265 unsafe { start.unchecked_add(n as Self) }
267 }
268
269 #[inline]
270 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
271 unsafe { start.unchecked_sub(n as Self) }
273 }
274 };
275}
276
277macro_rules! step_identical_methods {
279 () => {
280 #[inline]
281 #[allow(arithmetic_overflow)]
282 #[rustc_inherit_overflow_checks]
283 fn forward(start: Self, n: usize) -> Self {
284 if Self::forward_checked(start, n).is_none() {
287 let _ = Self::MAX + 1;
288 }
289 start.wrapping_add(n as Self)
291 }
292
293 #[inline]
294 #[allow(arithmetic_overflow)]
295 #[rustc_inherit_overflow_checks]
296 fn backward(start: Self, n: usize) -> Self {
297 if Self::backward_checked(start, n).is_none() {
300 let _ = Self::MIN - 1;
301 }
302 start.wrapping_sub(n as Self)
304 }
305 };
306}
307
308macro_rules! step_integer_impls {
309 {
310 [ $( [ $u_narrower:ident $i_narrower:ident ] ),+ ] <= usize <
311 [ $( [ $u_wider:ident $i_wider:ident ] ),+ ]
312 } => {
313 $(
314 #[allow(unreachable_patterns)]
315 #[unstable(feature = "step_trait", issue = "42168")]
316 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
317 const impl Step for $u_narrower {
318 step_identical_methods!();
319 step_unsigned_methods!();
320
321 #[inline]
322 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
323 if *start <= *end {
324 let steps = (*end - *start) as usize;
326 (steps, Some(steps))
327 } else {
328 (0, None)
329 }
330 }
331
332 #[inline]
333 fn forward_checked(start: Self, n: usize) -> Option<Self> {
334 match Self::try_from(n) {
335 Ok(n) => start.checked_add(n),
336 Err(_) => None, }
338 }
339
340 #[inline]
341 fn backward_checked(start: Self, n: usize) -> Option<Self> {
342 match Self::try_from(n) {
343 Ok(n) => start.checked_sub(n),
344 Err(_) => None, }
346 }
347
348 #[inline]
349 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
350 match Self::try_from(n) {
351 Ok(n) => start.overflowing_add(n),
352 Err(_) => (start.wrapping_add(n as Self), true),
354 }
355 }
356
357 #[inline]
358 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
359 match Self::try_from(n) {
360 Ok(n) => start.overflowing_sub(n),
361 Err(_) => (start.wrapping_sub(n as Self), true),
363 }
364 }
365 }
366
367 #[allow(unreachable_patterns)]
368 #[unstable(feature = "step_trait", issue = "42168")]
369 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
370 const impl Step for $i_narrower {
371 step_identical_methods!();
372 step_signed_methods!($u_narrower);
373
374 #[inline]
375 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
376 if *start <= *end {
377 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
383 (steps, Some(steps))
384 } else {
385 (0, None)
386 }
387 }
388
389 #[inline]
390 fn forward_checked(start: Self, n: usize) -> Option<Self> {
391 match $u_narrower::try_from(n) {
392 Ok(n) => {
393 let wrapped = start.wrapping_add(n as Self);
397 if wrapped >= start {
398 Some(wrapped)
399 } else {
400 None }
402 }
403 Err(_) => None,
407 }
408 }
409
410 #[inline]
411 fn backward_checked(start: Self, n: usize) -> Option<Self> {
412 match $u_narrower::try_from(n) {
413 Ok(n) => {
414 let wrapped = start.wrapping_sub(n as Self);
418 if wrapped <= start {
419 Some(wrapped)
420 } else {
421 None }
423 }
424 Err(_) => None,
428 }
429 }
430
431 #[inline]
432 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
433 match $u_narrower::try_from(n) {
434 Ok(n) => start.overflowing_add_unsigned(n),
435 Err(_) => (start.wrapping_add_unsigned(n as $u_narrower), true),
439 }
440 }
441
442 #[inline]
443 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
444 match $u_narrower::try_from(n) {
445 Ok(n) => start.overflowing_sub_unsigned(n),
446 Err(_) => (start.wrapping_sub_unsigned(n as $u_narrower), true),
450 }
451 }
452 }
453 )+
454
455 $(
456 #[allow(unreachable_patterns)]
457 #[unstable(feature = "step_trait", issue = "42168")]
458 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
459 const impl Step for $u_wider {
460 step_identical_methods!();
461 step_unsigned_methods!();
462
463 #[inline]
464 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
465 if *start <= *end {
466 if let Ok(steps) = usize::try_from(*end - *start) {
467 (steps, Some(steps))
468 } else {
469 (usize::MAX, None)
470 }
471 } else {
472 (0, None)
473 }
474 }
475
476 #[inline]
477 fn forward_checked(start: Self, n: usize) -> Option<Self> {
478 start.checked_add(n as Self)
479 }
480
481 #[inline]
482 fn backward_checked(start: Self, n: usize) -> Option<Self> {
483 start.checked_sub(n as Self)
484 }
485
486 #[inline]
487 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
488 start.overflowing_add(n as Self)
489 }
490
491 #[inline]
492 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
493 start.overflowing_sub(n as Self)
494 }
495 }
496
497 #[allow(unreachable_patterns)]
498 #[unstable(feature = "step_trait", issue = "42168")]
499 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
500 const impl Step for $i_wider {
501 step_identical_methods!();
502 step_signed_methods!($u_wider);
503
504 #[inline]
505 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
506 if *start <= *end {
507 match end.checked_sub(*start) {
508 Some(result) => {
509 if let Ok(steps) = usize::try_from(result) {
510 (steps, Some(steps))
511 } else {
512 (usize::MAX, None)
513 }
514 }
515 None => (usize::MAX, None),
518 }
519 } else {
520 (0, None)
521 }
522 }
523
524 #[inline]
525 fn forward_checked(start: Self, n: usize) -> Option<Self> {
526 start.checked_add(n as Self)
527 }
528
529 #[inline]
530 fn backward_checked(start: Self, n: usize) -> Option<Self> {
531 start.checked_sub(n as Self)
532 }
533
534 #[inline]
535 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
536 start.overflowing_add_unsigned(n as $u_wider)
537 }
538
539 #[inline]
540 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
541 start.overflowing_sub_unsigned(n as $u_wider)
542 }
543 }
544 )+
545 };
546}
547
548#[cfg(target_pointer_width = "64")]
549step_integer_impls! {
550 [ [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize] ] <= usize < [ [u128 i128] ]
551}
552
553#[cfg(target_pointer_width = "32")]
554step_integer_impls! {
555 [ [u8 i8], [u16 i16], [u32 i32], [usize isize] ] <= usize < [ [u64 i64], [u128 i128] ]
556}
557
558#[cfg(target_pointer_width = "16")]
559step_integer_impls! {
560 [ [u8 i8], [u16 i16], [usize isize] ] <= usize < [ [u32 i32], [u64 i64], [u128 i128] ]
561}
562
563macro_rules! step_nonzero_identical_methods {
565 ($int:ident) => {
566 #[inline]
567 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
568 unsafe { Self::new_unchecked(start.get().unchecked_add(n as $int)) }
570 }
571
572 #[inline]
573 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
574 unsafe { Self::new_unchecked(start.get().unchecked_sub(n as $int)) }
576 }
577
578 #[inline]
579 #[allow(arithmetic_overflow)]
580 #[rustc_inherit_overflow_checks]
581 fn forward(start: Self, n: usize) -> Self {
582 if Self::forward_checked(start, n).is_none() {
585 let _ = $int::MAX + 1;
586 }
587 start.saturating_add(n as $int)
589 }
590
591 #[inline]
592 #[allow(arithmetic_overflow)]
593 #[rustc_inherit_overflow_checks]
594 fn backward(start: Self, n: usize) -> Self {
595 if Self::backward_checked(start, n).is_none() {
598 let _ = $int::MIN - 1;
599 }
600 Self::new(start.get().saturating_sub(n as $int)).unwrap_or(Self::MIN)
602 }
603
604 #[inline]
610 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
611 if let Some(s) = Step::forward_checked(start, n) {
613 (s, false)
614 } else {
615 (Self::MAX, true)
616 }
617 }
618
619 #[inline]
620 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
621 if let Some(s) = Step::backward_checked(start, n) {
623 (s, false)
624 } else {
625 (Self::MIN, true)
626 }
627 }
628
629 #[inline]
630 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
631 if *start <= *end {
632 #[allow(irrefutable_let_patterns, reason = "happens on usize or narrower")]
633 if let Ok(steps) = usize::try_from(end.get() - start.get()) {
634 (steps, Some(steps))
635 } else {
636 (usize::MAX, None)
637 }
638 } else {
639 (0, None)
640 }
641 }
642 };
643}
644
645macro_rules! step_nonzero_impls {
646 {
647 [$( $narrower:ident ),+] <= usize < [$( $wider:ident ),+]
648 } => {
649 $(
650 #[allow(unreachable_patterns)]
651 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
652 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
653 const impl Step for NonZero<$narrower> {
654 step_nonzero_identical_methods!($narrower);
655
656 #[inline]
657 fn forward_checked(start: Self, n: usize) -> Option<Self> {
658 match $narrower::try_from(n) {
659 Ok(n) => start.checked_add(n),
660 Err(_) => None, }
662 }
663
664 #[inline]
665 fn backward_checked(start: Self, n: usize) -> Option<Self> {
666 match $narrower::try_from(n) {
667 Ok(n) => start.get().checked_sub(n).and_then(Self::new),
669 Err(_) => None, }
671 }
672 }
673 )+
674
675 $(
676 #[allow(unreachable_patterns)]
677 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
678 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
679 const impl Step for NonZero<$wider> {
680 step_nonzero_identical_methods!($wider);
681
682 #[inline]
683 fn forward_checked(start: Self, n: usize) -> Option<Self> {
684 start.checked_add(n as $wider)
685 }
686
687 #[inline]
688 fn backward_checked(start: Self, n: usize) -> Option<Self> {
689 start.get().checked_sub(n as $wider).and_then(Self::new)
690 }
691 }
692 )+
693 };
694}
695
696#[cfg(target_pointer_width = "64")]
697step_nonzero_impls! {
698 [u8, u16, u32, u64, usize] <= usize < [u128]
699}
700
701#[cfg(target_pointer_width = "32")]
702step_nonzero_impls! {
703 [u8, u16, u32, usize] <= usize < [u64, u128]
704}
705
706#[cfg(target_pointer_width = "16")]
707step_nonzero_impls! {
708 [u8, u16, usize] <= usize < [u32, u64, u128]
709}
710
711#[unstable(feature = "step_trait", issue = "42168")]
712#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
713const impl Step for char {
714 #[inline]
715 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
716 let start = start as u32;
717 let end = end as u32;
718 if start <= end {
719 let count = end - start;
720 if start < 0xD800 && 0xE000 <= end {
721 if let Ok(steps) = usize::try_from(count - 0x800) {
722 (steps, Some(steps))
723 } else {
724 (usize::MAX, None)
725 }
726 } else {
727 if let Ok(steps) = usize::try_from(count) {
728 (steps, Some(steps))
729 } else {
730 (usize::MAX, None)
731 }
732 }
733 } else {
734 (0, None)
735 }
736 }
737
738 #[inline]
739 fn forward_checked(start: char, count: usize) -> Option<char> {
740 let start = start as u32;
741 let mut res = Step::forward_checked(start, count)?;
742 if start < 0xD800 && 0xD800 <= res {
743 res = Step::forward_checked(res, 0x800)?;
744 }
745 if res <= char::MAX as u32 {
746 Some(unsafe { char::from_u32_unchecked(res) })
749 } else {
750 None
751 }
752 }
753
754 #[inline]
755 fn backward_checked(start: char, count: usize) -> Option<char> {
756 let start = start as u32;
757 let mut res = Step::backward_checked(start, count)?;
758 if start >= 0xE000 && 0xE000 > res {
759 res = Step::backward_checked(res, 0x800)?;
760 }
761 Some(unsafe { char::from_u32_unchecked(res) })
764 }
765
766 #[inline]
772 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
773 if let Some(c) = Step::forward_checked(start, count) {
774 (c, false)
775 } else {
776 (Self::MAX, true)
777 }
778 }
779
780 #[inline]
781 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
782 if let Some(c) = Step::backward_checked(start, count) {
783 (c, false)
784 } else {
785 (Self::MIN, true)
786 }
787 }
788
789 #[inline]
790 unsafe fn forward_unchecked(start: char, count: usize) -> char {
791 let start = start as u32;
792 let mut res = unsafe { Step::forward_unchecked(start, count) };
795 if start < 0xD800 && 0xD800 <= res {
796 res = unsafe { Step::forward_unchecked(res, 0x800) };
799 }
800 unsafe { char::from_u32_unchecked(res) }
803 }
804
805 #[inline]
806 unsafe fn backward_unchecked(start: char, count: usize) -> char {
807 let start = start as u32;
808 let mut res = unsafe { Step::backward_unchecked(start, count) };
811 if start >= 0xE000 && 0xE000 > res {
812 res = unsafe { Step::backward_unchecked(res, 0x800) };
815 }
816 unsafe { char::from_u32_unchecked(res) }
819 }
820}
821
822#[unstable(feature = "step_trait", issue = "42168")]
823#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
824const impl Step for AsciiChar {
825 #[inline]
826 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
827 Step::steps_between(&start.to_u8(), &end.to_u8())
828 }
829
830 #[inline]
831 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
832 let end = Step::forward_checked(start.to_u8(), count)?;
833 AsciiChar::from_u8(end)
834 }
835
836 #[inline]
837 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
838 let end = Step::backward_checked(start.to_u8(), count)?;
839
840 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
842 }
843
844 #[inline]
845 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
846 let (s, o) = (start as usize).overflowing_add(count);
847 let ret = s & (AsciiChar::MAX as usize);
848
849 (unsafe { AsciiChar::from_u8_unchecked(ret as u8) }, o || ret < s)
851 }
852
853 #[inline]
854 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
855 let (s, o) = (start as usize).overflowing_sub(count);
856 let ret = s & (AsciiChar::MAX as usize);
857
858 (unsafe { AsciiChar::from_u8_unchecked(ret as u8) }, o || ret < s)
860 }
861
862 #[inline]
863 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
864 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
867
868 unsafe { AsciiChar::from_u8_unchecked(end) }
870 }
871
872 #[inline]
873 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
874 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
877
878 unsafe { AsciiChar::from_u8_unchecked(end) }
880 }
881}
882
883#[unstable(feature = "step_trait", issue = "42168")]
884#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
885const impl Step for Ipv4Addr {
886 #[inline]
887 fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
888 u32::steps_between(&start.to_bits(), &end.to_bits())
889 }
890
891 #[inline]
892 fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
893 u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
894 }
895
896 #[inline]
897 fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
898 u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
899 }
900
901 #[inline]
902 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
903 let (s, o) = u32::forward_overflowing(start.to_bits(), count);
904 (Ipv4Addr::from_bits(s), o)
905 }
906
907 #[inline]
908 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
909 let (s, o) = u32::backward_overflowing(start.to_bits(), count);
910 (Ipv4Addr::from_bits(s), o)
911 }
912
913 #[inline]
914 unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
915 Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
918 }
919
920 #[inline]
921 unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
922 Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
925 }
926}
927
928#[unstable(feature = "step_trait", issue = "42168")]
929#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
930const impl Step for Ipv6Addr {
931 #[inline]
932 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
933 u128::steps_between(&start.to_bits(), &end.to_bits())
934 }
935
936 #[inline]
937 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
938 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
939 }
940
941 #[inline]
942 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
943 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
944 }
945
946 #[inline]
947 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
948 let (s, o) = u128::forward_overflowing(start.to_bits(), count);
949 (Ipv6Addr::from_bits(s), o)
950 }
951
952 #[inline]
953 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
954 let (s, o) = u128::backward_overflowing(start.to_bits(), count);
955 (Ipv6Addr::from_bits(s), o)
956 }
957
958 #[inline]
959 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
960 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
963 }
964
965 #[inline]
966 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
967 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
970 }
971}
972
973macro_rules! range_exact_iter_impl {
974 ($($t:ty)*) => ($(
975 #[stable(feature = "rust1", since = "1.0.0")]
976 impl ExactSizeIterator for ops::Range<$t> { }
977 )*)
978}
979
980macro_rules! unsafe_range_trusted_random_access_impl {
983 ($($t:ty)*) => ($(
984 #[doc(hidden)]
985 #[unstable(feature = "trusted_random_access", issue = "none")]
986 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
987
988 #[doc(hidden)]
989 #[unstable(feature = "trusted_random_access", issue = "none")]
990 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
991 const MAY_HAVE_SIDE_EFFECT: bool = false;
992 }
993 )*)
994}
995
996macro_rules! range_incl_exact_iter_impl {
997 ($($t:ty)*) => ($(
998 #[stable(feature = "inclusive_range", since = "1.26.0")]
999 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
1000 )*)
1001}
1002
1003const trait RangeIteratorImpl {
1005 type Item;
1006
1007 fn spec_next(&mut self) -> Option<Self::Item>;
1009 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
1010 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
1011
1012 fn spec_next_back(&mut self) -> Option<Self::Item>;
1014 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
1015 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
1016}
1017
1018#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1019const impl<A: [const] Step + [const] Destruct> RangeIteratorImpl for ops::Range<A> {
1020 type Item = A;
1021
1022 #[inline]
1023 default fn spec_next(&mut self) -> Option<A> {
1024 if self.start < self.end {
1025 let n =
1026 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1027 Some(mem::replace(&mut self.start, n))
1028 } else {
1029 None
1030 }
1031 }
1032
1033 #[inline]
1034 default fn spec_nth(&mut self, n: usize) -> Option<A> {
1035 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1036 if plus_n < self.end {
1037 self.start =
1038 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
1039 return Some(plus_n);
1040 }
1041 }
1042
1043 self.start = self.end.clone();
1044 None
1045 }
1046
1047 #[inline]
1048 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1049 let steps = Step::steps_between(&self.start, &self.end);
1050 let available = steps.1.unwrap_or(steps.0);
1051
1052 let taken = available.min(n);
1053
1054 self.start =
1055 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
1056
1057 NonZero::new(n - taken).map_or(Ok(()), Err)
1058 }
1059
1060 #[inline]
1061 default fn spec_next_back(&mut self) -> Option<A> {
1062 if self.start < self.end {
1063 self.end =
1064 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1065 Some(self.end.clone())
1066 } else {
1067 None
1068 }
1069 }
1070
1071 #[inline]
1072 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
1073 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1074 if minus_n > self.start {
1075 self.end =
1076 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
1077 return Some(self.end.clone());
1078 }
1079 }
1080
1081 self.end = self.start.clone();
1082 None
1083 }
1084
1085 #[inline]
1086 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1087 let steps = Step::steps_between(&self.start, &self.end);
1088 let available = steps.1.unwrap_or(steps.0);
1089
1090 let taken = available.min(n);
1091
1092 self.end =
1093 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
1094
1095 NonZero::new(n - taken).map_or(Ok(()), Err)
1096 }
1097}
1098
1099#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1100const impl<T: [const] TrustedStep + [const] Destruct> RangeIteratorImpl for ops::Range<T> {
1101 #[inline]
1102 fn spec_next(&mut self) -> Option<T> {
1103 if self.start < self.end {
1104 let old = self.start;
1105 self.start = unsafe { Step::forward_unchecked(old, 1) };
1107 Some(old)
1108 } else {
1109 None
1110 }
1111 }
1112
1113 #[inline]
1114 fn spec_nth(&mut self, n: usize) -> Option<T> {
1115 if let Some(plus_n) = Step::forward_checked(self.start, n) {
1116 if plus_n < self.end {
1117 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
1119 return Some(plus_n);
1120 }
1121 }
1122
1123 self.start = self.end;
1124 None
1125 }
1126
1127 #[inline]
1128 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1129 let steps = Step::steps_between(&self.start, &self.end);
1130 let available = steps.1.unwrap_or(steps.0);
1131
1132 let taken = available.min(n);
1133
1134 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
1139
1140 NonZero::new(n - taken).map_or(Ok(()), Err)
1141 }
1142
1143 #[inline]
1144 fn spec_next_back(&mut self) -> Option<T> {
1145 if self.start < self.end {
1146 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
1148 Some(self.end)
1149 } else {
1150 None
1151 }
1152 }
1153
1154 #[inline]
1155 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
1156 if let Some(minus_n) = Step::backward_checked(self.end, n) {
1157 if minus_n > self.start {
1158 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
1160 return Some(self.end);
1161 }
1162 }
1163
1164 self.end = self.start;
1165 None
1166 }
1167
1168 #[inline]
1169 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1170 let steps = Step::steps_between(&self.start, &self.end);
1171 let available = steps.1.unwrap_or(steps.0);
1172
1173 let taken = available.min(n);
1174
1175 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
1177
1178 NonZero::new(n - taken).map_or(Ok(()), Err)
1179 }
1180}
1181
1182#[stable(feature = "rust1", since = "1.0.0")]
1183#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1184const impl<A: [const] Step + [const] Destruct> Iterator for ops::Range<A> {
1185 type Item = A;
1186
1187 #[inline]
1188 fn next(&mut self) -> Option<A> {
1189 self.spec_next()
1190 }
1191
1192 #[inline]
1193 fn size_hint(&self) -> (usize, Option<usize>) {
1194 if self.start < self.end {
1195 Step::steps_between(&self.start, &self.end)
1196 } else {
1197 (0, Some(0))
1198 }
1199 }
1200
1201 #[inline]
1202 fn count(self) -> usize {
1203 if self.start < self.end {
1204 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
1205 } else {
1206 0
1207 }
1208 }
1209
1210 #[inline]
1211 fn nth(&mut self, n: usize) -> Option<A> {
1212 self.spec_nth(n)
1213 }
1214
1215 #[inline]
1216 fn last(mut self) -> Option<A> {
1217 self.next_back()
1218 }
1219
1220 #[inline]
1221 fn min(mut self) -> Option<A>
1222 where
1223 A: Ord,
1224 {
1225 self.next()
1226 }
1227
1228 #[inline]
1229 fn max(mut self) -> Option<A>
1230 where
1231 A: Ord,
1232 {
1233 self.next_back()
1234 }
1235
1236 #[inline]
1237 fn is_sorted(self) -> bool
1238 where
1239 Self: [const] Destruct,
1240 {
1241 true
1242 }
1243
1244 #[inline]
1245 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1246 self.spec_advance_by(n)
1247 }
1248
1249 #[inline]
1250 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
1251 where
1252 Self: TrustedRandomAccessNoCoerce,
1253 {
1254 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
1259 }
1260}
1261
1262range_exact_iter_impl! {
1271 usize u8 u16
1272 isize i8 i16
1273 NonZero<usize> NonZero<u8> NonZero<u16>
1274
1275 u32
1280 i32
1281}
1282
1283unsafe_range_trusted_random_access_impl! {
1284 usize u8 u16
1285 isize i8 i16
1286 NonZero<usize> NonZero<u8> NonZero<u16>
1287}
1288
1289#[cfg(target_pointer_width = "32")]
1290unsafe_range_trusted_random_access_impl! {
1291 u32 i32
1292 NonZero<u32>
1293}
1294
1295#[cfg(target_pointer_width = "64")]
1296unsafe_range_trusted_random_access_impl! {
1297 u32 i32
1298 u64 i64
1299 NonZero<u32>
1300 NonZero<u64>
1301}
1302
1303range_incl_exact_iter_impl! {
1304 u8
1305 i8
1306 NonZero<u8>
1307 NonZero<u16> NonZero<usize>
1310
1311 u16
1316 i16
1317}
1318
1319#[stable(feature = "rust1", since = "1.0.0")]
1320#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1321const impl<A: [const] Step + [const] Destruct> DoubleEndedIterator for ops::Range<A> {
1322 #[inline]
1323 fn next_back(&mut self) -> Option<A> {
1324 self.spec_next_back()
1325 }
1326
1327 #[inline]
1328 fn nth_back(&mut self, n: usize) -> Option<A> {
1329 self.spec_nth_back(n)
1330 }
1331
1332 #[inline]
1333 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1334 self.spec_advance_back_by(n)
1335 }
1336}
1337
1338#[unstable(feature = "trusted_len", issue = "37572")]
1358unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1359
1360#[stable(feature = "fused", since = "1.26.0")]
1361impl<A: Step> FusedIterator for ops::Range<A> {}
1362
1363#[stable(feature = "rust1", since = "1.0.0")]
1364impl<A: Step> Iterator for ops::RangeFrom<A> {
1365 type Item = A;
1366
1367 #[inline]
1368 fn next(&mut self) -> Option<A> {
1369 let n = Step::forward(self.start.clone(), 1);
1370 Some(mem::replace(&mut self.start, n))
1371 }
1372
1373 #[inline]
1374 fn size_hint(&self) -> (usize, Option<usize>) {
1375 (usize::MAX, None)
1376 }
1377
1378 #[inline]
1379 fn nth(&mut self, n: usize) -> Option<A> {
1380 let plus_n = Step::forward(self.start.clone(), n);
1381 self.start = Step::forward(plus_n.clone(), 1);
1382 Some(plus_n)
1383 }
1384}
1385
1386#[unstable(feature = "trusted_len", issue = "37572")]
1388unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1389
1390#[stable(feature = "fused", since = "1.26.0")]
1391impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1392
1393trait RangeInclusiveIteratorImpl {
1394 type Item;
1395
1396 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1398 where
1399 Self: Sized,
1400 F: FnMut(B, Self::Item) -> R,
1401 R: Try<Output = B>;
1402
1403 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1405 where
1406 Self: Sized,
1407 F: FnMut(B, Self::Item) -> R,
1408 R: Try<Output = B>;
1409}
1410
1411impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1412 type Item = A;
1413
1414 #[inline]
1415 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1416 where
1417 Self: Sized,
1418 F: FnMut(B, A) -> R,
1419 R: Try<Output = B>,
1420 {
1421 if self.is_empty() {
1422 return try { init };
1423 }
1424
1425 let mut accum = init;
1426
1427 while self.start < self.end {
1428 let n =
1429 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1430 let n = mem::replace(&mut self.start, n);
1431 accum = f(accum, n)?;
1432 }
1433
1434 self.exhausted = true;
1435
1436 if self.start == self.end {
1437 accum = f(accum, self.start.clone())?;
1438 }
1439
1440 try { accum }
1441 }
1442
1443 #[inline]
1444 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1445 where
1446 Self: Sized,
1447 F: FnMut(B, A) -> R,
1448 R: Try<Output = B>,
1449 {
1450 if self.is_empty() {
1451 return try { init };
1452 }
1453
1454 let mut accum = init;
1455
1456 while self.start < self.end {
1457 let n =
1458 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1459 let n = mem::replace(&mut self.end, n);
1460 accum = f(accum, n)?;
1461 }
1462
1463 self.exhausted = true;
1464
1465 if self.start == self.end {
1466 accum = f(accum, self.start.clone())?;
1467 }
1468
1469 try { accum }
1470 }
1471}
1472
1473impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1474 #[inline]
1475 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1476 where
1477 Self: Sized,
1478 F: FnMut(B, T) -> R,
1479 R: Try<Output = B>,
1480 {
1481 if self.is_empty() {
1482 return try { init };
1483 }
1484
1485 let mut accum = init;
1486
1487 while self.start < self.end {
1488 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1490 let n = mem::replace(&mut self.start, n);
1491 accum = f(accum, n)?;
1492 }
1493
1494 self.exhausted = true;
1495
1496 if self.start == self.end {
1497 accum = f(accum, self.start)?;
1498 }
1499
1500 try { accum }
1501 }
1502
1503 #[inline]
1504 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1505 where
1506 Self: Sized,
1507 F: FnMut(B, T) -> R,
1508 R: Try<Output = B>,
1509 {
1510 if self.is_empty() {
1511 return try { init };
1512 }
1513
1514 let mut accum = init;
1515
1516 while self.start < self.end {
1517 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1519 let n = mem::replace(&mut self.end, n);
1520 accum = f(accum, n)?;
1521 }
1522
1523 self.exhausted = true;
1524
1525 if self.start == self.end {
1526 accum = f(accum, self.start)?;
1527 }
1528
1529 try { accum }
1530 }
1531}
1532
1533#[stable(feature = "inclusive_range", since = "1.26.0")]
1534impl<A: Step> Iterator for ops::RangeInclusive<A> {
1535 type Item = A;
1536
1537 #[inline]
1538 fn next(&mut self) -> Option<A> {
1539 if self.is_empty() {
1540 return None;
1541 }
1542
1543 let (n, o) = Step::forward_overflowing(self.start.clone(), 1);
1544
1545 self.exhausted = o;
1546 Some(mem::replace(&mut self.start, n))
1547 }
1548
1549 #[inline]
1550 fn size_hint(&self) -> (usize, Option<usize>) {
1551 if self.is_empty() {
1552 return (0, Some(0));
1553 }
1554
1555 let hint = Step::steps_between(&self.start, &self.end);
1556 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1557 }
1558
1559 #[inline]
1560 fn count(self) -> usize {
1561 if self.is_empty() {
1562 return 0;
1563 }
1564
1565 Step::steps_between(&self.start, &self.end)
1566 .1
1567 .and_then(|steps| steps.checked_add(1))
1568 .expect("count overflowed usize")
1569 }
1570
1571 #[inline]
1572 fn nth(&mut self, n: usize) -> Option<A> {
1573 if self.is_empty() {
1574 return None;
1575 }
1576
1577 let (plus_n, on) = Step::forward_overflowing(self.start.clone(), n);
1578 let (plus_1, o1) = Step::forward_overflowing(plus_n.clone(), 1);
1579
1580 self.start = plus_1;
1581 self.exhausted = on | o1;
1582
1583 if !on && plus_n <= self.end { Some(plus_n) } else { None }
1584 }
1585
1586 #[inline]
1587 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1588 where
1589 Self: Sized,
1590 F: FnMut(B, Self::Item) -> R,
1591 R: Try<Output = B>,
1592 {
1593 self.spec_try_fold(init, f)
1594 }
1595
1596 impl_fold_via_try_fold! { fold -> try_fold }
1597
1598 #[inline]
1599 fn last(mut self) -> Option<A> {
1600 self.next_back()
1601 }
1602
1603 #[inline]
1604 fn min(mut self) -> Option<A>
1605 where
1606 A: Ord,
1607 {
1608 self.next()
1609 }
1610
1611 #[inline]
1612 fn max(mut self) -> Option<A>
1613 where
1614 A: Ord,
1615 {
1616 self.next_back()
1617 }
1618
1619 #[inline]
1620 fn is_sorted(self) -> bool {
1621 true
1622 }
1623}
1624
1625#[stable(feature = "inclusive_range", since = "1.26.0")]
1626impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1627 #[inline]
1628 fn next_back(&mut self) -> Option<A> {
1629 if self.is_empty() {
1630 return None;
1631 }
1632
1633 let (n, o) = Step::backward_overflowing(self.end.clone(), 1);
1634
1635 self.exhausted = o;
1636 Some(mem::replace(&mut self.end, n))
1637 }
1638
1639 #[inline]
1640 fn nth_back(&mut self, n: usize) -> Option<A> {
1641 if self.is_empty() {
1642 return None;
1643 }
1644
1645 let (minus_n, on) = Step::backward_overflowing(self.end.clone(), n);
1646 let (minus_1, o1) = Step::backward_overflowing(minus_n.clone(), 1);
1647
1648 self.end = minus_1;
1649 self.exhausted = on | o1;
1650
1651 if !on && minus_n >= self.start { Some(minus_n) } else { None }
1652 }
1653
1654 #[inline]
1655 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1656 where
1657 Self: Sized,
1658 F: FnMut(B, Self::Item) -> R,
1659 R: Try<Output = B>,
1660 {
1661 self.spec_try_rfold(init, f)
1662 }
1663
1664 impl_fold_via_try_fold! { rfold -> try_rfold }
1665}
1666
1667#[unstable(feature = "trusted_len", issue = "37572")]
1669unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1670
1671#[stable(feature = "fused", since = "1.26.0")]
1672impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}