iter.rs - source
Description: Source of the Rust file `library/core/src/range/iter.rs`.

#
core/range/
iter.rs

    1use crate::iter::{
    2    FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
    3};
    4use crate::num::NonZero;
    5use crate::range::{Range, RangeFrom, RangeInclusive, legacy};
    6use crate::{intrinsics, mem};
    7
    8/// By-value [`Range`] iterator.
    9#[unstable(feature = "new_range_api", issue = "125687")]
    10#[derive(Debug, Clone)]
    11pub struct RangeIter<A>(legacy::Range<A>);
    12
    13impl<A> RangeIter<A> {
    14    /// Returns the remainder of the range being iterated over.
    15    pub fn remainder(self) -> Range<A> {
    16        Range { start: self.0.start, end: self.0.end }
    17    }
    18}
    19
    20/// Safety: This macro must only be used on types that are `Copy` and result in ranges
    21/// which have an exact `size_hint()` where the upper bound must not be `None`.
    22macro_rules! unsafe_range_trusted_random_access_impl {
    23    ($($t:ty)*) => ($(
    24        #[doc(hidden)]
    25        #[unstable(feature = "trusted_random_access", issue = "none")]
    26        unsafe impl TrustedRandomAccess for RangeIter<$t> {}
    27
    28        #[doc(hidden)]
    29        #[unstable(feature = "trusted_random_access", issue = "none")]
    30        unsafe impl TrustedRandomAccessNoCoerce for RangeIter<$t> {
    31            const MAY_HAVE_SIDE_EFFECT: bool = false;
    32        }
    33    )*)
    34}
    35
    36unsafe_range_trusted_random_access_impl! {
    37    usize u8 u16
    38    isize i8 i16
    39}
    40
    41#[cfg(target_pointer_width = "32")]
    42unsafe_range_trusted_random_access_impl! {
    43    u32 i32
    44}
    45
    46#[cfg(target_pointer_width = "64")]
    47unsafe_range_trusted_random_access_impl! {
    48    u32 i32
    49    u64 i64
    50}
    51
    52#[unstable(feature = "new_range_api", issue = "125687")]
    53impl<A: Step> Iterator for RangeIter<A> {
    54    type Item = A;
    55
    56    #[inline]
    57    fn next(&mut self) -> Option<A> {
    58        self.0.next()
    59    }
    60
    61    #[inline]
    62    fn size_hint(&self) -> (usize, Option<usize>) {
    63        self.0.size_hint()
    64    }
    65
    66    #[inline]
    67    fn count(self) -> usize {
    68        self.0.count()
    69    }
    70
    71    #[inline]
    72    fn nth(&mut self, n: usize) -> Option<A> {
    73        self.0.nth(n)
    74    }
    75
    76    #[inline]
    77    fn last(self) -> Option<A> {
    78        self.0.last()
    79    }
    80
    81    #[inline]
    82    fn min(self) -> Option<A>
    83    where
    84        A: Ord,
    85    {
    86        self.0.min()
    87    }
    88
    89    #[inline]
    90    fn max(self) -> Option<A>
    91    where
    92        A: Ord,
    93    {
    94        self.0.max()
    95    }
    96
    97    #[inline]
    98    fn is_sorted(self) -> bool {
    99        true
    100    }
    101
    102    #[inline]
    103    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    104        self.0.advance_by(n)
    105    }
    106
    107    #[inline]
    108    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
    109    where
    110        Self: TrustedRandomAccessNoCoerce,
    111    {
    112        // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
    113        // that is in bounds.
    114        // Additionally Self: TrustedRandomAccess is only implemented for Copy types
    115        // which means even repeated reads of the same index would be safe.
    116        unsafe { Step::forward_unchecked(self.0.start.clone(), idx) }
    117    }
    118}
    119
    120#[unstable(feature = "new_range_api", issue = "125687")]
    121impl<A: Step> DoubleEndedIterator for RangeIter<A> {
    122    #[inline]
    123    fn next_back(&mut self) -> Option<A> {
    124        self.0.next_back()
    125    }
    126
    127    #[inline]
    128    fn nth_back(&mut self, n: usize) -> Option<A> {
    129        self.0.nth_back(n)
    130    }
    131
    132    #[inline]
    133    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    134        self.0.advance_back_by(n)
    135    }
    136}
    137
    138#[unstable(feature = "trusted_len", issue = "37572")]
    139unsafe impl<A: TrustedStep> TrustedLen for RangeIter<A> {}
    140
    141#[unstable(feature = "new_range_api", issue = "125687")]
    142impl<A: Step> FusedIterator for RangeIter<A> {}
    143
    144#[unstable(feature = "new_range_api", issue = "125687")]
    145impl<A: Step> IntoIterator for Range<A> {
    146    type Item = A;
    147    type IntoIter = RangeIter<A>;
    148
    149    fn into_iter(self) -> Self::IntoIter {
    150        RangeIter(self.into())
    151    }
    152}
    153
    154/// By-value [`RangeInclusive`] iterator.
    155#[unstable(feature = "new_range_api", issue = "125687")]
    156#[derive(Debug, Clone)]
    157pub struct RangeInclusiveIter<A>(legacy::RangeInclusive<A>);
    158
    159impl<A: Step> RangeInclusiveIter<A> {
    160    /// Returns the remainder of the range being iterated over.
    161    ///
    162    /// If the iterator is exhausted or empty, returns `None`.
    163    pub fn remainder(self) -> Option<RangeInclusive<A>> {
    164        if self.0.is_empty() {
    165            return None;
    166        }
    167
    168        Some(RangeInclusive { start: self.0.start, last: self.0.end })
    169    }
    170}
    171
    172#[unstable(feature = "new_range_api", issue = "125687")]
    173impl<A: Step> Iterator for RangeInclusiveIter<A> {
    174    type Item = A;
    175
    176    #[inline]
    177    fn next(&mut self) -> Option<A> {
    178        self.0.next()
    179    }
    180
    181    #[inline]
    182    fn size_hint(&self) -> (usize, Option<usize>) {
    183        self.0.size_hint()
    184    }
    185
    186    #[inline]
    187    fn count(self) -> usize {
    188        self.0.count()
    189    }
    190
    191    #[inline]
    192    fn nth(&mut self, n: usize) -> Option<A> {
    193        self.0.nth(n)
    194    }
    195
    196    #[inline]
    197    fn last(self) -> Option<A> {
    198        self.0.last()
    199    }
    200
    201    #[inline]
    202    fn min(self) -> Option<A>
    203    where
    204        A: Ord,
    205    {
    206        self.0.min()
    207    }
    208
    209    #[inline]
    210    fn max(self) -> Option<A>
    211    where
    212        A: Ord,
    213    {
    214        self.0.max()
    215    }
    216
    217    #[inline]
    218    fn is_sorted(self) -> bool {
    219        true
    220    }
    221
    222    #[inline]
    223    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    224        self.0.advance_by(n)
    225    }
    226}
    227
    228#[unstable(feature = "new_range_api", issue = "125687")]
    229impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> {
    230    #[inline]
    231    fn next_back(&mut self) -> Option<A> {
    232        self.0.next_back()
    233    }
    234
    235    #[inline]
    236    fn nth_back(&mut self, n: usize) -> Option<A> {
    237        self.0.nth_back(n)
    238    }
    239
    240    #[inline]
    241    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    242        self.0.advance_back_by(n)
    243    }
    244}
    245
    246#[unstable(feature = "trusted_len", issue = "37572")]
    247unsafe impl<A: TrustedStep> TrustedLen for RangeInclusiveIter<A> {}
    248
    249#[unstable(feature = "new_range_api", issue = "125687")]
    250impl<A: Step> FusedIterator for RangeInclusiveIter<A> {}
    251
    252#[unstable(feature = "new_range_api", issue = "125687")]
    253impl<A: Step> IntoIterator for RangeInclusive<A> {
    254    type Item = A;
    255    type IntoIter = RangeInclusiveIter<A>;
    256
    257    fn into_iter(self) -> Self::IntoIter {
    258        RangeInclusiveIter(self.into())
    259    }
    260}
    261
    262// These macros generate `ExactSizeIterator` impls for various range types.
    263//
    264// * `ExactSizeIterator::len` is required to always return an exact `usize`,
    265//   so no range can be longer than `usize::MAX`.
    266// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
    267//   For integer types in `RangeInclusive<_>`
    268//   this is the case for types *strictly narrower* than `usize`
    269//   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
    270macro_rules! range_exact_iter_impl {
    271    ($($t:ty)*) => ($(
    272        #[unstable(feature = "new_range_api", issue = "125687")]
    273        impl ExactSizeIterator for RangeIter<$t> { }
    274    )*)
    275}
    276
    277macro_rules! range_incl_exact_iter_impl {
    278    ($($t:ty)*) => ($(
    279        #[unstable(feature = "new_range_api", issue = "125687")]
    280        impl ExactSizeIterator for RangeInclusiveIter<$t> { }
    281    )*)
    282}
    283
    284range_exact_iter_impl! {
    285    usize u8 u16
    286    isize i8 i16
    287}
    288
    289range_incl_exact_iter_impl! {
    290    u8
    291    i8
    292}
    293
    294/// By-value [`RangeFrom`] iterator.
    295#[unstable(feature = "new_range_api", issue = "125687")]
    296#[derive(Debug, Clone)]
    297pub struct RangeFromIter<A> {
    298    start: A,
    299    /// Whether the first element of the iterator has yielded.
    300    /// Only used when overflow checks are enabled.
    301    first: bool,
    302}
    303
    304impl<A: Step> RangeFromIter<A> {
    305    /// Returns the remainder of the range being iterated over.
    306    #[inline]
    307    #[rustc_inherit_overflow_checks]
    308    pub fn remainder(self) -> RangeFrom<A> {
    309        if intrinsics::overflow_checks() {
    310            if !self.first {
    311                return RangeFrom { start: Step::forward(self.start, 1) };
    312            }
    313        }
    314
    315        RangeFrom { start: self.start }
    316    }
    317}
    318
    319#[unstable(feature = "new_range_api", issue = "125687")]
    320impl<A: Step> Iterator for RangeFromIter<A> {
    321    type Item = A;
    322
    323    #[inline]
    324    #[rustc_inherit_overflow_checks]
    325    fn next(&mut self) -> Option<A> {
    326        if intrinsics::overflow_checks() {
    327            if self.first {
    328                self.first = false;
    329                return Some(self.start.clone());
    330            }
    331
    332            self.start = Step::forward(self.start.clone(), 1);
    333            return Some(self.start.clone());
    334        }
    335
    336        let n = Step::forward(self.start.clone(), 1);
    337        Some(mem::replace(&mut self.start, n))
    338    }
    339
    340    #[inline]
    341    fn size_hint(&self) -> (usize, Option<usize>) {
    342        (usize::MAX, None)
    343    }
    344
    345    #[inline]
    346    #[rustc_inherit_overflow_checks]
    347    fn nth(&mut self, n: usize) -> Option<A> {
    348        if intrinsics::overflow_checks() {
    349            if self.first {
    350                self.first = false;
    351
    352                let plus_n = Step::forward(self.start.clone(), n);
    353                self.start = plus_n.clone();
    354                return Some(plus_n);
    355            }
    356
    357            let plus_n = Step::forward(self.start.clone(), n);
    358            self.start = Step::forward(plus_n.clone(), 1);
    359            return Some(self.start.clone());
    360        }
    361
    362        let plus_n = Step::forward(self.start.clone(), n);
    363        self.start = Step::forward(plus_n.clone(), 1);
    364        Some(plus_n)
    365    }
    366}
    367
    368#[unstable(feature = "trusted_len", issue = "37572")]
    369unsafe impl<A: TrustedStep> TrustedLen for RangeFromIter<A> {}
    370
    371#[unstable(feature = "new_range_api", issue = "125687")]
    372impl<A: Step> FusedIterator for RangeFromIter<A> {}
    373
    374#[unstable(feature = "new_range_api", issue = "125687")]
    375impl<A: Step> IntoIterator for RangeFrom<A> {
    376    type Item = A;
    377    type IntoIter = RangeFromIter<A>;
    378
    379    fn into_iter(self) -> Self::IntoIter {
    380        RangeFromIter { start: self.start, first: true }
    381    }
    382}