1#[cfg(not(feature = "ferrocene_subset"))]
2use super::{
3 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
4};
5#[cfg(not(feature = "ferrocene_subset"))]
6use crate::ascii::Char as AsciiChar;
7use crate::mem;
8#[cfg(not(feature = "ferrocene_subset"))]
9use crate::net::{Ipv4Addr, Ipv6Addr};
10use crate::num::NonZero;
11use crate::ops::{self, Try};
12
13#[cfg(feature = "ferrocene_subset")]
15#[rustfmt::skip]
16use super::TrustedStep;
17
18#[cfg(not(feature = "ferrocene_subset"))]
20macro_rules! unsafe_impl_trusted_step {
21 ($($type:ty)*) => {$(
22 #[unstable(feature = "trusted_step", issue = "85731")]
23 unsafe impl TrustedStep for $type {}
24 )*};
25}
26#[cfg(not(feature = "ferrocene_subset"))]
27unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];
28
29#[rustc_diagnostic_item = "range_step"]
34#[unstable(feature = "step_trait", issue = "42168")]
35pub trait Step: Clone + PartialOrd + Sized {
36 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
51
52 fn forward_checked(start: Self, count: usize) -> Option<Self>;
69
70 fn forward(start: Self, count: usize) -> Self {
94 Step::forward_checked(start, count).expect("overflow in `Step::forward`")
95 }
96
97 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 fn backward(start: Self, count: usize) -> Self {
164 Step::backward_checked(start, count).expect("overflow in `Step::backward`")
165 }
166
167 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
189 Step::backward(start, count)
190 }
191}
192
193macro_rules! step_signed_methods {
196 ($unsigned: ty) => {
197 #[inline]
198 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
199 unsafe { start.checked_add_unsigned(n as $unsigned).unwrap_unchecked() }
201 }
202
203 #[inline]
204 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
205 unsafe { start.checked_sub_unsigned(n as $unsigned).unwrap_unchecked() }
207 }
208 };
209}
210
211macro_rules! step_unsigned_methods {
212 () => {
213 #[inline]
214 unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
215 unsafe { start.unchecked_add(n as Self) }
217 }
218
219 #[inline]
220 unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
221 unsafe { start.unchecked_sub(n as Self) }
223 }
224 };
225}
226
227macro_rules! step_identical_methods {
229 () => {
230 #[inline]
231 #[allow(arithmetic_overflow)]
232 #[rustc_inherit_overflow_checks]
233 fn forward(start: Self, n: usize) -> Self {
234 if Self::forward_checked(start, n).is_none() {
237 let _ = Self::MAX + 1;
238 }
239 start.wrapping_add(n as Self)
241 }
242
243 #[inline]
244 #[allow(arithmetic_overflow)]
245 #[rustc_inherit_overflow_checks]
246 fn backward(start: Self, n: usize) -> Self {
247 if Self::backward_checked(start, n).is_none() {
250 let _ = Self::MIN - 1;
251 }
252 start.wrapping_sub(n as Self)
254 }
255 };
256}
257
258macro_rules! step_integer_impls {
259 {
260 narrower than or same width as usize:
261 $( [ $u_narrower:ident $i_narrower:ident ] ),+;
262 wider than usize:
263 $( [ $u_wider:ident $i_wider:ident ] ),+;
264 } => {
265 $(
266 #[allow(unreachable_patterns)]
267 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
268 impl Step for $u_narrower {
269 step_identical_methods!();
270 step_unsigned_methods!();
271
272 #[inline]
273 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
274 if *start <= *end {
275 let steps = (*end - *start) as usize;
277 (steps, Some(steps))
278 } else {
279 (0, None)
280 }
281 }
282
283 #[inline]
284 fn forward_checked(start: Self, n: usize) -> Option<Self> {
285 match Self::try_from(n) {
286 Ok(n) => start.checked_add(n),
287 Err(_) => None, }
289 }
290
291 #[inline]
292 fn backward_checked(start: Self, n: usize) -> Option<Self> {
293 match Self::try_from(n) {
294 Ok(n) => start.checked_sub(n),
295 Err(_) => None, }
297 }
298 }
299
300 #[allow(unreachable_patterns)]
301 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
302 impl Step for $i_narrower {
303 step_identical_methods!();
304 step_signed_methods!($u_narrower);
305
306 #[inline]
307 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
308 if *start <= *end {
309 let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
315 (steps, Some(steps))
316 } else {
317 (0, None)
318 }
319 }
320
321 #[inline]
322 fn forward_checked(start: Self, n: usize) -> Option<Self> {
323 match $u_narrower::try_from(n) {
324 Ok(n) => {
325 let wrapped = start.wrapping_add(n as Self);
329 if wrapped >= start {
330 Some(wrapped)
331 } else {
332 None }
334 }
335 Err(_) => None,
339 }
340 }
341
342 #[inline]
343 fn backward_checked(start: Self, n: usize) -> Option<Self> {
344 match $u_narrower::try_from(n) {
345 Ok(n) => {
346 let wrapped = start.wrapping_sub(n as Self);
350 if wrapped <= start {
351 Some(wrapped)
352 } else {
353 None }
355 }
356 Err(_) => None,
360 }
361 }
362 }
363 )+
364
365 $(
366 #[allow(unreachable_patterns)]
367 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
368 impl Step for $u_wider {
369 step_identical_methods!();
370 step_unsigned_methods!();
371
372 #[inline]
373 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
374 if *start <= *end {
375 if let Ok(steps) = usize::try_from(*end - *start) {
376 (steps, Some(steps))
377 } else {
378 (usize::MAX, None)
379 }
380 } else {
381 (0, None)
382 }
383 }
384
385 #[inline]
386 fn forward_checked(start: Self, n: usize) -> Option<Self> {
387 start.checked_add(n as Self)
388 }
389
390 #[inline]
391 fn backward_checked(start: Self, n: usize) -> Option<Self> {
392 start.checked_sub(n as Self)
393 }
394 }
395
396 #[allow(unreachable_patterns)]
397 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
398 impl Step for $i_wider {
399 step_identical_methods!();
400 step_signed_methods!($u_wider);
401
402 #[inline]
403 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
404 if *start <= *end {
405 match end.checked_sub(*start) {
406 Some(result) => {
407 if let Ok(steps) = usize::try_from(result) {
408 (steps, Some(steps))
409 } else {
410 (usize::MAX, None)
411 }
412 }
413 None => (usize::MAX, None),
416 }
417 } else {
418 (0, None)
419 }
420 }
421
422 #[inline]
423 fn forward_checked(start: Self, n: usize) -> Option<Self> {
424 start.checked_add(n as Self)
425 }
426
427 #[inline]
428 fn backward_checked(start: Self, n: usize) -> Option<Self> {
429 start.checked_sub(n as Self)
430 }
431 }
432 )+
433 };
434}
435
436#[cfg(target_pointer_width = "64")]
437step_integer_impls! {
438 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize];
439 wider than usize: [u128 i128];
440}
441
442#[cfg(target_pointer_width = "32")]
443step_integer_impls! {
444 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize];
445 wider than usize: [u64 i64], [u128 i128];
446}
447
448#[cfg(target_pointer_width = "16")]
449step_integer_impls! {
450 narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize];
451 wider than usize: [u32 i32], [u64 i64], [u128 i128];
452}
453
454#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
455#[cfg(not(feature = "ferrocene_subset"))]
456impl Step for char {
457 #[inline]
458 fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
459 let start = start as u32;
460 let end = end as u32;
461 if start <= end {
462 let count = end - start;
463 if start < 0xD800 && 0xE000 <= end {
464 if let Ok(steps) = usize::try_from(count - 0x800) {
465 (steps, Some(steps))
466 } else {
467 (usize::MAX, None)
468 }
469 } else {
470 if let Ok(steps) = usize::try_from(count) {
471 (steps, Some(steps))
472 } else {
473 (usize::MAX, None)
474 }
475 }
476 } else {
477 (0, None)
478 }
479 }
480
481 #[inline]
482 fn forward_checked(start: char, count: usize) -> Option<char> {
483 let start = start as u32;
484 let mut res = Step::forward_checked(start, count)?;
485 if start < 0xD800 && 0xD800 <= res {
486 res = Step::forward_checked(res, 0x800)?;
487 }
488 if res <= char::MAX as u32 {
489 Some(unsafe { char::from_u32_unchecked(res) })
492 } else {
493 None
494 }
495 }
496
497 #[inline]
498 fn backward_checked(start: char, count: usize) -> Option<char> {
499 let start = start as u32;
500 let mut res = Step::backward_checked(start, count)?;
501 if start >= 0xE000 && 0xE000 > res {
502 res = Step::backward_checked(res, 0x800)?;
503 }
504 Some(unsafe { char::from_u32_unchecked(res) })
507 }
508
509 #[inline]
510 unsafe fn forward_unchecked(start: char, count: usize) -> char {
511 let start = start as u32;
512 let mut res = unsafe { Step::forward_unchecked(start, count) };
515 if start < 0xD800 && 0xD800 <= res {
516 res = unsafe { Step::forward_unchecked(res, 0x800) };
519 }
520 unsafe { char::from_u32_unchecked(res) }
523 }
524
525 #[inline]
526 unsafe fn backward_unchecked(start: char, count: usize) -> char {
527 let start = start as u32;
528 let mut res = unsafe { Step::backward_unchecked(start, count) };
531 if start >= 0xE000 && 0xE000 > res {
532 res = unsafe { Step::backward_unchecked(res, 0x800) };
535 }
536 unsafe { char::from_u32_unchecked(res) }
539 }
540}
541
542#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
543#[cfg(not(feature = "ferrocene_subset"))]
544impl Step for AsciiChar {
545 #[inline]
546 fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
547 Step::steps_between(&start.to_u8(), &end.to_u8())
548 }
549
550 #[inline]
551 fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
552 let end = Step::forward_checked(start.to_u8(), count)?;
553 AsciiChar::from_u8(end)
554 }
555
556 #[inline]
557 fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
558 let end = Step::backward_checked(start.to_u8(), count)?;
559
560 Some(unsafe { AsciiChar::from_u8_unchecked(end) })
562 }
563
564 #[inline]
565 unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
566 let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
569
570 unsafe { AsciiChar::from_u8_unchecked(end) }
572 }
573
574 #[inline]
575 unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
576 let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
579
580 unsafe { AsciiChar::from_u8_unchecked(end) }
582 }
583}
584
585#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
586#[cfg(not(feature = "ferrocene_subset"))]
587impl Step for Ipv4Addr {
588 #[inline]
589 fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
590 u32::steps_between(&start.to_bits(), &end.to_bits())
591 }
592
593 #[inline]
594 fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
595 u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
596 }
597
598 #[inline]
599 fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
600 u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
601 }
602
603 #[inline]
604 unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
605 Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
608 }
609
610 #[inline]
611 unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
612 Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
615 }
616}
617
618#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
619#[cfg(not(feature = "ferrocene_subset"))]
620impl Step for Ipv6Addr {
621 #[inline]
622 fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
623 u128::steps_between(&start.to_bits(), &end.to_bits())
624 }
625
626 #[inline]
627 fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
628 u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
629 }
630
631 #[inline]
632 fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
633 u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
634 }
635
636 #[inline]
637 unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
638 Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
641 }
642
643 #[inline]
644 unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
645 Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
648 }
649}
650
651macro_rules! range_exact_iter_impl {
652 ($($t:ty)*) => ($(
653 #[stable(feature = "rust1", since = "1.0.0")]
654 impl ExactSizeIterator for ops::Range<$t> { }
655 )*)
656}
657
658#[cfg(not(feature = "ferrocene_subset"))]
661macro_rules! unsafe_range_trusted_random_access_impl {
662 ($($t:ty)*) => ($(
663 #[doc(hidden)]
664 #[unstable(feature = "trusted_random_access", issue = "none")]
665 unsafe impl TrustedRandomAccess for ops::Range<$t> {}
666
667 #[doc(hidden)]
668 #[unstable(feature = "trusted_random_access", issue = "none")]
669 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
670 const MAY_HAVE_SIDE_EFFECT: bool = false;
671 }
672 )*)
673}
674
675#[cfg(not(feature = "ferrocene_subset"))]
676macro_rules! range_incl_exact_iter_impl {
677 ($($t:ty)*) => ($(
678 #[stable(feature = "inclusive_range", since = "1.26.0")]
679 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
680 )*)
681}
682
683trait RangeIteratorImpl {
685 type Item;
686
687 fn spec_next(&mut self) -> Option<Self::Item>;
689 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
690 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
691
692 fn spec_next_back(&mut self) -> Option<Self::Item>;
694 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
695 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
696}
697
698impl<A: Step> RangeIteratorImpl for ops::Range<A> {
699 type Item = A;
700
701 #[inline]
702 default fn spec_next(&mut self) -> Option<A> {
703 if self.start < self.end {
704 let n =
705 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
706 Some(mem::replace(&mut self.start, n))
707 } else {
708 None
709 }
710 }
711
712 #[inline]
713 default fn spec_nth(&mut self, n: usize) -> Option<A> {
714 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
715 if plus_n < self.end {
716 self.start =
717 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
718 return Some(plus_n);
719 }
720 }
721
722 self.start = self.end.clone();
723 None
724 }
725
726 #[inline]
727 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
728 let steps = Step::steps_between(&self.start, &self.end);
729 let available = steps.1.unwrap_or(steps.0);
730
731 let taken = available.min(n);
732
733 self.start =
734 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
735
736 NonZero::new(n - taken).map_or(Ok(()), Err)
737 }
738
739 #[inline]
740 default fn spec_next_back(&mut self) -> Option<A> {
741 if self.start < self.end {
742 self.end =
743 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
744 Some(self.end.clone())
745 } else {
746 None
747 }
748 }
749
750 #[inline]
751 default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
752 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
753 if minus_n > self.start {
754 self.end =
755 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
756 return Some(self.end.clone());
757 }
758 }
759
760 self.end = self.start.clone();
761 None
762 }
763
764 #[inline]
765 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
766 let steps = Step::steps_between(&self.start, &self.end);
767 let available = steps.1.unwrap_or(steps.0);
768
769 let taken = available.min(n);
770
771 self.end =
772 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
773
774 NonZero::new(n - taken).map_or(Ok(()), Err)
775 }
776}
777
778#[cfg(not(feature = "ferrocene_subset"))]
779impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
780 #[inline]
781 fn spec_next(&mut self) -> Option<T> {
782 if self.start < self.end {
783 let old = self.start;
784 self.start = unsafe { Step::forward_unchecked(old, 1) };
786 Some(old)
787 } else {
788 None
789 }
790 }
791
792 #[inline]
793 fn spec_nth(&mut self, n: usize) -> Option<T> {
794 if let Some(plus_n) = Step::forward_checked(self.start, n) {
795 if plus_n < self.end {
796 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
798 return Some(plus_n);
799 }
800 }
801
802 self.start = self.end;
803 None
804 }
805
806 #[inline]
807 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
808 let steps = Step::steps_between(&self.start, &self.end);
809 let available = steps.1.unwrap_or(steps.0);
810
811 let taken = available.min(n);
812
813 self.start = unsafe { Step::forward_unchecked(self.start, taken) };
818
819 NonZero::new(n - taken).map_or(Ok(()), Err)
820 }
821
822 #[inline]
823 fn spec_next_back(&mut self) -> Option<T> {
824 if self.start < self.end {
825 self.end = unsafe { Step::backward_unchecked(self.end, 1) };
827 Some(self.end)
828 } else {
829 None
830 }
831 }
832
833 #[inline]
834 fn spec_nth_back(&mut self, n: usize) -> Option<T> {
835 if let Some(minus_n) = Step::backward_checked(self.end, n) {
836 if minus_n > self.start {
837 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
839 return Some(self.end);
840 }
841 }
842
843 self.end = self.start;
844 None
845 }
846
847 #[inline]
848 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
849 let steps = Step::steps_between(&self.start, &self.end);
850 let available = steps.1.unwrap_or(steps.0);
851
852 let taken = available.min(n);
853
854 self.end = unsafe { Step::backward_unchecked(self.end, taken) };
856
857 NonZero::new(n - taken).map_or(Ok(()), Err)
858 }
859}
860
861#[stable(feature = "rust1", since = "1.0.0")]
862impl<A: Step> Iterator for ops::Range<A> {
863 type Item = A;
864
865 #[inline]
866 fn next(&mut self) -> Option<A> {
867 self.spec_next()
868 }
869
870 #[inline]
871 fn size_hint(&self) -> (usize, Option<usize>) {
872 if self.start < self.end {
873 Step::steps_between(&self.start, &self.end)
874 } else {
875 (0, Some(0))
876 }
877 }
878
879 #[inline]
880 fn count(self) -> usize {
881 if self.start < self.end {
882 Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
883 } else {
884 0
885 }
886 }
887
888 #[inline]
889 fn nth(&mut self, n: usize) -> Option<A> {
890 self.spec_nth(n)
891 }
892
893 #[inline]
894 fn last(mut self) -> Option<A> {
895 self.next_back()
896 }
897
898 #[inline]
899 #[cfg(not(feature = "ferrocene_subset"))]
900 fn min(mut self) -> Option<A>
901 where
902 A: Ord,
903 {
904 self.next()
905 }
906
907 #[inline]
908 #[cfg(not(feature = "ferrocene_subset"))]
909 fn max(mut self) -> Option<A>
910 where
911 A: Ord,
912 {
913 self.next_back()
914 }
915
916 #[inline]
917 #[cfg(not(feature = "ferrocene_subset"))]
918 fn is_sorted(self) -> bool {
919 true
920 }
921
922 #[inline]
923 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
924 self.spec_advance_by(n)
925 }
926
927 #[inline]
928 #[cfg(not(feature = "ferrocene_subset"))]
929 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
930 where
931 Self: TrustedRandomAccessNoCoerce,
932 {
933 unsafe { Step::forward_unchecked(self.start.clone(), idx) }
938 }
939}
940
941range_exact_iter_impl! {
950 usize u8 u16
951 isize i8 i16
952
953 u32
958 i32
959}
960
961#[cfg(not(feature = "ferrocene_subset"))]
962unsafe_range_trusted_random_access_impl! {
963 usize u8 u16
964 isize i8 i16
965}
966
967#[cfg(target_pointer_width = "32")]
968#[cfg(not(feature = "ferrocene_subset"))]
969unsafe_range_trusted_random_access_impl! {
970 u32 i32
971}
972
973#[cfg(target_pointer_width = "64")]
974#[cfg(not(feature = "ferrocene_subset"))]
975unsafe_range_trusted_random_access_impl! {
976 u32 i32
977 u64 i64
978}
979
980#[cfg(not(feature = "ferrocene_subset"))]
981range_incl_exact_iter_impl! {
982 u8
983 i8
984
985 u16
990 i16
991}
992
993#[stable(feature = "rust1", since = "1.0.0")]
994impl<A: Step> DoubleEndedIterator for ops::Range<A> {
995 #[inline]
996 fn next_back(&mut self) -> Option<A> {
997 self.spec_next_back()
998 }
999
1000 #[inline]
1001 fn nth_back(&mut self, n: usize) -> Option<A> {
1002 self.spec_nth_back(n)
1003 }
1004
1005 #[inline]
1006 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1007 self.spec_advance_back_by(n)
1008 }
1009}
1010
1011#[unstable(feature = "trusted_len", issue = "37572")]
1031#[cfg(not(feature = "ferrocene_subset"))]
1032unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
1033
1034#[stable(feature = "fused", since = "1.26.0")]
1035#[cfg(not(feature = "ferrocene_subset"))]
1036impl<A: Step> FusedIterator for ops::Range<A> {}
1037
1038#[stable(feature = "rust1", since = "1.0.0")]
1039#[cfg(not(feature = "ferrocene_subset"))]
1040impl<A: Step> Iterator for ops::RangeFrom<A> {
1041 type Item = A;
1042
1043 #[inline]
1044 fn next(&mut self) -> Option<A> {
1045 let n = Step::forward(self.start.clone(), 1);
1046 Some(mem::replace(&mut self.start, n))
1047 }
1048
1049 #[inline]
1050 fn size_hint(&self) -> (usize, Option<usize>) {
1051 (usize::MAX, None)
1052 }
1053
1054 #[inline]
1055 fn nth(&mut self, n: usize) -> Option<A> {
1056 let plus_n = Step::forward(self.start.clone(), n);
1057 self.start = Step::forward(plus_n.clone(), 1);
1058 Some(plus_n)
1059 }
1060}
1061
1062#[unstable(feature = "trusted_len", issue = "37572")]
1064#[cfg(not(feature = "ferrocene_subset"))]
1065unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
1066
1067#[stable(feature = "fused", since = "1.26.0")]
1068#[cfg(not(feature = "ferrocene_subset"))]
1069impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
1070
1071trait RangeInclusiveIteratorImpl {
1072 type Item;
1073
1074 fn spec_next(&mut self) -> Option<Self::Item>;
1076 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1077 where
1078 Self: Sized,
1079 F: FnMut(B, Self::Item) -> R,
1080 R: Try<Output = B>;
1081
1082 fn spec_next_back(&mut self) -> Option<Self::Item>;
1084 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1085 where
1086 Self: Sized,
1087 F: FnMut(B, Self::Item) -> R,
1088 R: Try<Output = B>;
1089}
1090
1091impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
1092 type Item = A;
1093
1094 #[inline]
1095 default fn spec_next(&mut self) -> Option<A> {
1096 if self.is_empty() {
1097 return None;
1098 }
1099 let is_iterating = self.start < self.end;
1100 Some(if is_iterating {
1101 let n =
1102 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1103 mem::replace(&mut self.start, n)
1104 } else {
1105 self.exhausted = true;
1106 self.start.clone()
1107 })
1108 }
1109
1110 #[inline]
1111 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1112 where
1113 Self: Sized,
1114 F: FnMut(B, A) -> R,
1115 R: Try<Output = B>,
1116 {
1117 if self.is_empty() {
1118 return try { init };
1119 }
1120
1121 let mut accum = init;
1122
1123 while self.start < self.end {
1124 let n =
1125 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
1126 let n = mem::replace(&mut self.start, n);
1127 accum = f(accum, n)?;
1128 }
1129
1130 self.exhausted = true;
1131
1132 if self.start == self.end {
1133 accum = f(accum, self.start.clone())?;
1134 }
1135
1136 try { accum }
1137 }
1138
1139 #[inline]
1140 default fn spec_next_back(&mut self) -> Option<A> {
1141 if self.is_empty() {
1142 return None;
1143 }
1144 let is_iterating = self.start < self.end;
1145 Some(if is_iterating {
1146 let n =
1147 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1148 mem::replace(&mut self.end, n)
1149 } else {
1150 self.exhausted = true;
1151 self.end.clone()
1152 })
1153 }
1154
1155 #[inline]
1156 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1157 where
1158 Self: Sized,
1159 F: FnMut(B, A) -> R,
1160 R: Try<Output = B>,
1161 {
1162 if self.is_empty() {
1163 return try { init };
1164 }
1165
1166 let mut accum = init;
1167
1168 while self.start < self.end {
1169 let n =
1170 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
1171 let n = mem::replace(&mut self.end, n);
1172 accum = f(accum, n)?;
1173 }
1174
1175 self.exhausted = true;
1176
1177 if self.start == self.end {
1178 accum = f(accum, self.start.clone())?;
1179 }
1180
1181 try { accum }
1182 }
1183}
1184
1185impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1186 #[inline]
1187 fn spec_next(&mut self) -> Option<T> {
1188 if self.is_empty() {
1189 return None;
1190 }
1191 let is_iterating = self.start < self.end;
1192 Some(if is_iterating {
1193 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1195 mem::replace(&mut self.start, n)
1196 } else {
1197 self.exhausted = true;
1198 self.start
1199 })
1200 }
1201
1202 #[inline]
1203 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1204 where
1205 Self: Sized,
1206 F: FnMut(B, T) -> R,
1207 R: Try<Output = B>,
1208 {
1209 if self.is_empty() {
1210 return try { init };
1211 }
1212
1213 let mut accum = init;
1214
1215 while self.start < self.end {
1216 let n = unsafe { Step::forward_unchecked(self.start, 1) };
1218 let n = mem::replace(&mut self.start, n);
1219 accum = f(accum, n)?;
1220 }
1221
1222 self.exhausted = true;
1223
1224 if self.start == self.end {
1225 accum = f(accum, self.start)?;
1226 }
1227
1228 try { accum }
1229 }
1230
1231 #[inline]
1232 fn spec_next_back(&mut self) -> Option<T> {
1233 if self.is_empty() {
1234 return None;
1235 }
1236 let is_iterating = self.start < self.end;
1237 Some(if is_iterating {
1238 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1240 mem::replace(&mut self.end, n)
1241 } else {
1242 self.exhausted = true;
1243 self.end
1244 })
1245 }
1246
1247 #[inline]
1248 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1249 where
1250 Self: Sized,
1251 F: FnMut(B, T) -> R,
1252 R: Try<Output = B>,
1253 {
1254 if self.is_empty() {
1255 return try { init };
1256 }
1257
1258 let mut accum = init;
1259
1260 while self.start < self.end {
1261 let n = unsafe { Step::backward_unchecked(self.end, 1) };
1263 let n = mem::replace(&mut self.end, n);
1264 accum = f(accum, n)?;
1265 }
1266
1267 self.exhausted = true;
1268
1269 if self.start == self.end {
1270 accum = f(accum, self.start)?;
1271 }
1272
1273 try { accum }
1274 }
1275}
1276
1277#[stable(feature = "inclusive_range", since = "1.26.0")]
1278impl<A: Step> Iterator for ops::RangeInclusive<A> {
1279 type Item = A;
1280
1281 #[inline]
1282 fn next(&mut self) -> Option<A> {
1283 self.spec_next()
1284 }
1285
1286 #[inline]
1287 fn size_hint(&self) -> (usize, Option<usize>) {
1288 if self.is_empty() {
1289 return (0, Some(0));
1290 }
1291
1292 let hint = Step::steps_between(&self.start, &self.end);
1293 (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
1294 }
1295
1296 #[inline]
1297 fn count(self) -> usize {
1298 if self.is_empty() {
1299 return 0;
1300 }
1301
1302 Step::steps_between(&self.start, &self.end)
1303 .1
1304 .and_then(|steps| steps.checked_add(1))
1305 .expect("count overflowed usize")
1306 }
1307
1308 #[inline]
1309 fn nth(&mut self, n: usize) -> Option<A> {
1310 if self.is_empty() {
1311 return None;
1312 }
1313
1314 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1315 use crate::cmp::Ordering::*;
1316
1317 match plus_n.partial_cmp(&self.end) {
1318 Some(Less) => {
1319 self.start = Step::forward(plus_n.clone(), 1);
1320 return Some(plus_n);
1321 }
1322 Some(Equal) => {
1323 self.start = plus_n.clone();
1324 self.exhausted = true;
1325 return Some(plus_n);
1326 }
1327 _ => {}
1328 }
1329 }
1330
1331 self.start = self.end.clone();
1332 self.exhausted = true;
1333 None
1334 }
1335
1336 #[inline]
1337 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1338 where
1339 Self: Sized,
1340 F: FnMut(B, Self::Item) -> R,
1341 R: Try<Output = B>,
1342 {
1343 self.spec_try_fold(init, f)
1344 }
1345
1346 impl_fold_via_try_fold! { fold -> try_fold }
1347
1348 #[inline]
1349 fn last(mut self) -> Option<A> {
1350 self.next_back()
1351 }
1352
1353 #[cfg(not(feature = "ferrocene_subset"))]
1354 #[inline]
1355 fn min(mut self) -> Option<A>
1356 where
1357 A: Ord,
1358 {
1359 self.next()
1360 }
1361
1362 #[cfg(not(feature = "ferrocene_subset"))]
1363 #[inline]
1364 fn max(mut self) -> Option<A>
1365 where
1366 A: Ord,
1367 {
1368 self.next_back()
1369 }
1370
1371 #[cfg(not(feature = "ferrocene_subset"))]
1372 #[inline]
1373 fn is_sorted(self) -> bool {
1374 true
1375 }
1376}
1377
1378#[stable(feature = "inclusive_range", since = "1.26.0")]
1379impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1380 #[inline]
1381 fn next_back(&mut self) -> Option<A> {
1382 self.spec_next_back()
1383 }
1384
1385 #[inline]
1386 fn nth_back(&mut self, n: usize) -> Option<A> {
1387 if self.is_empty() {
1388 return None;
1389 }
1390
1391 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1392 use crate::cmp::Ordering::*;
1393
1394 match minus_n.partial_cmp(&self.start) {
1395 Some(Greater) => {
1396 self.end = Step::backward(minus_n.clone(), 1);
1397 return Some(minus_n);
1398 }
1399 Some(Equal) => {
1400 self.end = minus_n.clone();
1401 self.exhausted = true;
1402 return Some(minus_n);
1403 }
1404 _ => {}
1405 }
1406 }
1407
1408 self.end = self.start.clone();
1409 self.exhausted = true;
1410 None
1411 }
1412
1413 #[inline]
1414 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1415 where
1416 Self: Sized,
1417 F: FnMut(B, Self::Item) -> R,
1418 R: Try<Output = B>,
1419 {
1420 self.spec_try_rfold(init, f)
1421 }
1422
1423 impl_fold_via_try_fold! { rfold -> try_rfold }
1424}
1425
1426#[unstable(feature = "trusted_len", issue = "37572")]
1428#[cfg(not(feature = "ferrocene_subset"))]
1429unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1430
1431#[stable(feature = "fused", since = "1.26.0")]
1432#[cfg(not(feature = "ferrocene_subset"))]
1433impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}