use crate::iter::{ FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep, }; use crate::num::NonZero; use crate::range::{Range, RangeFrom, RangeInclusive, legacy}; /// By-value [`Range`] iterator. #[unstable(feature = "new_range_api", issue = "125687")] #[derive(Debug, Clone)] pub struct IterRange(legacy::Range); impl IterRange { /// Returns the remainder of the range being iterated over. pub fn remainder(self) -> Range { Range { start: self.0.start, end: self.0.end } } } /// Safety: This macro must only be used on types that are `Copy` and result in ranges /// which have an exact `size_hint()` where the upper bound must not be `None`. macro_rules! unsafe_range_trusted_random_access_impl { ($($t:ty)*) => ($( #[doc(hidden)] #[unstable(feature = "trusted_random_access", issue = "none")] unsafe impl TrustedRandomAccess for IterRange<$t> {} #[doc(hidden)] #[unstable(feature = "trusted_random_access", issue = "none")] unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> { const MAY_HAVE_SIDE_EFFECT: bool = false; } )*) } unsafe_range_trusted_random_access_impl! { usize u8 u16 isize i8 i16 } #[cfg(target_pointer_width = "32")] unsafe_range_trusted_random_access_impl! { u32 i32 } #[cfg(target_pointer_width = "64")] unsafe_range_trusted_random_access_impl! { u32 i32 u64 i64 } #[unstable(feature = "new_range_api", issue = "125687")] impl Iterator for IterRange { type Item = A; #[inline] fn next(&mut self) -> Option { self.0.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn count(self) -> usize { self.0.count() } #[inline] fn nth(&mut self, n: usize) -> Option { self.0.nth(n) } #[inline] fn last(self) -> Option { self.0.last() } #[inline] fn min(self) -> Option where A: Ord, { self.0.min() } #[inline] fn max(self) -> Option where A: Ord, { self.0.max() } #[inline] fn is_sorted(self) -> bool { true } #[inline] fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { self.0.advance_by(n) } #[inline] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce, { // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index // that is in bounds. // Additionally Self: TrustedRandomAccess is only implemented for Copy types // which means even repeated reads of the same index would be safe. unsafe { Step::forward_unchecked(self.0.start.clone(), idx) } } } #[unstable(feature = "new_range_api", issue = "125687")] impl DoubleEndedIterator for IterRange { #[inline] fn next_back(&mut self) -> Option { self.0.next_back() } #[inline] fn nth_back(&mut self, n: usize) -> Option { self.0.nth_back(n) } #[inline] fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { self.0.advance_back_by(n) } } #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IterRange {} #[unstable(feature = "new_range_api", issue = "125687")] impl FusedIterator for IterRange {} #[unstable(feature = "new_range_api", issue = "125687")] impl IntoIterator for Range { type Item = A; type IntoIter = IterRange; fn into_iter(self) -> Self::IntoIter { IterRange(self.into()) } } /// By-value [`RangeInclusive`] iterator. #[unstable(feature = "new_range_api", issue = "125687")] #[derive(Debug, Clone)] pub struct IterRangeInclusive(legacy::RangeInclusive); impl IterRangeInclusive { /// Returns the remainder of the range being iterated over. /// /// If the iterator is exhausted or empty, returns `None`. pub fn remainder(self) -> Option> { if self.0.is_empty() { return None; } Some(RangeInclusive { start: self.0.start, end: self.0.end }) } } #[unstable(feature = "trusted_random_access", issue = "none")] impl Iterator for IterRangeInclusive { type Item = A; #[inline] fn next(&mut self) -> Option { self.0.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn count(self) -> usize { self.0.count() } #[inline] fn nth(&mut self, n: usize) -> Option { self.0.nth(n) } #[inline] fn last(self) -> Option { self.0.last() } #[inline] fn min(self) -> Option where A: Ord, { self.0.min() } #[inline] fn max(self) -> Option where A: Ord, { self.0.max() } #[inline] fn is_sorted(self) -> bool { true } #[inline] fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { self.0.advance_by(n) } } #[unstable(feature = "new_range_api", issue = "125687")] impl DoubleEndedIterator for IterRangeInclusive { #[inline] fn next_back(&mut self) -> Option { self.0.next_back() } #[inline] fn nth_back(&mut self, n: usize) -> Option { self.0.nth_back(n) } #[inline] fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { self.0.advance_back_by(n) } } #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IterRangeInclusive {} #[unstable(feature = "new_range_api", issue = "125687")] impl FusedIterator for IterRangeInclusive {} #[unstable(feature = "new_range_api", issue = "125687")] impl IntoIterator for RangeInclusive { type Item = A; type IntoIter = IterRangeInclusive; fn into_iter(self) -> Self::IntoIter { IterRangeInclusive(self.into()) } } // These macros generate `ExactSizeIterator` impls for various range types. // // * `ExactSizeIterator::len` is required to always return an exact `usize`, // so no range can be longer than `usize::MAX`. // * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`. // For integer types in `RangeInclusive<_>` // this is the case for types *strictly narrower* than `usize` // since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( #[unstable(feature = "new_range_api", issue = "125687")] impl ExactSizeIterator for IterRange<$t> { } )*) } macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( #[unstable(feature = "new_range_api", issue = "125687")] impl ExactSizeIterator for IterRangeInclusive<$t> { } )*) } range_exact_iter_impl! { usize u8 u16 isize i8 i16 } range_incl_exact_iter_impl! { u8 i8 } /// By-value [`RangeFrom`] iterator. #[unstable(feature = "new_range_api", issue = "125687")] #[derive(Debug, Clone)] pub struct IterRangeFrom(legacy::RangeFrom); impl IterRangeFrom { /// Returns the remainder of the range being iterated over. pub fn remainder(self) -> RangeFrom { RangeFrom { start: self.0.start } } } #[unstable(feature = "trusted_random_access", issue = "none")] impl Iterator for IterRangeFrom { type Item = A; #[inline] fn next(&mut self) -> Option { self.0.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } #[inline] fn nth(&mut self, n: usize) -> Option { self.0.nth(n) } } #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IterRangeFrom {} #[unstable(feature = "new_range_api", issue = "125687")] impl FusedIterator for IterRangeFrom {} #[unstable(feature = "new_range_api", issue = "125687")] impl IntoIterator for RangeFrom { type Item = A; type IntoIter = IterRangeFrom; fn into_iter(self) -> Self::IntoIter { IterRangeFrom(self.into()) } }