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];
18
19#[rustc_diagnostic_item = "range_step"]
24#[rustc_on_unimplemented(
25 message = "`std::ops::Range<{Self}>` is not an iterator",
26 label = "`Range<{Self}>` is not an iterator",
27 note = "`Range` only implements `Iterator` for select types in the standard library, \
28 particularly integers; to see the full list of types, see the documentation for the \
29 unstable `Step` trait"
30)]
31#[unstable(feature = "step_trait", issue = "42168")]
32#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
33pub const trait Step: [const] Clone + [const] PartialOrd + Sized {
34 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
49
50 fn forward_checked(start: Self, count: usize) -> Option<Self>;
67
68 #[ferrocene::prevalidated]
92 fn forward(start: Self, count: usize) -> Self {
93 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
94 }
95
96 #[ferrocene::prevalidated]
118 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
119 Step::forward(start, count)
120 }
121
122 fn backward_checked(start: Self, count: usize) -> Option<Self>;
139
140 #[ferrocene::prevalidated]
164 fn backward(start: Self, count: usize) -> Self {
165 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
166 }
167
168 #[ferrocene::prevalidated]
190 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
191 Step::backward(start, count)
192 }
193}
194
195macro_rules! step_signed_methods {
198 ($unsigned: ty) => {
199 #[inline]
200 #[ferrocene::prevalidated]
201 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
202 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
204 }
205
206 #[inline]
207 #[ferrocene::prevalidated]
208 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
209 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
211 }
212 };
213}
214
215macro_rules! step_unsigned_methods {
216 () => {
217 #[inline]
218 #[ferrocene::prevalidated]
219 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
220 unsafe { start.unchecked_add(n as Self) }
222 }
223
224 #[inline]
225 #[ferrocene::prevalidated]
226 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
227 unsafe { start.unchecked_sub(n as Self) }
229 }
230 };
231}
232
233macro_rules! step_identical_methods {
235 () => {
236 #[inline]
237 #[allow(arithmetic_overflow)]
238 #[rustc_inherit_overflow_checks]
239 #[ferrocene::prevalidated]
240 fn forward(start: Self, n: usize) -> Self {
241 if Self::forward_checked(start, n).is_none() {
244 let _ = Self::MAX + 1;
245 }
246 start.wrapping_add(n as Self)
248 }
249
250 #[inline]
251 #[allow(arithmetic_overflow)]
252 #[rustc_inherit_overflow_checks]
253 #[ferrocene::prevalidated]
254 fn backward(start: Self, n: usize) -> Self {
255 if Self::backward_checked(start, n).is_none() {
258 let _ = Self::MIN - 1;
259 }
260 start.wrapping_sub(n as Self)
262 }
263 };
264}
265
266macro_rules! step_integer_impls {
267 {
268 narrower than or same width as usize:
269 $( [ $u_narrower:ident $i_narrower:ident ] ),+;
270 wider than usize:
271 $( [ $u_wider:ident $i_wider:ident ] ),+;
272 } => {
273 $(
274 #[allow(unreachable_patterns)]
275 #[unstable(feature = "step_trait", issue = "42168")]
276 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
277 impl const Step for $u_narrower {
278 step_identical_methods!();
279 step_unsigned_methods!();
280
281 #[inline]
282 #[ferrocene::prevalidated]
283 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
284 if *start <= *end {
285 let steps = (*end - *start) as usize;
287 (steps, Some(steps))
288 } else {
289 (0, None)
290 }
291 }
292
293 #[inline]
294 #[ferrocene::prevalidated]
295 fn forward_checked(start: Self, n: usize) -> Option<Self> {
296 match Self::try_from(n) {
297 Ok(n) => start.checked_add(n),
298 Err(_) => None, }
300 }
301
302 #[inline]
303 #[ferrocene::prevalidated]
304 fn backward_checked(start: Self, n: usize) -> Option<Self> {
305 match Self::try_from(n) {
306 Ok(n) => start.checked_sub(n),
307 Err(_) => None, }
309 }
310 }
311
312 #[allow(unreachable_patterns)]
313 #[unstable(feature = "step_trait", issue = "42168")]
314 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
315 impl const Step for $i_narrower {
316 step_identical_methods!();
317 step_signed_methods!($u_narrower);
318
319 #[inline]
320 #[ferrocene::prevalidated]
321 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
322 if *start <= *end {
323 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
329 (steps, Some(steps))
330 } else {
331 (0, None)
332 }
333 }
334
335 #[inline]
336 #[ferrocene::prevalidated]
337 fn forward_checked(start: Self, n: usize) -> Option<Self> {
338 match $u_narrower::try_from(n) {
339 Ok(n) => {
340 let wrapped = start.wrapping_add(n as Self);
344 if wrapped >= start {
345 Some(wrapped)
346 } else {
347 None }
349 }
350 Err(_) => None,
354 }
355 }
356
357 #[inline]
358 #[ferrocene::prevalidated]
359 fn backward_checked(start: Self, n: usize) -> Option<Self> {
360 match $u_narrower::try_from(n) {
361 Ok(n) => {
362 let wrapped = start.wrapping_sub(n as Self);
366 if wrapped <= start {
367 Some(wrapped)
368 } else {
369 None }
371 }
372 Err(_) => None,
376 }
377 }
378 }
379 )+
380
381 $(
382 #[allow(unreachable_patterns)]
383 #[unstable(feature = "step_trait", issue = "42168")]
384 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
385 impl const Step for $u_wider {
386 step_identical_methods!();
387 step_unsigned_methods!();
388
389 #[inline]
390 #[ferrocene::prevalidated]
391 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
392 if *start <= *end {
393 if let Ok(steps) = usize::try_from(*end - *start) {
394 (steps, Some(steps))
395 } else {
396 (usize::MAX, None)
397 }
398 } else {
399 (0, None)
400 }
401 }
402
403 #[inline]
404 #[ferrocene::prevalidated]
405 fn forward_checked(start: Self, n: usize) -> Option<Self> {
406 start.checked_add(n as Self)
407 }
408
409 #[inline]
410 #[ferrocene::prevalidated]
411 fn backward_checked(start: Self, n: usize) -> Option<Self> {
412 start.checked_sub(n as Self)
413 }
414 }
415
416 #[allow(unreachable_patterns)]
417 #[unstable(feature = "step_trait", issue = "42168")]
418 #[rustc_const_unstable(feature = "step_trait", issue = "42168")]
419 impl const Step for $i_wider {
420 step_identical_methods!();
421 step_signed_methods!($u_wider);
422
423 #[inline]
424 #[ferrocene::prevalidated]
425 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
426 if *start <= *end {
427 match end.checked_sub(*start) {
428 Some(result) => {
429 if let Ok(steps) = usize::try_from(result) {
430 (steps, Some(steps))
431 } else {
432 (usize::MAX, None)
433 }
434 }
435 None => (usize::MAX, None),
438 }
439 } else {
440 (0, None)
441 }
442 }
443
444 #[inline]
445 #[ferrocene::prevalidated]
446 fn forward_checked(start: Self, n: usize) -> Option<Self> {
447 start.checked_add(n as Self)
448 }
449
450 #[inline]
451 #[ferrocene::prevalidated]
452 fn backward_checked(start: Self, n: usize) -> Option<Self> {
453 start.checked_sub(n as Self)
454 }
455 }
456 )+
457 };
458}
459
460#[cfg(target_pointer_width = "64")]
461step_integer_impls! {
462 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize];
463 wider than usize: [u128 i128];
464}
465
466#[cfg(target_pointer_width = "32")]
467step_integer_impls! {
468 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize];
469 wider than usize: [u64 i64], [u128 i128];
470}
471
472#[cfg(target_pointer_width = "16")]
473step_integer_impls! {
474 narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize];
475 wider than usize: [u32 i32], [u64 i64], [u128 i128];
476}
477
478#[unstable(feature = "step_trait", issue = "42168")]
479#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
480impl const Step for char {
481 #[inline]
482 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
483 let start = start as u32;
484 let end = end as u32;
485 if start <= end {
486 let count = end - start;
487 if start < 0xD800 && 0xE000 <= end {
488 if let Ok(steps) = usize::try_from(count - 0x800) {
489 (steps, Some(steps))
490 } else {
491 (usize::MAX, None)
492 }
493 } else {
494 if let Ok(steps) = usize::try_from(count) {
495 (steps, Some(steps))
496 } else {
497 (usize::MAX, None)
498 }
499 }
500 } else {
501 (0, None)
502 }
503 }
504
505 #[inline]
506 fn forward_checked(start: char, count: usize) -> Option<char> {
507 let start = start as u32;
508 let mut res = Step::forward_checked(start, count)?;
509 if start < 0xD800 && 0xD800 <= res {
510 res = Step::forward_checked(res, 0x800)?;
511 }
512 if res <= char::MAX as u32 {
513 Some(unsafe { char::from_u32_unchecked(res) })
516 } else {
517 None
518 }
519 }
520
521 #[inline]
522 fn backward_checked(start: char, count: usize) -> Option<char> {
523 let start = start as u32;
524 let mut res = Step::backward_checked(start, count)?;
525 if start >= 0xE000 && 0xE000 > res {
526 res = Step::backward_checked(res, 0x800)?;
527 }
528 Some(unsafe { char::from_u32_unchecked(res) })
531 }
532
533 #[inline]
534 unsafe fn forward_unchecked(start: char, count: usize) -> char {
535 let start = start as u32;
536 let mut res = unsafe { Step::forward_unchecked(start, count) };
539 if start < 0xD800 && 0xD800 <= res {
540 res = unsafe { Step::forward_unchecked(res, 0x800) };
543 }
544 unsafe { char::from_u32_unchecked(res) }
547 }
548
549 #[inline]
550 unsafe fn backward_unchecked(start: char, count: usize) -> char {
551 let start = start as u32;
552 let mut res = unsafe { Step::backward_unchecked(start, count) };
555 if start >= 0xE000 && 0xE000 > res {
556 res = unsafe { Step::backward_unchecked(res, 0x800) };
559 }
560 unsafe { char::from_u32_unchecked(res) }
563 }
564}
565
566#[unstable(feature = "step_trait", issue = "42168")]
567#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
568impl const Step for AsciiChar {
569 #[inline]
570 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
571 Step::steps_between(&start.to_u8(), &end.to_u8())
572 }
573
574 #[inline]
575 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
576 let end = Step::forward_checked(start.to_u8(), count)?;
577 AsciiChar::from_u8(end)
578 }
579
580 #[inline]
581 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
582 let end = Step::backward_checked(start.to_u8(), count)?;
583
584 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
586 }
587
588 #[inline]
589 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
590 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
593
594 unsafe { AsciiChar::from_u8_unchecked(end) }
596 }
597
598 #[inline]
599 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
600 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
603
604 unsafe { AsciiChar::from_u8_unchecked(end) }
606 }
607}
608
609#[unstable(feature = "step_trait", issue = "42168")]
610#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
611impl const Step for Ipv4Addr {
612 #[inline]
613 fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
614 u32::steps_between(&start.to_bits(), &end.to_bits())
615 }
616
617 #[inline]
618 fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
619 u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
620 }
621
622 #[inline]
623 fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
624 u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
625 }
626
627 #[inline]
628 unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
629 Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
632 }
633
634 #[inline]
635 unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
636 Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
639 }
640}
641
642#[unstable(feature = "step_trait", issue = "42168")]
643#[rustc_const_unstable(feature = "step_trait", issue = "42168")]
644impl const Step for Ipv6Addr {
645 #[inline]
646 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
647 u128::steps_between(&start.to_bits(), &end.to_bits())
648 }
649
650 #[inline]
651 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
652 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
653 }
654
655 #[inline]
656 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
657 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
658 }
659
660 #[inline]
661 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
662 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
665 }
666
667 #[inline]
668 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
669 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
672 }
673}
674
675macro_rules! range_exact_iter_impl {
676 ($($t:ty)*) => ($(
677 #[stable(feature = "rust1", since = "1.0.0")]
678 impl ExactSizeIterator for ops::Range<$t> { }
679 )*)
680}
681
682macro_rules! unsafe_range_trusted_random_access_impl {
685 ($($t:ty)*) => ($(
686 #[doc(hidden)]
687 #[unstable(feature = "trusted_random_access", issue = "none")]
688 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
689
690 #[doc(hidden)]
691 #[unstable(feature = "trusted_random_access", issue = "none")]
692 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
693 const MAY_HAVE_SIDE_EFFECT: bool = false;
694 }
695 )*)
696}
697
698macro_rules! range_incl_exact_iter_impl {
699 ($($t:ty)*) => ($(
700 #[stable(feature = "inclusive_range", since = "1.26.0")]
701 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
702 )*)
703}
704
705trait RangeIteratorImpl {
707 type Item;
708
709 fn spec_next(&mut self) -> Option<Self::Item>;
711 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
712 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
713
714 fn spec_next_back(&mut self) -> Option<Self::Item>;
716 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
717 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
718}
719
720impl<A: Step> RangeIteratorImpl for ops::Range<A> {
721 type Item = A;
722
723 #[inline]
724 #[ferrocene::prevalidated]
725 default fn spec_next(&mut self) -> Option<A> {
726 if self.start < self.end {
727 let n =
728 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
729 Some(mem::replace(&mut self.start, n))
730 } else {
731 None
732 }
733 }
734
735 #[inline]
736 #[ferrocene::prevalidated]
737 default fn spec_nth(&mut self, n: usize) -> Option<A> {
738 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
739 if plus_n < self.end {
740 self.start =
741 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
742 return Some(plus_n);
743 }
744 }
745
746 self.start = self.end.clone();
747 None
748 }
749
750 #[inline]
751 #[ferrocene::prevalidated]
752 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
753 let steps = Step::steps_between(&self.start, &self.end);
754 let available = steps.1.unwrap_or(steps.0);
755
756 let taken = available.min(n);
757
758 self.start =
759 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
760
761 NonZero::new(n - taken).map_or(Ok(()), Err)
762 }
763
764 #[inline]
765 #[ferrocene::prevalidated]
766 default fn spec_next_back(&mut self) -> Option<A> {
767 if self.start < self.end {
768 self.end =
769 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
770 Some(self.end.clone())
771 } else {
772 None
773 }
774 }
775
776 #[inline]
777 #[ferrocene::prevalidated]
778 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
779 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
780 if minus_n > self.start {
781 self.end =
782 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
783 return Some(self.end.clone());
784 }
785 }
786
787 self.end = self.start.clone();
788 None
789 }
790
791 #[inline]
792 #[ferrocene::prevalidated]
793 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
794 let steps = Step::steps_between(&self.start, &self.end);
795 let available = steps.1.unwrap_or(steps.0);
796
797 let taken = available.min(n);
798
799 self.end =
800 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
801
802 NonZero::new(n - taken).map_or(Ok(()), Err)
803 }
804}
805
806impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
807 #[inline]
808 #[ferrocene::prevalidated]
809 fn spec_next(&mut self) -> Option<T> {
810 if self.start < self.end {
811 let old = self.start;
812 self.start = unsafe { Step::forward_unchecked(old, 1) };
814 Some(old)
815 } else {
816 None
817 }
818 }
819
820 #[inline]
821 #[ferrocene::prevalidated]
822 fn spec_nth(&mut self, n: usize) -> Option<T> {
823 if let Some(plus_n) = Step::forward_checked(self.start, n) {
824 if plus_n < self.end {
825 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
827 return Some(plus_n);
828 }
829 }
830
831 self.start = self.end;
832 None
833 }
834
835 #[inline]
836 #[ferrocene::prevalidated]
837 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
838 let steps = Step::steps_between(&self.start, &self.end);
839 let available = steps.1.unwrap_or(steps.0);
840
841 let taken = available.min(n);
842
843 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
848
849 NonZero::new(n - taken).map_or(Ok(()), Err)
850 }
851
852 #[inline]
853 #[ferrocene::prevalidated]
854 fn spec_next_back(&mut self) -> Option<T> {
855 if self.start < self.end {
856 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
858 Some(self.end)
859 } else {
860 None
861 }
862 }
863
864 #[inline]
865 #[ferrocene::prevalidated]
866 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
867 if let Some(minus_n) = Step::backward_checked(self.end, n) {
868 if minus_n > self.start {
869 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
871 return Some(self.end);
872 }
873 }
874
875 self.end = self.start;
876 None
877 }
878
879 #[inline]
880 #[ferrocene::prevalidated]
881 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
882 let steps = Step::steps_between(&self.start, &self.end);
883 let available = steps.1.unwrap_or(steps.0);
884
885 let taken = available.min(n);
886
887 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
889
890 NonZero::new(n - taken).map_or(Ok(()), Err)
891 }
892}
893
894#[stable(feature = "rust1", since = "1.0.0")]
895impl<A: Step> Iterator for ops::Range<A> {
896 type Item = A;
897
898 #[inline]
899 #[ferrocene::prevalidated]
900 fn next(&mut self) -> Option<A> {
901 self.spec_next()
902 }
903
904 #[inline]
905 #[ferrocene::prevalidated]
906 fn size_hint(&self) -> (usize, Option<usize>) {
907 if self.start < self.end {
908 Step::steps_between(&self.start, &self.end)
909 } else {
910 (0, Some(0))
911 }
912 }
913
914 #[inline]
915 #[ferrocene::prevalidated]
916 fn count(self) -> usize {
917 if self.start < self.end {
918 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
919 } else {
920 0
921 }
922 }
923
924 #[inline]
925 #[ferrocene::prevalidated]
926 fn nth(&mut self, n: usize) -> Option<A> {
927 self.spec_nth(n)
928 }
929
930 #[inline]
931 #[ferrocene::prevalidated]
932 fn last(mut self) -> Option<A> {
933 self.next_back()
934 }
935
936 #[inline]
937 fn min(mut self) -> Option<A>
938 where
939 A: Ord,
940 {
941 self.next()
942 }
943
944 #[inline]
945 fn max(mut self) -> Option<A>
946 where
947 A: Ord,
948 {
949 self.next_back()
950 }
951
952 #[inline]
953 fn is_sorted(self) -> bool {
954 true
955 }
956
957 #[inline]
958 #[ferrocene::prevalidated]
959 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
960 self.spec_advance_by(n)
961 }
962
963 #[inline]
964 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
965 where
966 Self: TrustedRandomAccessNoCoerce,
967 {
968 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
973 }
974}
975
976range_exact_iter_impl! {
985 usize u8 u16
986 isize i8 i16
987
988 u32
993 i32
994}
995
996unsafe_range_trusted_random_access_impl! {
997 usize u8 u16
998 isize i8 i16
999}
1000
1001#[cfg(target_pointer_width = "32")]
1002unsafe_range_trusted_random_access_impl! {
1003 u32 i32
1004}
1005
1006#[cfg(target_pointer_width = "64")]
1007unsafe_range_trusted_random_access_impl! {
1008 u32 i32
1009 u64 i64
1010}
1011
1012range_incl_exact_iter_impl! {
1013 u8
1014 i8
1015
1016 u16
1021 i16
1022}
1023
1024#[stable(feature = "rust1", since = "1.0.0")]
1025impl<A: Step> DoubleEndedIterator for ops::Range<A> {
1026 #[inline]
1027 #[ferrocene::prevalidated]
1028 fn next_back(&mut self) -> Option<A> {
1029 self.spec_next_back()
1030 }
1031
1032 #[inline]
1033 #[ferrocene::prevalidated]
1034 fn nth_back(&mut self, n: usize) -> Option<A> {
1035 self.spec_nth_back(n)
1036 }
1037
1038 #[inline]
1039 #[ferrocene::prevalidated]
1040 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1041 self.spec_advance_back_by(n)
1042 }
1043}
1044
1045#[unstable(feature = "trusted_len", issue = "37572")]
1065unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1066
1067#[stable(feature = "fused", since = "1.26.0")]
1068impl<A: Step> FusedIterator for ops::Range<A> {}
1069
1070#[stable(feature = "rust1", since = "1.0.0")]
1071impl<A: Step> Iterator for ops::RangeFrom<A> {
1072 type Item = A;
1073
1074 #[inline]
1075 fn next(&mut self) -> Option<A> {
1076 let n = Step::forward(self.start.clone(), 1);
1077 Some(mem::replace(&mut self.start, n))
1078 }
1079
1080 #[inline]
1081 fn size_hint(&self) -> (usize, Option<usize>) {
1082 (usize::MAX, None)
1083 }
1084
1085 #[inline]
1086 fn nth(&mut self, n: usize) -> Option<A> {
1087 let plus_n = Step::forward(self.start.clone(), n);
1088 self.start = Step::forward(plus_n.clone(), 1);
1089 Some(plus_n)
1090 }
1091}
1092
1093#[unstable(feature = "trusted_len", issue = "37572")]
1095unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1096
1097#[stable(feature = "fused", since = "1.26.0")]
1098impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1099
1100trait RangeInclusiveIteratorImpl {
1101 type Item;
1102
1103 fn spec_next(&mut self) -> Option<Self::Item>;
1105 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1106 where
1107 Self: Sized,
1108 F: FnMut(B, Self::Item) -> R,
1109 R: Try<Output = B>;
1110
1111 fn spec_next_back(&mut self) -> Option<Self::Item>;
1113 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1114 where
1115 Self: Sized,
1116 F: FnMut(B, Self::Item) -> R,
1117 R: Try<Output = B>;
1118}
1119
1120impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1121 type Item = A;
1122
1123 #[inline]
1124 #[ferrocene::prevalidated]
1125 default fn spec_next(&mut self) -> Option<A> {
1126 if self.is_empty() {
1127 return None;
1128 }
1129 let is_iterating = self.start < self.end;
1130 Some(if is_iterating {
1131 let n =
1132 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1133 mem::replace(&mut self.start, n)
1134 } else {
1135 self.exhausted = true;
1136 self.start.clone()
1137 })
1138 }
1139
1140 #[inline]
1141 #[ferrocene::prevalidated]
1142 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1143 where
1144 Self: Sized,
1145 F: FnMut(B, A) -> R,
1146 R: Try<Output = B>,
1147 {
1148 if self.is_empty() {
1149 return try { init };
1150 }
1151
1152 let mut accum = init;
1153
1154 while self.start < self.end {
1155 let n =
1156 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1157 let n = mem::replace(&mut self.start, n);
1158 accum = f(accum, n)?;
1159 }
1160
1161 self.exhausted = true;
1162
1163 if self.start == self.end {
1164 accum = f(accum, self.start.clone())?;
1165 }
1166
1167 try { accum }
1168 }
1169
1170 #[inline]
1171 #[ferrocene::prevalidated]
1172 default fn spec_next_back(&mut self) -> Option<A> {
1173 if self.is_empty() {
1174 return None;
1175 }
1176 let is_iterating = self.start < self.end;
1177 Some(if is_iterating {
1178 let n =
1179 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1180 mem::replace(&mut self.end, n)
1181 } else {
1182 self.exhausted = true;
1183 self.end.clone()
1184 })
1185 }
1186
1187 #[inline]
1188 #[ferrocene::prevalidated]
1189 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1190 where
1191 Self: Sized,
1192 F: FnMut(B, A) -> R,
1193 R: Try<Output = B>,
1194 {
1195 if self.is_empty() {
1196 return try { init };
1197 }
1198
1199 let mut accum = init;
1200
1201 while self.start < self.end {
1202 let n =
1203 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1204 let n = mem::replace(&mut self.end, n);
1205 accum = f(accum, n)?;
1206 }
1207
1208 self.exhausted = true;
1209
1210 if self.start == self.end {
1211 accum = f(accum, self.start.clone())?;
1212 }
1213
1214 try { accum }
1215 }
1216}
1217
1218impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1219 #[inline]
1220 #[ferrocene::prevalidated]
1221 fn spec_next(&mut self) -> Option<T> {
1222 if self.is_empty() {
1223 return None;
1224 }
1225 let is_iterating = self.start < self.end;
1226 Some(if is_iterating {
1227 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1229 mem::replace(&mut self.start, n)
1230 } else {
1231 self.exhausted = true;
1232 self.start
1233 })
1234 }
1235
1236 #[inline]
1237 #[ferrocene::prevalidated]
1238 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1239 where
1240 Self: Sized,
1241 F: FnMut(B, T) -> R,
1242 R: Try<Output = B>,
1243 {
1244 if self.is_empty() {
1245 return try { init };
1246 }
1247
1248 let mut accum = init;
1249
1250 while self.start < self.end {
1251 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1253 let n = mem::replace(&mut self.start, n);
1254 accum = f(accum, n)?;
1255 }
1256
1257 self.exhausted = true;
1258
1259 if self.start == self.end {
1260 accum = f(accum, self.start)?;
1261 }
1262
1263 try { accum }
1264 }
1265
1266 #[inline]
1267 #[ferrocene::prevalidated]
1268 fn spec_next_back(&mut self) -> Option<T> {
1269 if self.is_empty() {
1270 return None;
1271 }
1272 let is_iterating = self.start < self.end;
1273 Some(if is_iterating {
1274 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1276 mem::replace(&mut self.end, n)
1277 } else {
1278 self.exhausted = true;
1279 self.end
1280 })
1281 }
1282
1283 #[inline]
1284 #[ferrocene::prevalidated]
1285 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1286 where
1287 Self: Sized,
1288 F: FnMut(B, T) -> R,
1289 R: Try<Output = B>,
1290 {
1291 if self.is_empty() {
1292 return try { init };
1293 }
1294
1295 let mut accum = init;
1296
1297 while self.start < self.end {
1298 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1300 let n = mem::replace(&mut self.end, n);
1301 accum = f(accum, n)?;
1302 }
1303
1304 self.exhausted = true;
1305
1306 if self.start == self.end {
1307 accum = f(accum, self.start)?;
1308 }
1309
1310 try { accum }
1311 }
1312}
1313
1314#[stable(feature = "inclusive_range", since = "1.26.0")]
1315impl<A: Step> Iterator for ops::RangeInclusive<A> {
1316 type Item = A;
1317
1318 #[inline]
1319 #[ferrocene::prevalidated]
1320 fn next(&mut self) -> Option<A> {
1321 self.spec_next()
1322 }
1323
1324 #[inline]
1325 #[ferrocene::prevalidated]
1326 fn size_hint(&self) -> (usize, Option<usize>) {
1327 if self.is_empty() {
1328 return (0, Some(0));
1329 }
1330
1331 let hint = Step::steps_between(&self.start, &self.end);
1332 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1333 }
1334
1335 #[inline]
1336 #[ferrocene::prevalidated]
1337 fn count(self) -> usize {
1338 if self.is_empty() {
1339 return 0;
1340 }
1341
1342 Step::steps_between(&self.start, &self.end)
1343 .1
1344 .and_then(|steps| steps.checked_add(1))
1345 .expect("count overflowed usize")
1346 }
1347
1348 #[inline]
1349 #[ferrocene::prevalidated]
1350 fn nth(&mut self, n: usize) -> Option<A> {
1351 if self.is_empty() {
1352 return None;
1353 }
1354
1355 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1356 use crate::cmp::Ordering::*;
1357
1358 match plus_n.partial_cmp(&self.end) {
1359 Some(Less) => {
1360 self.start = Step::forward(plus_n.clone(), 1);
1361 return Some(plus_n);
1362 }
1363 Some(Equal) => {
1364 self.start = plus_n.clone();
1365 self.exhausted = true;
1366 return Some(plus_n);
1367 }
1368 _ => {}
1369 }
1370 }
1371
1372 self.start = self.end.clone();
1373 self.exhausted = true;
1374 None
1375 }
1376
1377 #[inline]
1378 #[ferrocene::prevalidated]
1379 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1380 where
1381 Self: Sized,
1382 F: FnMut(B, Self::Item) -> R,
1383 R: Try<Output = B>,
1384 {
1385 self.spec_try_fold(init, f)
1386 }
1387
1388 impl_fold_via_try_fold! { fold -> try_fold }
1389
1390 #[inline]
1391 #[ferrocene::prevalidated]
1392 fn last(mut self) -> Option<A> {
1393 self.next_back()
1394 }
1395
1396 #[inline]
1397 fn min(mut self) -> Option<A>
1398 where
1399 A: Ord,
1400 {
1401 self.next()
1402 }
1403
1404 #[inline]
1405 fn max(mut self) -> Option<A>
1406 where
1407 A: Ord,
1408 {
1409 self.next_back()
1410 }
1411
1412 #[inline]
1413 fn is_sorted(self) -> bool {
1414 true
1415 }
1416}
1417
1418#[stable(feature = "inclusive_range", since = "1.26.0")]
1419impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1420 #[inline]
1421 #[ferrocene::prevalidated]
1422 fn next_back(&mut self) -> Option<A> {
1423 self.spec_next_back()
1424 }
1425
1426 #[inline]
1427 #[ferrocene::prevalidated]
1428 fn nth_back(&mut self, n: usize) -> Option<A> {
1429 if self.is_empty() {
1430 return None;
1431 }
1432
1433 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1434 use crate::cmp::Ordering::*;
1435
1436 match minus_n.partial_cmp(&self.start) {
1437 Some(Greater) => {
1438 self.end = Step::backward(minus_n.clone(), 1);
1439 return Some(minus_n);
1440 }
1441 Some(Equal) => {
1442 self.end = minus_n.clone();
1443 self.exhausted = true;
1444 return Some(minus_n);
1445 }
1446 _ => {}
1447 }
1448 }
1449
1450 self.end = self.start.clone();
1451 self.exhausted = true;
1452 None
1453 }
1454
1455 #[inline]
1456 #[ferrocene::prevalidated]
1457 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1458 where
1459 Self: Sized,
1460 F: FnMut(B, Self::Item) -> R,
1461 R: Try<Output = B>,
1462 {
1463 self.spec_try_rfold(init, f)
1464 }
1465
1466 impl_fold_via_try_fold! { rfold -> try_rfold }
1467}
1468
1469#[unstable(feature = "trusted_len", issue = "37572")]
1471unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1472
1473#[stable(feature = "fused", since = "1.26.0")]
1474impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}