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 #[ferrocene::prevalidated]
119 fn forward(start: Self, count: usize) -> Self {
120 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
121 }
122
123 #[ferrocene::prevalidated]
145 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
146 Step::forward(start, count)
147 }
148
149 fn backward_checked(start: Self, count: usize) -> Option<Self>;
166
167 fn backward_overflowing(start: Self, count: usize) -> (Self, bool);
191
192 #[ferrocene::prevalidated]
216 fn backward(start: Self, count: usize) -> Self {
217 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
218 }
219
220 #[ferrocene::prevalidated]
242 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
243 Step::backward(start, count)
244 }
245}
246
247macro_rules! step_signed_methods {
250 ($unsigned: ty) => {
251 #[inline]
252 #[ferrocene::prevalidated]
253 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
254 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
256 }
257
258 #[inline]
259 #[ferrocene::prevalidated]
260 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
261 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
263 }
264 };
265}
266
267macro_rules! step_unsigned_methods {
268 () => {
269 #[inline]
270 #[ferrocene::prevalidated]
271 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
272 unsafe { start.unchecked_add(n as Self) }
274 }
275
276 #[inline]
277 #[ferrocene::prevalidated]
278 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
279 unsafe { start.unchecked_sub(n as Self) }
281 }
282 };
283}
284
285macro_rules! step_identical_methods {
287 () => {
288 #[inline]
289 #[allow(arithmetic_overflow)]
290 #[rustc_inherit_overflow_checks]
291 #[ferrocene::prevalidated]
292 fn forward(start: Self, n: usize) -> Self {
293 if Self::forward_checked(start, n).is_none() {
296 let _ = Self::MAX + 1;
297 }
298 start.wrapping_add(n as Self)
300 }
301
302 #[inline]
303 #[allow(arithmetic_overflow)]
304 #[rustc_inherit_overflow_checks]
305 #[ferrocene::prevalidated]
306 fn backward(start: Self, n: usize) -> Self {
307 if Self::backward_checked(start, n).is_none() {
310 let _ = Self::MIN - 1;
311 }
312 start.wrapping_sub(n as Self)
314 }
315 };
316}
317
318macro_rules! step_integer_impls {
319 {
320 [ $( [ $u_narrower:ident $i_narrower:ident ] ),+ ] <= usize <
321 [ $( [ $u_wider:ident $i_wider:ident ] ),+ ]
322 } => {
323 $(
324 #[allow(unreachable_patterns)]
325 #[unstable(feature = "step_trait", issue = "42168")]
326 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
327 const impl Step for $u_narrower {
328 step_identical_methods!();
329 step_unsigned_methods!();
330
331 #[inline]
332 #[ferrocene::prevalidated]
333 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
334 if *start <= *end {
335 let steps = (*end - *start) as usize;
337 (steps, Some(steps))
338 } else {
339 (0, None)
340 }
341 }
342
343 #[inline]
344 #[ferrocene::prevalidated]
345 fn forward_checked(start: Self, n: usize) -> Option<Self> {
346 match Self::try_from(n) {
347 Ok(n) => start.checked_add(n),
348 Err(_) => None, }
350 }
351
352 #[inline]
353 #[ferrocene::prevalidated]
354 fn backward_checked(start: Self, n: usize) -> Option<Self> {
355 match Self::try_from(n) {
356 Ok(n) => start.checked_sub(n),
357 Err(_) => None, }
359 }
360
361 #[inline]
362 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
363 match Self::try_from(n) {
364 Ok(n) => start.overflowing_add(n),
365 Err(_) => (start.wrapping_add(n as Self), true),
367 }
368 }
369
370 #[inline]
371 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
372 match Self::try_from(n) {
373 Ok(n) => start.overflowing_sub(n),
374 Err(_) => (start.wrapping_sub(n as Self), true),
376 }
377 }
378 }
379
380 #[allow(unreachable_patterns)]
381 #[unstable(feature = "step_trait", issue = "42168")]
382 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
383 const impl Step for $i_narrower {
384 step_identical_methods!();
385 step_signed_methods!($u_narrower);
386
387 #[inline]
388 #[ferrocene::prevalidated]
389 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
390 if *start <= *end {
391 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
397 (steps, Some(steps))
398 } else {
399 (0, None)
400 }
401 }
402
403 #[inline]
404 #[ferrocene::prevalidated]
405 fn forward_checked(start: Self, n: usize) -> Option<Self> {
406 match $u_narrower::try_from(n) {
407 Ok(n) => {
408 let wrapped = start.wrapping_add(n as Self);
412 if wrapped >= start {
413 Some(wrapped)
414 } else {
415 None }
417 }
418 Err(_) => None,
422 }
423 }
424
425 #[inline]
426 #[ferrocene::prevalidated]
427 fn backward_checked(start: Self, n: usize) -> Option<Self> {
428 match $u_narrower::try_from(n) {
429 Ok(n) => {
430 let wrapped = start.wrapping_sub(n as Self);
434 if wrapped <= start {
435 Some(wrapped)
436 } else {
437 None }
439 }
440 Err(_) => None,
444 }
445 }
446
447 #[inline]
448 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
449 match $u_narrower::try_from(n) {
450 Ok(n) => start.overflowing_add_unsigned(n),
451 Err(_) => (start.wrapping_add_unsigned(n as $u_narrower), true),
455 }
456 }
457
458 #[inline]
459 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
460 match $u_narrower::try_from(n) {
461 Ok(n) => start.overflowing_sub_unsigned(n),
462 Err(_) => (start.wrapping_sub_unsigned(n as $u_narrower), true),
466 }
467 }
468 }
469 )+
470
471 $(
472 #[allow(unreachable_patterns)]
473 #[unstable(feature = "step_trait", issue = "42168")]
474 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
475 const impl Step for $u_wider {
476 step_identical_methods!();
477 step_unsigned_methods!();
478
479 #[inline]
480 #[ferrocene::prevalidated]
481 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
482 if *start <= *end {
483 if let Ok(steps) = usize::try_from(*end - *start) {
484 (steps, Some(steps))
485 } else {
486 (usize::MAX, None)
487 }
488 } else {
489 (0, None)
490 }
491 }
492
493 #[inline]
494 #[ferrocene::prevalidated]
495 fn forward_checked(start: Self, n: usize) -> Option<Self> {
496 start.checked_add(n as Self)
497 }
498
499 #[inline]
500 #[ferrocene::prevalidated]
501 fn backward_checked(start: Self, n: usize) -> Option<Self> {
502 start.checked_sub(n as Self)
503 }
504
505 #[inline]
506 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
507 start.overflowing_add(n as Self)
508 }
509
510 #[inline]
511 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
512 start.overflowing_sub(n as Self)
513 }
514 }
515
516 #[allow(unreachable_patterns)]
517 #[unstable(feature = "step_trait", issue = "42168")]
518 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
519 const impl Step for $i_wider {
520 step_identical_methods!();
521 step_signed_methods!($u_wider);
522
523 #[inline]
524 #[ferrocene::prevalidated]
525 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
526 if *start <= *end {
527 match end.checked_sub(*start) {
528 Some(result) => {
529 if let Ok(steps) = usize::try_from(result) {
530 (steps, Some(steps))
531 } else {
532 (usize::MAX, None)
533 }
534 }
535 None => (usize::MAX, None),
538 }
539 } else {
540 (0, None)
541 }
542 }
543
544 #[inline]
545 #[ferrocene::prevalidated]
546 fn forward_checked(start: Self, n: usize) -> Option<Self> {
547 start.checked_add(n as Self)
548 }
549
550 #[inline]
551 #[ferrocene::prevalidated]
552 fn backward_checked(start: Self, n: usize) -> Option<Self> {
553 start.checked_sub(n as Self)
554 }
555
556 #[inline]
557 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
558 start.overflowing_add_unsigned(n as $u_wider)
559 }
560
561 #[inline]
562 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
563 start.overflowing_sub_unsigned(n as $u_wider)
564 }
565 }
566 )+
567 };
568}
569
570#[cfg(target_pointer_width = "64")]
571step_integer_impls! {
572 [ [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize] ] <= usize < [ [u128 i128] ]
573}
574
575#[cfg(target_pointer_width = "32")]
576step_integer_impls! {
577 [ [u8 i8], [u16 i16], [u32 i32], [usize isize] ] <= usize < [ [u64 i64], [u128 i128] ]
578}
579
580#[cfg(target_pointer_width = "16")]
581step_integer_impls! {
582 [ [u8 i8], [u16 i16], [usize isize] ] <= usize < [ [u32 i32], [u64 i64], [u128 i128] ]
583}
584
585macro_rules! step_nonzero_identical_methods {
587 ($int:ident) => {
588 #[inline]
589 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
590 unsafe { Self::new_unchecked(start.get().unchecked_add(n as $int)) }
592 }
593
594 #[inline]
595 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
596 unsafe { Self::new_unchecked(start.get().unchecked_sub(n as $int)) }
598 }
599
600 #[inline]
601 #[allow(arithmetic_overflow)]
602 #[rustc_inherit_overflow_checks]
603 fn forward(start: Self, n: usize) -> Self {
604 if Self::forward_checked(start, n).is_none() {
607 let _ = $int::MAX + 1;
608 }
609 start.saturating_add(n as $int)
611 }
612
613 #[inline]
614 #[allow(arithmetic_overflow)]
615 #[rustc_inherit_overflow_checks]
616 fn backward(start: Self, n: usize) -> Self {
617 if Self::backward_checked(start, n).is_none() {
620 let _ = $int::MIN - 1;
621 }
622 Self::new(start.get().saturating_sub(n as $int)).unwrap_or(Self::MIN)
624 }
625
626 #[inline]
632 fn forward_overflowing(start: Self, n: usize) -> (Self, bool) {
633 if let Some(s) = Step::forward_checked(start, n) {
635 (s, false)
636 } else {
637 (Self::MAX, true)
638 }
639 }
640
641 #[inline]
642 fn backward_overflowing(start: Self, n: usize) -> (Self, bool) {
643 if let Some(s) = Step::backward_checked(start, n) {
645 (s, false)
646 } else {
647 (Self::MIN, true)
648 }
649 }
650
651 #[inline]
652 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
653 if *start <= *end {
654 #[allow(irrefutable_let_patterns, reason = "happens on usize or narrower")]
655 if let Ok(steps) = usize::try_from(end.get() - start.get()) {
656 (steps, Some(steps))
657 } else {
658 (usize::MAX, None)
659 }
660 } else {
661 (0, None)
662 }
663 }
664 };
665}
666
667macro_rules! step_nonzero_impls {
668 {
669 [$( $narrower:ident ),+] <= usize < [$( $wider:ident ),+]
670 } => {
671 $(
672 #[allow(unreachable_patterns)]
673 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
674 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
675 const impl Step for NonZero<$narrower> {
676 step_nonzero_identical_methods!($narrower);
677
678 #[inline]
679 fn forward_checked(start: Self, n: usize) -> Option<Self> {
680 match $narrower::try_from(n) {
681 Ok(n) => start.checked_add(n),
682 Err(_) => None, }
684 }
685
686 #[inline]
687 fn backward_checked(start: Self, n: usize) -> Option<Self> {
688 match $narrower::try_from(n) {
689 Ok(n) => start.get().checked_sub(n).and_then(Self::new),
691 Err(_) => None, }
693 }
694 }
695 )+
696
697 $(
698 #[allow(unreachable_patterns)]
699 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
700 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
701 const impl Step for NonZero<$wider> {
702 step_nonzero_identical_methods!($wider);
703
704 #[inline]
705 fn forward_checked(start: Self, n: usize) -> Option<Self> {
706 start.checked_add(n as $wider)
707 }
708
709 #[inline]
710 fn backward_checked(start: Self, n: usize) -> Option<Self> {
711 start.get().checked_sub(n as $wider).and_then(Self::new)
712 }
713 }
714 )+
715 };
716}
717
718#[cfg(target_pointer_width = "64")]
719step_nonzero_impls! {
720 [u8, u16, u32, u64, usize] <= usize < [u128]
721}
722
723#[cfg(target_pointer_width = "32")]
724step_nonzero_impls! {
725 [u8, u16, u32, usize] <= usize < [u64, u128]
726}
727
728#[cfg(target_pointer_width = "16")]
729step_nonzero_impls! {
730 [u8, u16, usize] <= usize < [u32, u64, u128]
731}
732
733#[unstable(feature = "step_trait", issue = "42168")]
734#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
735const impl Step for char {
736 #[inline]
737 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
738 let start = start as u32;
739 let end = end as u32;
740 if start <= end {
741 let count = end - start;
742 if start < 0xD800 && 0xE000 <= end {
743 if let Ok(steps) = usize::try_from(count - 0x800) {
744 (steps, Some(steps))
745 } else {
746 (usize::MAX, None)
747 }
748 } else {
749 if let Ok(steps) = usize::try_from(count) {
750 (steps, Some(steps))
751 } else {
752 (usize::MAX, None)
753 }
754 }
755 } else {
756 (0, None)
757 }
758 }
759
760 #[inline]
761 fn forward_checked(start: char, count: usize) -> Option<char> {
762 let start = start as u32;
763 let mut res = Step::forward_checked(start, count)?;
764 if start < 0xD800 && 0xD800 <= res {
765 res = Step::forward_checked(res, 0x800)?;
766 }
767 if res <= char::MAX as u32 {
768 Some(unsafe { char::from_u32_unchecked(res) })
771 } else {
772 None
773 }
774 }
775
776 #[inline]
777 fn backward_checked(start: char, count: usize) -> Option<char> {
778 let start = start as u32;
779 let mut res = Step::backward_checked(start, count)?;
780 if start >= 0xE000 && 0xE000 > res {
781 res = Step::backward_checked(res, 0x800)?;
782 }
783 Some(unsafe { char::from_u32_unchecked(res) })
786 }
787
788 #[inline]
794 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
795 if let Some(c) = Step::forward_checked(start, count) {
796 (c, false)
797 } else {
798 (Self::MAX, true)
799 }
800 }
801
802 #[inline]
803 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
804 if let Some(c) = Step::backward_checked(start, count) {
805 (c, false)
806 } else {
807 (Self::MIN, true)
808 }
809 }
810
811 #[inline]
812 unsafe fn forward_unchecked(start: char, count: usize) -> char {
813 let start = start as u32;
814 let mut res = unsafe { Step::forward_unchecked(start, count) };
817 if start < 0xD800 && 0xD800 <= res {
818 res = unsafe { Step::forward_unchecked(res, 0x800) };
821 }
822 unsafe { char::from_u32_unchecked(res) }
825 }
826
827 #[inline]
828 unsafe fn backward_unchecked(start: char, count: usize) -> char {
829 let start = start as u32;
830 let mut res = unsafe { Step::backward_unchecked(start, count) };
833 if start >= 0xE000 && 0xE000 > res {
834 res = unsafe { Step::backward_unchecked(res, 0x800) };
837 }
838 unsafe { char::from_u32_unchecked(res) }
841 }
842}
843
844#[unstable(feature = "step_trait", issue = "42168")]
845#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
846const impl Step for AsciiChar {
847 #[inline]
848 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
849 Step::steps_between(&start.to_u8(), &end.to_u8())
850 }
851
852 #[inline]
853 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
854 let end = Step::forward_checked(start.to_u8(), count)?;
855 AsciiChar::from_u8(end)
856 }
857
858 #[inline]
859 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
860 let end = Step::backward_checked(start.to_u8(), count)?;
861
862 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
864 }
865
866 #[inline]
867 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
868 let (s, o) = (start as usize).overflowing_add(count);
869 let ret = s & (AsciiChar::MAX as usize);
870
871 (unsafe { AsciiChar::from_u8_unchecked(ret as u8) }, o || ret < s)
873 }
874
875 #[inline]
876 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
877 let (s, o) = (start as usize).overflowing_sub(count);
878 let ret = s & (AsciiChar::MAX as usize);
879
880 (unsafe { AsciiChar::from_u8_unchecked(ret as u8) }, o || ret < s)
882 }
883
884 #[inline]
885 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
886 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
889
890 unsafe { AsciiChar::from_u8_unchecked(end) }
892 }
893
894 #[inline]
895 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
896 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
899
900 unsafe { AsciiChar::from_u8_unchecked(end) }
902 }
903}
904
905#[unstable(feature = "step_trait", issue = "42168")]
906#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
907const impl Step for Ipv4Addr {
908 #[inline]
909 fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
910 u32::steps_between(&start.to_bits(), &end.to_bits())
911 }
912
913 #[inline]
914 fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
915 u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
916 }
917
918 #[inline]
919 fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
920 u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
921 }
922
923 #[inline]
924 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
925 let (s, o) = u32::forward_overflowing(start.to_bits(), count);
926 (Ipv4Addr::from_bits(s), o)
927 }
928
929 #[inline]
930 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
931 let (s, o) = u32::backward_overflowing(start.to_bits(), count);
932 (Ipv4Addr::from_bits(s), o)
933 }
934
935 #[inline]
936 unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
937 Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
940 }
941
942 #[inline]
943 unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
944 Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
947 }
948}
949
950#[unstable(feature = "step_trait", issue = "42168")]
951#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
952const impl Step for Ipv6Addr {
953 #[inline]
954 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
955 u128::steps_between(&start.to_bits(), &end.to_bits())
956 }
957
958 #[inline]
959 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
960 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
961 }
962
963 #[inline]
964 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
965 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
966 }
967
968 #[inline]
969 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
970 let (s, o) = u128::forward_overflowing(start.to_bits(), count);
971 (Ipv6Addr::from_bits(s), o)
972 }
973
974 #[inline]
975 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
976 let (s, o) = u128::backward_overflowing(start.to_bits(), count);
977 (Ipv6Addr::from_bits(s), o)
978 }
979
980 #[inline]
981 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
982 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
985 }
986
987 #[inline]
988 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
989 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
992 }
993}
994
995macro_rules! range_exact_iter_impl {
996 ($($t:ty)*) => ($(
997 #[stable(feature = "rust1", since = "1.0.0")]
998 impl ExactSizeIterator for ops::Range<$t> { }
999 )*)
1000}
1001
1002macro_rules! unsafe_range_trusted_random_access_impl {
1005 ($($t:ty)*) => ($(
1006 #[doc(hidden)]
1007 #[unstable(feature = "trusted_random_access", issue = "none")]
1008 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
1009
1010 #[doc(hidden)]
1011 #[unstable(feature = "trusted_random_access", issue = "none")]
1012 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
1013 const MAY_HAVE_SIDE_EFFECT: bool = false;
1014 }
1015 )*)
1016}
1017
1018macro_rules! range_incl_exact_iter_impl {
1019 ($($t:ty)*) => ($(
1020 #[stable(feature = "inclusive_range", since = "1.26.0")]
1021 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
1022 )*)
1023}
1024
1025const trait RangeIteratorImpl {
1027 type Item;
1028
1029 fn spec_next(&mut self) -> Option<Self::Item>;
1031 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
1032 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
1033
1034 fn spec_next_back(&mut self) -> Option<Self::Item>;
1036 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
1037 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
1038}
1039
1040#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1041const impl<A: [const] Step + [const] Destruct> RangeIteratorImpl for ops::Range<A> {
1042 type Item = A;
1043
1044 #[inline]
1045 #[ferrocene::prevalidated]
1046 default fn spec_next(&mut self) -> Option<A> {
1047 if self.start < self.end {
1048 let n =
1049 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1050 Some(mem::replace(&mut self.start, n))
1051 } else {
1052 None
1053 }
1054 }
1055
1056 #[inline]
1057 #[ferrocene::prevalidated]
1058 default fn spec_nth(&mut self, n: usize) -> Option<A> {
1059 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1060 if plus_n < self.end {
1061 self.start =
1062 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
1063 return Some(plus_n);
1064 }
1065 }
1066
1067 self.start = self.end.clone();
1068 None
1069 }
1070
1071 #[inline]
1072 #[ferrocene::prevalidated]
1073 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1074 let steps = Step::steps_between(&self.start, &self.end);
1075 let available = steps.1.unwrap_or(steps.0);
1076
1077 let taken = available.min(n);
1078
1079 self.start =
1080 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
1081
1082 NonZero::new(n - taken).map_or(Ok(()), Err)
1083 }
1084
1085 #[inline]
1086 #[ferrocene::prevalidated]
1087 default fn spec_next_back(&mut self) -> Option<A> {
1088 if self.start < self.end {
1089 self.end =
1090 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1091 Some(self.end.clone())
1092 } else {
1093 None
1094 }
1095 }
1096
1097 #[inline]
1098 #[ferrocene::prevalidated]
1099 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
1100 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1101 if minus_n > self.start {
1102 self.end =
1103 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
1104 return Some(self.end.clone());
1105 }
1106 }
1107
1108 self.end = self.start.clone();
1109 None
1110 }
1111
1112 #[inline]
1113 #[ferrocene::prevalidated]
1114 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1115 let steps = Step::steps_between(&self.start, &self.end);
1116 let available = steps.1.unwrap_or(steps.0);
1117
1118 let taken = available.min(n);
1119
1120 self.end =
1121 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
1122
1123 NonZero::new(n - taken).map_or(Ok(()), Err)
1124 }
1125}
1126
1127#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1128const impl<T: [const] TrustedStep + [const] Destruct> RangeIteratorImpl for ops::Range<T> {
1129 #[inline]
1130 #[ferrocene::prevalidated]
1131 fn spec_next(&mut self) -> Option<T> {
1132 if self.start < self.end {
1133 let old = self.start;
1134 self.start = unsafe { Step::forward_unchecked(old, 1) };
1136 Some(old)
1137 } else {
1138 None
1139 }
1140 }
1141
1142 #[inline]
1143 #[ferrocene::prevalidated]
1144 fn spec_nth(&mut self, n: usize) -> Option<T> {
1145 if let Some(plus_n) = Step::forward_checked(self.start, n) {
1146 if plus_n < self.end {
1147 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
1149 return Some(plus_n);
1150 }
1151 }
1152
1153 self.start = self.end;
1154 None
1155 }
1156
1157 #[inline]
1158 #[ferrocene::prevalidated]
1159 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1160 let steps = Step::steps_between(&self.start, &self.end);
1161 let available = steps.1.unwrap_or(steps.0);
1162
1163 let taken = available.min(n);
1164
1165 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
1170
1171 NonZero::new(n - taken).map_or(Ok(()), Err)
1172 }
1173
1174 #[inline]
1175 #[ferrocene::prevalidated]
1176 fn spec_next_back(&mut self) -> Option<T> {
1177 if self.start < self.end {
1178 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
1180 Some(self.end)
1181 } else {
1182 None
1183 }
1184 }
1185
1186 #[inline]
1187 #[ferrocene::prevalidated]
1188 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
1189 if let Some(minus_n) = Step::backward_checked(self.end, n) {
1190 if minus_n > self.start {
1191 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
1193 return Some(self.end);
1194 }
1195 }
1196
1197 self.end = self.start;
1198 None
1199 }
1200
1201 #[inline]
1202 #[ferrocene::prevalidated]
1203 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1204 let steps = Step::steps_between(&self.start, &self.end);
1205 let available = steps.1.unwrap_or(steps.0);
1206
1207 let taken = available.min(n);
1208
1209 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
1211
1212 NonZero::new(n - taken).map_or(Ok(()), Err)
1213 }
1214}
1215
1216#[stable(feature = "rust1", since = "1.0.0")]
1217#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1218const impl<A: [const] Step + [const] Destruct> Iterator for ops::Range<A> {
1219 type Item = A;
1220
1221 #[inline]
1222 #[ferrocene::prevalidated]
1223 fn next(&mut self) -> Option<A> {
1224 self.spec_next()
1225 }
1226
1227 #[inline]
1228 #[ferrocene::prevalidated]
1229 fn size_hint(&self) -> (usize, Option<usize>) {
1230 if self.start < self.end {
1231 Step::steps_between(&self.start, &self.end)
1232 } else {
1233 (0, Some(0))
1234 }
1235 }
1236
1237 #[inline]
1238 #[ferrocene::prevalidated]
1239 fn count(self) -> usize {
1240 if self.start < self.end {
1241 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
1242 } else {
1243 0
1244 }
1245 }
1246
1247 #[inline]
1248 #[ferrocene::prevalidated]
1249 fn nth(&mut self, n: usize) -> Option<A> {
1250 self.spec_nth(n)
1251 }
1252
1253 #[inline]
1266 fn min(mut self) -> Option<A>
1267 where
1268 A: Ord,
1269 {
1270 self.next()
1271 }
1272
1273 #[inline]
1274 fn max(mut self) -> Option<A>
1275 where
1276 A: Ord,
1277 {
1278 self.next_back()
1279 }
1280
1281 #[inline]
1282 fn is_sorted(self) -> bool
1283 where
1284 Self: [const] Destruct,
1285 {
1286 true
1287 }
1288
1289 #[inline]
1290 #[ferrocene::prevalidated]
1291 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1292 self.spec_advance_by(n)
1293 }
1294
1295 #[inline]
1296 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
1297 where
1298 Self: TrustedRandomAccessNoCoerce,
1299 {
1300 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
1305 }
1306}
1307
1308range_exact_iter_impl! {
1317 usize u8 u16
1318 isize i8 i16
1319 NonZero<usize> NonZero<u8> NonZero<u16>
1320
1321 u32
1326 i32
1327}
1328
1329unsafe_range_trusted_random_access_impl! {
1330 usize u8 u16
1331 isize i8 i16
1332 NonZero<usize> NonZero<u8> NonZero<u16>
1333}
1334
1335#[cfg(target_pointer_width = "32")]
1336unsafe_range_trusted_random_access_impl! {
1337 u32 i32
1338 NonZero<u32>
1339}
1340
1341#[cfg(target_pointer_width = "64")]
1342unsafe_range_trusted_random_access_impl! {
1343 u32 i32
1344 u64 i64
1345 NonZero<u32>
1346 NonZero<u64>
1347}
1348
1349range_incl_exact_iter_impl! {
1350 u8
1351 i8
1352 NonZero<u8>
1353 NonZero<u16> NonZero<usize>
1356
1357 u16
1362 i16
1363}
1364
1365#[stable(feature = "rust1", since = "1.0.0")]
1366#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
1367const impl<A: [const] Step + [const] Destruct> DoubleEndedIterator for ops::Range<A> {
1368 #[inline]
1369 #[ferrocene::prevalidated]
1370 fn next_back(&mut self) -> Option<A> {
1371 self.spec_next_back()
1372 }
1373
1374 #[inline]
1375 #[ferrocene::prevalidated]
1376 fn nth_back(&mut self, n: usize) -> Option<A> {
1377 self.spec_nth_back(n)
1378 }
1379
1380 #[inline]
1381 #[ferrocene::prevalidated]
1382 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1383 self.spec_advance_back_by(n)
1384 }
1385}
1386
1387#[unstable(feature = "trusted_len", issue = "37572")]
1407unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1408
1409#[stable(feature = "fused", since = "1.26.0")]
1410impl<A: Step> FusedIterator for ops::Range<A> {}
1411
1412#[stable(feature = "rust1", since = "1.0.0")]
1413impl<A: Step> Iterator for ops::RangeFrom<A> {
1414 type Item = A;
1415
1416 #[inline]
1417 fn next(&mut self) -> Option<A> {
1418 let n = Step::forward(self.start.clone(), 1);
1419 Some(mem::replace(&mut self.start, n))
1420 }
1421
1422 #[inline]
1423 fn size_hint(&self) -> (usize, Option<usize>) {
1424 (usize::MAX, None)
1425 }
1426
1427 #[inline]
1428 fn nth(&mut self, n: usize) -> Option<A> {
1429 let plus_n = Step::forward(self.start.clone(), n);
1430 self.start = Step::forward(plus_n.clone(), 1);
1431 Some(plus_n)
1432 }
1433}
1434
1435#[unstable(feature = "trusted_len", issue = "37572")]
1437unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1438
1439#[stable(feature = "fused", since = "1.26.0")]
1440impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1441
1442trait RangeInclusiveIteratorImpl {
1443 type Item;
1444
1445 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1447 where
1448 Self: Sized,
1449 F: FnMut(B, Self::Item) -> R,
1450 R: Try<Output = B>;
1451
1452 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1454 where
1455 Self: Sized,
1456 F: FnMut(B, Self::Item) -> R,
1457 R: Try<Output = B>;
1458}
1459
1460impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1461 type Item = A;
1462
1463 #[inline]
1464 #[ferrocene::prevalidated]
1465 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1466 where
1467 Self: Sized,
1468 F: FnMut(B, A) -> R,
1469 R: Try<Output = B>,
1470 {
1471 if self.is_empty() {
1472 return try { init };
1473 }
1474
1475 let mut accum = init;
1476
1477 while self.start < self.end {
1478 let n =
1479 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1480 let n = mem::replace(&mut self.start, n);
1481 accum = f(accum, n)?;
1482 }
1483
1484 self.exhausted = true;
1485
1486 if self.start == self.end {
1487 accum = f(accum, self.start.clone())?;
1488 }
1489
1490 try { accum }
1491 }
1492
1493 #[inline]
1494 #[ferrocene::prevalidated]
1495 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1496 where
1497 Self: Sized,
1498 F: FnMut(B, A) -> R,
1499 R: Try<Output = B>,
1500 {
1501 if self.is_empty() {
1502 return try { init };
1503 }
1504
1505 let mut accum = init;
1506
1507 while self.start < self.end {
1508 let n =
1509 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1510 let n = mem::replace(&mut self.end, n);
1511 accum = f(accum, n)?;
1512 }
1513
1514 self.exhausted = true;
1515
1516 if self.start == self.end {
1517 accum = f(accum, self.start.clone())?;
1518 }
1519
1520 try { accum }
1521 }
1522}
1523
1524impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1525 #[inline]
1526 #[ferrocene::prevalidated]
1527 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1528 where
1529 Self: Sized,
1530 F: FnMut(B, T) -> R,
1531 R: Try<Output = B>,
1532 {
1533 if self.is_empty() {
1534 return try { init };
1535 }
1536
1537 let mut accum = init;
1538
1539 while self.start < self.end {
1540 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1542 let n = mem::replace(&mut self.start, n);
1543 accum = f(accum, n)?;
1544 }
1545
1546 self.exhausted = true;
1547
1548 if self.start == self.end {
1549 accum = f(accum, self.start)?;
1550 }
1551
1552 try { accum }
1553 }
1554
1555 #[inline]
1556 #[ferrocene::prevalidated]
1557 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1558 where
1559 Self: Sized,
1560 F: FnMut(B, T) -> R,
1561 R: Try<Output = B>,
1562 {
1563 if self.is_empty() {
1564 return try { init };
1565 }
1566
1567 let mut accum = init;
1568
1569 while self.start < self.end {
1570 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1572 let n = mem::replace(&mut self.end, n);
1573 accum = f(accum, n)?;
1574 }
1575
1576 self.exhausted = true;
1577
1578 if self.start == self.end {
1579 accum = f(accum, self.start)?;
1580 }
1581
1582 try { accum }
1583 }
1584}
1585
1586#[stable(feature = "inclusive_range", since = "1.26.0")]
1587impl<A: Step> Iterator for ops::RangeInclusive<A> {
1588 type Item = A;
1589
1590 #[inline]
1591 #[ferrocene::prevalidated]
1592 fn next(&mut self) -> Option<A> {
1593 if self.is_empty() {
1594 return None;
1595 }
1596
1597 let (n, o) = Step::forward_overflowing(self.start.clone(), 1);
1598
1599 self.exhausted = o;
1600 Some(mem::replace(&mut self.start, n))
1601 }
1602
1603 #[inline]
1604 #[ferrocene::prevalidated]
1605 fn size_hint(&self) -> (usize, Option<usize>) {
1606 if self.is_empty() {
1607 return (0, Some(0));
1608 }
1609
1610 let hint = Step::steps_between(&self.start, &self.end);
1611 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1612 }
1613
1614 #[inline]
1615 #[ferrocene::prevalidated]
1616 fn count(self) -> usize {
1617 if self.is_empty() {
1618 return 0;
1619 }
1620
1621 Step::steps_between(&self.start, &self.end)
1622 .1
1623 .and_then(|steps| steps.checked_add(1))
1624 .expect("count overflowed usize")
1625 }
1626
1627 #[inline]
1628 #[ferrocene::prevalidated]
1629 fn nth(&mut self, n: usize) -> Option<A> {
1630 if self.is_empty() {
1631 return None;
1632 }
1633
1634 let (plus_n, on) = Step::forward_overflowing(self.start.clone(), n);
1635 let (plus_1, o1) = Step::forward_overflowing(plus_n.clone(), 1);
1636
1637 self.start = plus_1;
1638 self.exhausted = on | o1;
1639
1640 if !on && plus_n <= self.end { Some(plus_n) } else { None }
1641 }
1642
1643 #[inline]
1644 #[ferrocene::prevalidated]
1645 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1646 where
1647 Self: Sized,
1648 F: FnMut(B, Self::Item) -> R,
1649 R: Try<Output = B>,
1650 {
1651 self.spec_try_fold(init, f)
1652 }
1653
1654 impl_fold_via_try_fold! { fold -> try_fold }
1655
1656 #[inline]
1657 #[ferrocene::prevalidated]
1658 fn last(mut self) -> Option<A> {
1659 self.next_back()
1660 }
1661
1662 #[inline]
1663 fn min(mut self) -> Option<A>
1664 where
1665 A: Ord,
1666 {
1667 self.next()
1668 }
1669
1670 #[inline]
1671 fn max(mut self) -> Option<A>
1672 where
1673 A: Ord,
1674 {
1675 self.next_back()
1676 }
1677
1678 #[inline]
1679 fn is_sorted(self) -> bool {
1680 true
1681 }
1682}
1683
1684#[stable(feature = "inclusive_range", since = "1.26.0")]
1685impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1686 #[inline]
1687 #[ferrocene::prevalidated]
1688 fn next_back(&mut self) -> Option<A> {
1689 if self.is_empty() {
1690 return None;
1691 }
1692
1693 let (n, o) = Step::backward_overflowing(self.end.clone(), 1);
1694
1695 self.exhausted = o;
1696 Some(mem::replace(&mut self.end, n))
1697 }
1698
1699 #[inline]
1700 #[ferrocene::prevalidated]
1701 fn nth_back(&mut self, n: usize) -> Option<A> {
1702 if self.is_empty() {
1703 return None;
1704 }
1705
1706 let (minus_n, on) = Step::backward_overflowing(self.end.clone(), n);
1707 let (minus_1, o1) = Step::backward_overflowing(minus_n.clone(), 1);
1708
1709 self.end = minus_1;
1710 self.exhausted = on | o1;
1711
1712 if !on && minus_n >= self.start { Some(minus_n) } else { None }
1713 }
1714
1715 #[inline]
1716 #[ferrocene::prevalidated]
1717 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1718 where
1719 Self: Sized,
1720 F: FnMut(B, Self::Item) -> R,
1721 R: Try<Output = B>,
1722 {
1723 self.spec_try_rfold(init, f)
1724 }
1725
1726 impl_fold_via_try_fold! { rfold -> try_rfold }
1727}
1728
1729#[unstable(feature = "trusted_len", issue = "37572")]
1731unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1732
1733#[stable(feature = "fused", since = "1.26.0")]
1734impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}