1#[cfg(not(feature = "ferrocene_certified"))]
2use super::{
3 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
4};
5#[cfg(not(feature = "ferrocene_certified"))]
6use crate::ascii::Char as AsciiChar;
7use crate::mem;
8#[cfg(not(feature = "ferrocene_certified"))]
9use crate::net::{Ipv4Addr, Ipv6Addr};
10use crate::num::NonZero;
11#[cfg(not(feature = "ferrocene_certified"))]
12use crate::ops::{self, Try};
13
14#[cfg(feature = "ferrocene_certified")]
16#[rustfmt::skip]
17use crate::ops;
18
19#[cfg(not(feature = "ferrocene_certified"))]
21macro_rules! unsafe_impl_trusted_step {
22 ($($type:ty)*) => {$(
23 #[unstable(feature = "trusted_step", issue = "85731")]
24 unsafe impl TrustedStep for $type {}
25 )*};
26}
27#[cfg(not(feature = "ferrocene_certified"))]
28unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];
29
30#[rustc_diagnostic_item = "range_step"]
35#[unstable(feature = "step_trait", issue = "42168")]
36pub trait Step: Clone + PartialOrd + Sized {
37 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
52
53 fn forward_checked(start: Self, count: usize) -> Option<Self>;
70
71 #[cfg(not(feature = "ferrocene_certified"))]
95 fn forward(start: Self, count: usize) -> Self {
96 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
97 }
98
99 #[cfg(not(feature = "ferrocene_certified"))]
121 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
122 Step::forward(start, count)
123 }
124
125 fn backward_checked(start: Self, count: usize) -> Option<Self>;
142
143 #[cfg(not(feature = "ferrocene_certified"))]
167 fn backward(start: Self, count: usize) -> Self {
168 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
169 }
170
171 #[cfg(not(feature = "ferrocene_certified"))]
193 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
194 Step::backward(start, count)
195 }
196}
197
198#[cfg(not(feature = "ferrocene_certified"))]
201macro_rules! step_signed_methods {
202 ($unsigned: ty) => {
203 #[inline]
204 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
205 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
207 }
208
209 #[inline]
210 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
211 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
213 }
214 };
215}
216
217#[cfg(not(feature = "ferrocene_certified"))]
218macro_rules! step_unsigned_methods {
219 () => {
220 #[inline]
221 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
222 unsafe { start.unchecked_add(n as Self) }
224 }
225
226 #[inline]
227 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
228 unsafe { start.unchecked_sub(n as Self) }
230 }
231 };
232}
233
234#[cfg(not(feature = "ferrocene_certified"))]
236macro_rules! step_identical_methods {
237 () => {
238 #[inline]
239 #[allow(arithmetic_overflow)]
240 #[rustc_inherit_overflow_checks]
241 fn forward(start: Self, n: usize) -> Self {
242 if Self::forward_checked(start, n).is_none() {
245 let _ = Self::MAX + 1;
246 }
247 start.wrapping_add(n as Self)
249 }
250
251 #[inline]
252 #[allow(arithmetic_overflow)]
253 #[rustc_inherit_overflow_checks]
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", reason = "recently redesigned", issue = "42168")]
276 impl Step for $u_narrower {
277 #[cfg(not(feature = "ferrocene_certified"))]
278 step_identical_methods!();
279 #[cfg(not(feature = "ferrocene_certified"))]
280 step_unsigned_methods!();
281
282 #[inline]
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 fn forward_checked(start: Self, n: usize) -> Option<Self> {
295 match Self::try_from(n) {
296 Ok(n) => start.checked_add(n),
297 Err(_) => None, }
299 }
300
301 #[inline]
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", reason = "recently redesigned", issue = "42168")]
312 impl Step for $i_narrower {
313 #[cfg(not(feature = "ferrocene_certified"))]
314 step_identical_methods!();
315 #[cfg(not(feature = "ferrocene_certified"))]
316 step_signed_methods!($u_narrower);
317
318 #[inline]
319 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
320 if *start <= *end {
321 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
327 (steps, Some(steps))
328 } else {
329 (0, None)
330 }
331 }
332
333 #[inline]
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 fn backward_checked(start: Self, n: usize) -> Option<Self> {
356 match $u_narrower::try_from(n) {
357 Ok(n) => {
358 let wrapped = start.wrapping_sub(n as Self);
362 if wrapped <= start {
363 Some(wrapped)
364 } else {
365 None }
367 }
368 Err(_) => None,
372 }
373 }
374 }
375 )+
376
377 $(
378 #[allow(unreachable_patterns)]
379 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
380 impl Step for $u_wider {
381 #[cfg(not(feature = "ferrocene_certified"))]
382 step_identical_methods!();
383 #[cfg(not(feature = "ferrocene_certified"))]
384 step_unsigned_methods!();
385
386 #[inline]
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 fn forward_checked(start: Self, n: usize) -> Option<Self> {
401 start.checked_add(n as Self)
402 }
403
404 #[inline]
405 fn backward_checked(start: Self, n: usize) -> Option<Self> {
406 start.checked_sub(n as Self)
407 }
408 }
409
410 #[allow(unreachable_patterns)]
411 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
412 impl Step for $i_wider {
413 #[cfg(not(feature = "ferrocene_certified"))]
414 step_identical_methods!();
415 #[cfg(not(feature = "ferrocene_certified"))]
416 step_signed_methods!($u_wider);
417
418 #[inline]
419 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
420 if *start <= *end {
421 match end.checked_sub(*start) {
422 Some(result) => {
423 if let Ok(steps) = usize::try_from(result) {
424 (steps, Some(steps))
425 } else {
426 (usize::MAX, None)
427 }
428 }
429 None => (usize::MAX, None),
432 }
433 } else {
434 (0, None)
435 }
436 }
437
438 #[inline]
439 fn forward_checked(start: Self, n: usize) -> Option<Self> {
440 start.checked_add(n as Self)
441 }
442
443 #[inline]
444 fn backward_checked(start: Self, n: usize) -> Option<Self> {
445 start.checked_sub(n as Self)
446 }
447 }
448 )+
449 };
450}
451
452#[cfg(target_pointer_width = "64")]
453step_integer_impls! {
454 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize];
455 wider than usize: [u128 i128];
456}
457
458#[cfg(target_pointer_width = "32")]
459step_integer_impls! {
460 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize];
461 wider than usize: [u64 i64], [u128 i128];
462}
463
464#[cfg(target_pointer_width = "16")]
465step_integer_impls! {
466 narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize];
467 wider than usize: [u32 i32], [u64 i64], [u128 i128];
468}
469
470#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
471#[cfg(not(feature = "ferrocene_certified"))]
472impl Step for char {
473 #[inline]
474 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
475 let start = start as u32;
476 let end = end as u32;
477 if start <= end {
478 let count = end - start;
479 if start < 0xD800 && 0xE000 <= end {
480 if let Ok(steps) = usize::try_from(count - 0x800) {
481 (steps, Some(steps))
482 } else {
483 (usize::MAX, None)
484 }
485 } else {
486 if let Ok(steps) = usize::try_from(count) {
487 (steps, Some(steps))
488 } else {
489 (usize::MAX, None)
490 }
491 }
492 } else {
493 (0, None)
494 }
495 }
496
497 #[inline]
498 fn forward_checked(start: char, count: usize) -> Option<char> {
499 let start = start as u32;
500 let mut res = Step::forward_checked(start, count)?;
501 if start < 0xD800 && 0xD800 <= res {
502 res = Step::forward_checked(res, 0x800)?;
503 }
504 if res <= char::MAX as u32 {
505 Some(unsafe { char::from_u32_unchecked(res) })
508 } else {
509 None
510 }
511 }
512
513 #[inline]
514 fn backward_checked(start: char, count: usize) -> Option<char> {
515 let start = start as u32;
516 let mut res = Step::backward_checked(start, count)?;
517 if start >= 0xE000 && 0xE000 > res {
518 res = Step::backward_checked(res, 0x800)?;
519 }
520 Some(unsafe { char::from_u32_unchecked(res) })
523 }
524
525 #[inline]
526 unsafe fn forward_unchecked(start: char, count: usize) -> char {
527 let start = start as u32;
528 let mut res = unsafe { Step::forward_unchecked(start, count) };
531 if start < 0xD800 && 0xD800 <= res {
532 res = unsafe { Step::forward_unchecked(res, 0x800) };
535 }
536 unsafe { char::from_u32_unchecked(res) }
539 }
540
541 #[inline]
542 unsafe fn backward_unchecked(start: char, count: usize) -> char {
543 let start = start as u32;
544 let mut res = unsafe { Step::backward_unchecked(start, count) };
547 if start >= 0xE000 && 0xE000 > res {
548 res = unsafe { Step::backward_unchecked(res, 0x800) };
551 }
552 unsafe { char::from_u32_unchecked(res) }
555 }
556}
557
558#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
559#[cfg(not(feature = "ferrocene_certified"))]
560impl Step for AsciiChar {
561 #[inline]
562 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
563 Step::steps_between(&start.to_u8(), &end.to_u8())
564 }
565
566 #[inline]
567 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
568 let end = Step::forward_checked(start.to_u8(), count)?;
569 AsciiChar::from_u8(end)
570 }
571
572 #[inline]
573 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
574 let end = Step::backward_checked(start.to_u8(), count)?;
575
576 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
578 }
579
580 #[inline]
581 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
582 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
585
586 unsafe { AsciiChar::from_u8_unchecked(end) }
588 }
589
590 #[inline]
591 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
592 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
595
596 unsafe { AsciiChar::from_u8_unchecked(end) }
598 }
599}
600
601#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
602#[cfg(not(feature = "ferrocene_certified"))]
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", reason = "recently redesigned", issue = "42168")]
635#[cfg(not(feature = "ferrocene_certified"))]
636impl Step for Ipv6Addr {
637 #[inline]
638 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
639 u128::steps_between(&start.to_bits(), &end.to_bits())
640 }
641
642 #[inline]
643 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
644 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
645 }
646
647 #[inline]
648 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
649 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
650 }
651
652 #[inline]
653 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
654 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
657 }
658
659 #[inline]
660 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
661 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
664 }
665}
666
667#[cfg(not(feature = "ferrocene_certified"))]
668macro_rules! range_exact_iter_impl {
669 ($($t:ty)*) => ($(
670 #[stable(feature = "rust1", since = "1.0.0")]
671 impl ExactSizeIterator for ops::Range<$t> { }
672 )*)
673}
674
675#[cfg(not(feature = "ferrocene_certified"))]
678macro_rules! unsafe_range_trusted_random_access_impl {
679 ($($t:ty)*) => ($(
680 #[doc(hidden)]
681 #[unstable(feature = "trusted_random_access", issue = "none")]
682 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
683
684 #[doc(hidden)]
685 #[unstable(feature = "trusted_random_access", issue = "none")]
686 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
687 const MAY_HAVE_SIDE_EFFECT: bool = false;
688 }
689 )*)
690}
691
692#[cfg(not(feature = "ferrocene_certified"))]
693macro_rules! range_incl_exact_iter_impl {
694 ($($t:ty)*) => ($(
695 #[stable(feature = "inclusive_range", since = "1.26.0")]
696 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
697 )*)
698}
699
700trait RangeIteratorImpl {
702 type Item;
703
704 fn spec_next(&mut self) -> Option<Self::Item>;
706 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
707 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
708
709 fn spec_next_back(&mut self) -> Option<Self::Item>;
711 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
712 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
713}
714
715impl<A: Step> RangeIteratorImpl for ops::Range<A> {
716 type Item = A;
717
718 #[inline]
719 default fn spec_next(&mut self) -> Option<A> {
720 if self.start < self.end {
721 let n =
722 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
723 Some(mem::replace(&mut self.start, n))
724 } else {
725 None
726 }
727 }
728
729 #[inline]
730 default fn spec_nth(&mut self, n: usize) -> Option<A> {
731 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
732 if plus_n < self.end {
733 self.start =
734 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
735 return Some(plus_n);
736 }
737 }
738
739 self.start = self.end.clone();
740 None
741 }
742
743 #[inline]
744 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
745 let steps = Step::steps_between(&self.start, &self.end);
746 let available = steps.1.unwrap_or(steps.0);
747
748 let taken = available.min(n);
749
750 self.start =
751 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
752
753 NonZero::new(n - taken).map_or(Ok(()), Err)
754 }
755
756 #[inline]
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 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
769 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
770 if minus_n > self.start {
771 self.end =
772 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
773 return Some(self.end.clone());
774 }
775 }
776
777 self.end = self.start.clone();
778 None
779 }
780
781 #[inline]
782 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
783 let steps = Step::steps_between(&self.start, &self.end);
784 let available = steps.1.unwrap_or(steps.0);
785
786 let taken = available.min(n);
787
788 self.end =
789 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
790
791 NonZero::new(n - taken).map_or(Ok(()), Err)
792 }
793}
794
795#[cfg(not(feature = "ferrocene_certified"))]
796impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
797 #[inline]
798 fn spec_next(&mut self) -> Option<T> {
799 if self.start < self.end {
800 let old = self.start;
801 self.start = unsafe { Step::forward_unchecked(old, 1) };
803 Some(old)
804 } else {
805 None
806 }
807 }
808
809 #[inline]
810 fn spec_nth(&mut self, n: usize) -> Option<T> {
811 if let Some(plus_n) = Step::forward_checked(self.start, n) {
812 if plus_n < self.end {
813 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
815 return Some(plus_n);
816 }
817 }
818
819 self.start = self.end;
820 None
821 }
822
823 #[inline]
824 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
825 let steps = Step::steps_between(&self.start, &self.end);
826 let available = steps.1.unwrap_or(steps.0);
827
828 let taken = available.min(n);
829
830 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
835
836 NonZero::new(n - taken).map_or(Ok(()), Err)
837 }
838
839 #[inline]
840 fn spec_next_back(&mut self) -> Option<T> {
841 if self.start < self.end {
842 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
844 Some(self.end)
845 } else {
846 None
847 }
848 }
849
850 #[inline]
851 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
852 if let Some(minus_n) = Step::backward_checked(self.end, n) {
853 if minus_n > self.start {
854 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
856 return Some(self.end);
857 }
858 }
859
860 self.end = self.start;
861 None
862 }
863
864 #[inline]
865 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
866 let steps = Step::steps_between(&self.start, &self.end);
867 let available = steps.1.unwrap_or(steps.0);
868
869 let taken = available.min(n);
870
871 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
873
874 NonZero::new(n - taken).map_or(Ok(()), Err)
875 }
876}
877
878#[stable(feature = "rust1", since = "1.0.0")]
879impl<A: Step> Iterator for ops::Range<A> {
880 type Item = A;
881
882 #[inline]
883 fn next(&mut self) -> Option<A> {
884 self.spec_next()
885 }
886
887 #[inline]
888 fn size_hint(&self) -> (usize, Option<usize>) {
889 if self.start < self.end {
890 Step::steps_between(&self.start, &self.end)
891 } else {
892 (0, Some(0))
893 }
894 }
895
896 #[inline]
897 #[cfg(not(feature = "ferrocene_certified"))]
898 fn count(self) -> usize {
899 if self.start < self.end {
900 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
901 } else {
902 0
903 }
904 }
905
906 #[inline]
907 fn nth(&mut self, n: usize) -> Option<A> {
908 self.spec_nth(n)
909 }
910
911 #[inline]
912 #[cfg(not(feature = "ferrocene_certified"))]
913 fn last(mut self) -> Option<A> {
914 self.next_back()
915 }
916
917 #[inline]
918 #[cfg(not(feature = "ferrocene_certified"))]
919 fn min(mut self) -> Option<A>
920 where
921 A: Ord,
922 {
923 self.next()
924 }
925
926 #[inline]
927 #[cfg(not(feature = "ferrocene_certified"))]
928 fn max(mut self) -> Option<A>
929 where
930 A: Ord,
931 {
932 self.next_back()
933 }
934
935 #[inline]
936 #[cfg(not(feature = "ferrocene_certified"))]
937 fn is_sorted(self) -> bool {
938 true
939 }
940
941 #[inline]
942 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
943 self.spec_advance_by(n)
944 }
945
946 #[inline]
947 #[cfg(not(feature = "ferrocene_certified"))]
948 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
949 where
950 Self: TrustedRandomAccessNoCoerce,
951 {
952 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
957 }
958}
959
960#[cfg(not(feature = "ferrocene_certified"))]
969range_exact_iter_impl! {
970 usize u8 u16
971 isize i8 i16
972
973 u32
978 i32
979}
980
981#[cfg(not(feature = "ferrocene_certified"))]
982unsafe_range_trusted_random_access_impl! {
983 usize u8 u16
984 isize i8 i16
985}
986
987#[cfg(target_pointer_width = "32")]
988#[cfg(not(feature = "ferrocene_certified"))]
989unsafe_range_trusted_random_access_impl! {
990 u32 i32
991}
992
993#[cfg(target_pointer_width = "64")]
994#[cfg(not(feature = "ferrocene_certified"))]
995unsafe_range_trusted_random_access_impl! {
996 u32 i32
997 u64 i64
998}
999
1000#[cfg(not(feature = "ferrocene_certified"))]
1001range_incl_exact_iter_impl! {
1002 u8
1003 i8
1004
1005 u16
1010 i16
1011}
1012
1013#[stable(feature = "rust1", since = "1.0.0")]
1014impl<A: Step> DoubleEndedIterator for ops::Range<A> {
1015 #[inline]
1016 fn next_back(&mut self) -> Option<A> {
1017 self.spec_next_back()
1018 }
1019
1020 #[inline]
1021 fn nth_back(&mut self, n: usize) -> Option<A> {
1022 self.spec_nth_back(n)
1023 }
1024
1025 #[inline]
1026 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1027 self.spec_advance_back_by(n)
1028 }
1029}
1030
1031#[unstable(feature = "trusted_len", issue = "37572")]
1051#[cfg(not(feature = "ferrocene_certified"))]
1052unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1053
1054#[stable(feature = "fused", since = "1.26.0")]
1055#[cfg(not(feature = "ferrocene_certified"))]
1056impl<A: Step> FusedIterator for ops::Range<A> {}
1057
1058#[stable(feature = "rust1", since = "1.0.0")]
1059#[cfg(not(feature = "ferrocene_certified"))]
1060impl<A: Step> Iterator for ops::RangeFrom<A> {
1061 type Item = A;
1062
1063 #[inline]
1064 fn next(&mut self) -> Option<A> {
1065 let n = Step::forward(self.start.clone(), 1);
1066 Some(mem::replace(&mut self.start, n))
1067 }
1068
1069 #[inline]
1070 fn size_hint(&self) -> (usize, Option<usize>) {
1071 (usize::MAX, None)
1072 }
1073
1074 #[inline]
1075 fn nth(&mut self, n: usize) -> Option<A> {
1076 let plus_n = Step::forward(self.start.clone(), n);
1077 self.start = Step::forward(plus_n.clone(), 1);
1078 Some(plus_n)
1079 }
1080}
1081
1082#[unstable(feature = "trusted_len", issue = "37572")]
1084#[cfg(not(feature = "ferrocene_certified"))]
1085unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1086
1087#[stable(feature = "fused", since = "1.26.0")]
1088#[cfg(not(feature = "ferrocene_certified"))]
1089impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1090
1091#[cfg(not(feature = "ferrocene_certified"))]
1092trait RangeInclusiveIteratorImpl {
1093 type Item;
1094
1095 fn spec_next(&mut self) -> Option<Self::Item>;
1097 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1098 where
1099 Self: Sized,
1100 F: FnMut(B, Self::Item) -> R,
1101 R: Try<Output = B>;
1102
1103 fn spec_next_back(&mut self) -> Option<Self::Item>;
1105 fn spec_try_rfold<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
1112#[cfg(not(feature = "ferrocene_certified"))]
1113impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1114 type Item = A;
1115
1116 #[inline]
1117 default fn spec_next(&mut self) -> Option<A> {
1118 if self.is_empty() {
1119 return None;
1120 }
1121 let is_iterating = self.start < self.end;
1122 Some(if is_iterating {
1123 let n =
1124 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1125 mem::replace(&mut self.start, n)
1126 } else {
1127 self.exhausted = true;
1128 self.start.clone()
1129 })
1130 }
1131
1132 #[inline]
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 default fn spec_next_back(&mut self) -> Option<A> {
1163 if self.is_empty() {
1164 return None;
1165 }
1166 let is_iterating = self.start < self.end;
1167 Some(if is_iterating {
1168 let n =
1169 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1170 mem::replace(&mut self.end, n)
1171 } else {
1172 self.exhausted = true;
1173 self.end.clone()
1174 })
1175 }
1176
1177 #[inline]
1178 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1179 where
1180 Self: Sized,
1181 F: FnMut(B, A) -> R,
1182 R: Try<Output = B>,
1183 {
1184 if self.is_empty() {
1185 return try { init };
1186 }
1187
1188 let mut accum = init;
1189
1190 while self.start < self.end {
1191 let n =
1192 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1193 let n = mem::replace(&mut self.end, n);
1194 accum = f(accum, n)?;
1195 }
1196
1197 self.exhausted = true;
1198
1199 if self.start == self.end {
1200 accum = f(accum, self.start.clone())?;
1201 }
1202
1203 try { accum }
1204 }
1205}
1206
1207#[cfg(not(feature = "ferrocene_certified"))]
1208impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1209 #[inline]
1210 fn spec_next(&mut self) -> Option<T> {
1211 if self.is_empty() {
1212 return None;
1213 }
1214 let is_iterating = self.start < self.end;
1215 Some(if is_iterating {
1216 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1218 mem::replace(&mut self.start, n)
1219 } else {
1220 self.exhausted = true;
1221 self.start
1222 })
1223 }
1224
1225 #[inline]
1226 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1227 where
1228 Self: Sized,
1229 F: FnMut(B, T) -> R,
1230 R: Try<Output = B>,
1231 {
1232 if self.is_empty() {
1233 return try { init };
1234 }
1235
1236 let mut accum = init;
1237
1238 while self.start < self.end {
1239 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1241 let n = mem::replace(&mut self.start, n);
1242 accum = f(accum, n)?;
1243 }
1244
1245 self.exhausted = true;
1246
1247 if self.start == self.end {
1248 accum = f(accum, self.start)?;
1249 }
1250
1251 try { accum }
1252 }
1253
1254 #[inline]
1255 fn spec_next_back(&mut self) -> Option<T> {
1256 if self.is_empty() {
1257 return None;
1258 }
1259 let is_iterating = self.start < self.end;
1260 Some(if is_iterating {
1261 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1263 mem::replace(&mut self.end, n)
1264 } else {
1265 self.exhausted = true;
1266 self.end
1267 })
1268 }
1269
1270 #[inline]
1271 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1272 where
1273 Self: Sized,
1274 F: FnMut(B, T) -> R,
1275 R: Try<Output = B>,
1276 {
1277 if self.is_empty() {
1278 return try { init };
1279 }
1280
1281 let mut accum = init;
1282
1283 while self.start < self.end {
1284 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1286 let n = mem::replace(&mut self.end, n);
1287 accum = f(accum, n)?;
1288 }
1289
1290 self.exhausted = true;
1291
1292 if self.start == self.end {
1293 accum = f(accum, self.start)?;
1294 }
1295
1296 try { accum }
1297 }
1298}
1299
1300#[stable(feature = "inclusive_range", since = "1.26.0")]
1301#[cfg(not(feature = "ferrocene_certified"))]
1302impl<A: Step> Iterator for ops::RangeInclusive<A> {
1303 type Item = A;
1304
1305 #[inline]
1306 fn next(&mut self) -> Option<A> {
1307 self.spec_next()
1308 }
1309
1310 #[inline]
1311 fn size_hint(&self) -> (usize, Option<usize>) {
1312 if self.is_empty() {
1313 return (0, Some(0));
1314 }
1315
1316 let hint = Step::steps_between(&self.start, &self.end);
1317 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1318 }
1319
1320 #[inline]
1321 fn count(self) -> usize {
1322 if self.is_empty() {
1323 return 0;
1324 }
1325
1326 Step::steps_between(&self.start, &self.end)
1327 .1
1328 .and_then(|steps| steps.checked_add(1))
1329 .expect("count overflowed usize")
1330 }
1331
1332 #[inline]
1333 fn nth(&mut self, n: usize) -> Option<A> {
1334 if self.is_empty() {
1335 return None;
1336 }
1337
1338 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1339 use crate::cmp::Ordering::*;
1340
1341 match plus_n.partial_cmp(&self.end) {
1342 Some(Less) => {
1343 self.start = Step::forward(plus_n.clone(), 1);
1344 return Some(plus_n);
1345 }
1346 Some(Equal) => {
1347 self.start = plus_n.clone();
1348 self.exhausted = true;
1349 return Some(plus_n);
1350 }
1351 _ => {}
1352 }
1353 }
1354
1355 self.start = self.end.clone();
1356 self.exhausted = true;
1357 None
1358 }
1359
1360 #[inline]
1361 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1362 where
1363 Self: Sized,
1364 F: FnMut(B, Self::Item) -> R,
1365 R: Try<Output = B>,
1366 {
1367 self.spec_try_fold(init, f)
1368 }
1369
1370 impl_fold_via_try_fold! { fold -> try_fold }
1371
1372 #[inline]
1373 fn last(mut self) -> Option<A> {
1374 self.next_back()
1375 }
1376
1377 #[inline]
1378 fn min(mut self) -> Option<A>
1379 where
1380 A: Ord,
1381 {
1382 self.next()
1383 }
1384
1385 #[inline]
1386 fn max(mut self) -> Option<A>
1387 where
1388 A: Ord,
1389 {
1390 self.next_back()
1391 }
1392
1393 #[inline]
1394 fn is_sorted(self) -> bool {
1395 true
1396 }
1397}
1398
1399#[stable(feature = "inclusive_range", since = "1.26.0")]
1400#[cfg(not(feature = "ferrocene_certified"))]
1401impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1402 #[inline]
1403 fn next_back(&mut self) -> Option<A> {
1404 self.spec_next_back()
1405 }
1406
1407 #[inline]
1408 fn nth_back(&mut self, n: usize) -> Option<A> {
1409 if self.is_empty() {
1410 return None;
1411 }
1412
1413 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1414 use crate::cmp::Ordering::*;
1415
1416 match minus_n.partial_cmp(&self.start) {
1417 Some(Greater) => {
1418 self.end = Step::backward(minus_n.clone(), 1);
1419 return Some(minus_n);
1420 }
1421 Some(Equal) => {
1422 self.end = minus_n.clone();
1423 self.exhausted = true;
1424 return Some(minus_n);
1425 }
1426 _ => {}
1427 }
1428 }
1429
1430 self.end = self.start.clone();
1431 self.exhausted = true;
1432 None
1433 }
1434
1435 #[inline]
1436 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1437 where
1438 Self: Sized,
1439 F: FnMut(B, Self::Item) -> R,
1440 R: Try<Output = B>,
1441 {
1442 self.spec_try_rfold(init, f)
1443 }
1444
1445 impl_fold_via_try_fold! { rfold -> try_rfold }
1446}
1447
1448#[unstable(feature = "trusted_len", issue = "37572")]
1450#[cfg(not(feature = "ferrocene_certified"))]
1451unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1452
1453#[stable(feature = "fused", since = "1.26.0")]
1454#[cfg(not(feature = "ferrocene_certified"))]
1455impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}