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