blob: c29b498bd25f86913d706d22d7f487f8bc72dd3c [file]
use crate::iter::{
FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
};
use crate::num::NonZero;
use crate::range::{Range, RangeFrom, RangeInclusive, legacy};
use crate::{intrinsics, mem};
/// By-value [`Range`] iterator.
#[unstable(feature = "new_range_api", issue = "125687")]
#[derive(Debug, Clone)]
pub struct RangeIter<A>(legacy::Range<A>);
impl<A> RangeIter<A> {
#[unstable(feature = "new_range_remainder", issue = "154458")]
/// Returns the remainder of the range being iterated over.
///
/// # Examples
///
/// ```
/// #![feature(new_range_api)]
/// #![feature(new_range_remainder)]
///
/// let range = core::range::Range::from(3..11);
/// let mut iter = range.into_iter();
/// assert_eq!(iter.clone().remainder(), range);
/// iter.next();
/// assert_eq!(iter.clone().remainder(), core::range::Range::from(4..11));
/// iter.by_ref().for_each(drop);
/// assert!(iter.remainder().is_empty());
/// ```
pub fn remainder(self) -> Range<A> {
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 RangeIter<$t> {}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl TrustedRandomAccessNoCoerce for RangeIter<$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<A: Step> Iterator for RangeIter<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
#[inline]
fn count(self) -> usize {
self.0.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<A> {
self.0.nth(n)
}
#[inline]
fn last(self) -> Option<A> {
self.0.last()
}
#[inline]
fn min(self) -> Option<A>
where
A: Ord,
{
self.0.min()
}
#[inline]
fn max(self) -> Option<A>
where
A: Ord,
{
self.0.max()
}
#[inline]
fn is_sorted(self) -> bool {
true
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
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<A: Step> DoubleEndedIterator for RangeIter<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
self.0.next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<A> {
self.0.nth_back(n)
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
self.0.advance_back_by(n)
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: TrustedStep> TrustedLen for RangeIter<A> {}
#[unstable(feature = "new_range_api", issue = "125687")]
impl<A: Step> FusedIterator for RangeIter<A> {}
#[unstable(feature = "new_range_api", issue = "125687")]
impl<A: Step> IntoIterator for Range<A> {
type Item = A;
type IntoIter = RangeIter<A>;
fn into_iter(self) -> Self::IntoIter {
RangeIter(self.into())
}
}
/// By-value [`RangeInclusive`] iterator.
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
#[derive(Debug, Clone)]
pub struct RangeInclusiveIter<A>(legacy::RangeInclusive<A>);
impl<A: Step> RangeInclusiveIter<A> {
/// Returns the remainder of the range being iterated over.
///
/// If the iterator is exhausted or empty, returns `None`.
///
/// # Examples
///
/// ```
/// #![feature(new_range_remainder)]
///
/// let range = core::range::RangeInclusive::from(3..=11);
/// let mut iter = range.into_iter();
/// assert_eq!(iter.clone().remainder().unwrap(), range);
/// iter.next();
/// assert_eq!(iter.clone().remainder().unwrap(), core::range::RangeInclusive::from(4..=11));
/// iter.by_ref().for_each(drop);
/// assert!(iter.remainder().is_none());
/// ```
#[unstable(feature = "new_range_remainder", issue = "154458")]
pub fn remainder(self) -> Option<RangeInclusive<A>> {
if self.0.is_empty() {
return None;
}
Some(RangeInclusive { start: self.0.start, last: self.0.end })
}
}
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
impl<A: Step> Iterator for RangeInclusiveIter<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
#[inline]
fn count(self) -> usize {
self.0.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<A> {
self.0.nth(n)
}
#[inline]
fn last(self) -> Option<A> {
self.0.last()
}
#[inline]
fn min(self) -> Option<A>
where
A: Ord,
{
self.0.min()
}
#[inline]
fn max(self) -> Option<A>
where
A: Ord,
{
self.0.max()
}
#[inline]
fn is_sorted(self) -> bool {
true
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
self.0.advance_by(n)
}
}
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
impl<A: Step> DoubleEndedIterator for RangeInclusiveIter<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
self.0.next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<A> {
self.0.nth_back(n)
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
self.0.advance_back_by(n)
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: TrustedStep> TrustedLen for RangeInclusiveIter<A> {}
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
impl<A: Step> FusedIterator for RangeInclusiveIter<A> {}
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
impl<A: Step> IntoIterator for RangeInclusive<A> {
type Item = A;
type IntoIter = RangeInclusiveIter<A>;
fn into_iter(self) -> Self::IntoIter {
RangeInclusiveIter(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 RangeIter<$t> { }
)*)
}
macro_rules! range_incl_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
impl ExactSizeIterator for RangeInclusiveIter<$t> { }
)*)
}
range_exact_iter_impl! {
usize u8 u16
isize i8 i16
}
range_incl_exact_iter_impl! {
u8
i8
}
/// By-value [`RangeFrom`] iterator.
#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")]
#[derive(Debug, Clone)]
pub struct RangeFromIter<A> {
start: A,
/// Whether the maximum value of the iterator has yielded.
/// Only used when overflow checks are enabled.
exhausted: bool,
}
impl<A: Step> RangeFromIter<A> {
/// Returns the remainder of the range being iterated over.
///
/// # Examples
///
/// ```
/// #![feature(new_range_remainder)]
///
/// let range = core::range::RangeFrom::from(3..);
/// let mut iter = range.into_iter();
/// assert_eq!(iter.clone().remainder(), range);
/// iter.next();
/// assert_eq!(iter.remainder(), core::range::RangeFrom::from(4..));
/// ```
#[inline]
#[rustc_inherit_overflow_checks]
#[unstable(feature = "new_range_remainder", issue = "154458")]
pub fn remainder(self) -> RangeFrom<A> {
// Need to handle this case even if overflow-checks are disabled,
// because a `RangeFromIter` could be exhausted in a crate with
// overflow-checks enabled, but then passed to a crate with them
// disabled before this is called.
if self.exhausted {
return RangeFrom { start: Step::forward(self.start, 1) };
}
RangeFrom { start: self.start }
}
}
#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")]
impl<A: Step> Iterator for RangeFromIter<A> {
type Item = A;
#[inline]
#[rustc_inherit_overflow_checks]
fn next(&mut self) -> Option<A> {
if self.exhausted {
// This should panic if overflow checks are enabled, since
// `forward_checked` returned `None` in prior iteration.
self.start = Step::forward(self.start.clone(), 1);
// If we get here, if means this iterator was exhausted by a crate
// with overflow-checks enabled, but now we're iterating in a crate with
// overflow-checks disabled. Since we successfully incremented `self.start`
// above (in many cases this will wrap around to MIN), we now unset
// the flag so we don't repeat this process in the next iteration.
//
// This could also happen if `forward_checked` returned None but
// (for whatever reason, not applicable to any std implementors)
// `forward` doesn't panic when overflow-checks are enabled. In that
// case, this is also the correct behavior.
self.exhausted = false;
}
if intrinsics::overflow_checks() {
let Some(n) = Step::forward_checked(self.start.clone(), 1) else {
self.exhausted = true;
return Some(self.start.clone());
};
return Some(mem::replace(&mut self.start, n));
}
let n = Step::forward(self.start.clone(), 1);
Some(mem::replace(&mut self.start, n))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
#[inline]
#[rustc_inherit_overflow_checks]
fn nth(&mut self, n: usize) -> Option<A> {
// Typically `forward` will cause an overflow-check panic here,
// but unset the exhausted flag to handle the uncommon cases.
// See the comments in `next` for more details.
if self.exhausted {
self.start = Step::forward(self.start.clone(), 1);
self.exhausted = false;
}
if intrinsics::overflow_checks() {
let plus_n = Step::forward(self.start.clone(), n);
if let Some(plus_n1) = Step::forward_checked(plus_n.clone(), 1) {
self.start = plus_n1;
} else {
self.start = plus_n.clone();
self.exhausted = true;
}
return Some(plus_n);
}
let plus_n = Step::forward(self.start.clone(), n);
self.start = Step::forward(plus_n.clone(), 1);
Some(plus_n)
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: TrustedStep> TrustedLen for RangeFromIter<A> {}
#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")]
impl<A: Step> FusedIterator for RangeFromIter<A> {}
#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")]
impl<A: Step> IntoIterator for RangeFrom<A> {
type Item = A;
type IntoIter = RangeFromIter<A>;
fn into_iter(self) -> Self::IntoIter {
RangeFromIter { start: self.start, exhausted: false }
}
}