forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#77697 - WaffleLapkin:iter_split_adaptors, r…
…=m-ou-se Split each iterator adapter and source into individual modules This PR creates individual modules for each iterator adapter and iterator source. This is done to enhance the readability of corresponding modules (`adapters/mod.rs` and `sources.rs`) which were hard to navigate and read because of lots of repeated lines (e.g.: `adapters/mod.rs` was 3k lines long). This is also in line with some adapters which already had their own modules (`Flatten`, `FlatMap`, `Chain`, `Zip`, `Fuse`). This PR also makes `Take`s adapter fields private (I have no idea why they were `pub(super)` before). r? `@LukasKalbertodt`
- Loading branch information
Showing
33 changed files
with
3,574 additions
and
3,466 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess}; | ||
use crate::iter::{FusedIterator, TrustedLen}; | ||
use crate::ops::Try; | ||
|
||
/// An iterator that clones the elements of an underlying iterator. | ||
/// | ||
/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its | ||
/// documentation for more. | ||
/// | ||
/// [`cloned`]: Iterator::cloned | ||
/// [`Iterator`]: trait.Iterator.html | ||
#[stable(feature = "iter_cloned", since = "1.1.0")] | ||
#[must_use = "iterators are lazy and do nothing unless consumed"] | ||
#[derive(Clone, Debug)] | ||
pub struct Cloned<I> { | ||
it: I, | ||
} | ||
|
||
impl<I> Cloned<I> { | ||
pub(in crate::iter) fn new(it: I) -> Cloned<I> { | ||
Cloned { it } | ||
} | ||
} | ||
|
||
fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R { | ||
move |acc, elt| f(acc, elt.clone()) | ||
} | ||
|
||
#[stable(feature = "iter_cloned", since = "1.1.0")] | ||
impl<'a, I, T: 'a> Iterator for Cloned<I> | ||
where | ||
I: Iterator<Item = &'a T>, | ||
T: Clone, | ||
{ | ||
type Item = T; | ||
|
||
fn next(&mut self) -> Option<T> { | ||
self.it.next().cloned() | ||
} | ||
|
||
fn size_hint(&self) -> (usize, Option<usize>) { | ||
self.it.size_hint() | ||
} | ||
|
||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R | ||
where | ||
Self: Sized, | ||
F: FnMut(B, Self::Item) -> R, | ||
R: Try<Ok = B>, | ||
{ | ||
self.it.try_fold(init, clone_try_fold(f)) | ||
} | ||
|
||
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc | ||
where | ||
F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
self.it.map(T::clone).fold(init, f) | ||
} | ||
|
||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T | ||
where | ||
Self: TrustedRandomAccess, | ||
{ | ||
// SAFETY: the caller must uphold the contract for | ||
// `Iterator::__iterator_get_unchecked`. | ||
unsafe { try_get_unchecked(&mut self.it, idx).clone() } | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_cloned", since = "1.1.0")] | ||
impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I> | ||
where | ||
I: DoubleEndedIterator<Item = &'a T>, | ||
T: Clone, | ||
{ | ||
fn next_back(&mut self) -> Option<T> { | ||
self.it.next_back().cloned() | ||
} | ||
|
||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R | ||
where | ||
Self: Sized, | ||
F: FnMut(B, Self::Item) -> R, | ||
R: Try<Ok = B>, | ||
{ | ||
self.it.try_rfold(init, clone_try_fold(f)) | ||
} | ||
|
||
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc | ||
where | ||
F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
self.it.map(T::clone).rfold(init, f) | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_cloned", since = "1.1.0")] | ||
impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I> | ||
where | ||
I: ExactSizeIterator<Item = &'a T>, | ||
T: Clone, | ||
{ | ||
fn len(&self) -> usize { | ||
self.it.len() | ||
} | ||
|
||
fn is_empty(&self) -> bool { | ||
self.it.is_empty() | ||
} | ||
} | ||
|
||
#[stable(feature = "fused", since = "1.26.0")] | ||
impl<'a, I, T: 'a> FusedIterator for Cloned<I> | ||
where | ||
I: FusedIterator<Item = &'a T>, | ||
T: Clone, | ||
{ | ||
} | ||
|
||
#[doc(hidden)] | ||
#[unstable(feature = "trusted_random_access", issue = "none")] | ||
unsafe impl<I> TrustedRandomAccess for Cloned<I> | ||
where | ||
I: TrustedRandomAccess, | ||
{ | ||
#[inline] | ||
fn may_have_side_effect() -> bool { | ||
true | ||
} | ||
} | ||
|
||
#[unstable(feature = "trusted_len", issue = "37572")] | ||
unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I> | ||
where | ||
I: TrustedLen<Item = &'a T>, | ||
T: Clone, | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess}; | ||
use crate::iter::{FusedIterator, TrustedLen}; | ||
use crate::ops::Try; | ||
|
||
/// An iterator that copies the elements of an underlying iterator. | ||
/// | ||
/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its | ||
/// documentation for more. | ||
/// | ||
/// [`copied`]: Iterator::copied | ||
/// [`Iterator`]: trait.Iterator.html | ||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
#[must_use = "iterators are lazy and do nothing unless consumed"] | ||
#[derive(Clone, Debug)] | ||
pub struct Copied<I> { | ||
it: I, | ||
} | ||
|
||
impl<I> Copied<I> { | ||
pub(in crate::iter) fn new(it: I) -> Copied<I> { | ||
Copied { it } | ||
} | ||
} | ||
|
||
fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc { | ||
move |acc, &elt| f(acc, elt) | ||
} | ||
|
||
fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R { | ||
move |acc, &elt| f(acc, elt) | ||
} | ||
|
||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
impl<'a, I, T: 'a> Iterator for Copied<I> | ||
where | ||
I: Iterator<Item = &'a T>, | ||
T: Copy, | ||
{ | ||
type Item = T; | ||
|
||
fn next(&mut self) -> Option<T> { | ||
self.it.next().copied() | ||
} | ||
|
||
fn size_hint(&self) -> (usize, Option<usize>) { | ||
self.it.size_hint() | ||
} | ||
|
||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R | ||
where | ||
Self: Sized, | ||
F: FnMut(B, Self::Item) -> R, | ||
R: Try<Ok = B>, | ||
{ | ||
self.it.try_fold(init, copy_try_fold(f)) | ||
} | ||
|
||
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc | ||
where | ||
F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
self.it.fold(init, copy_fold(f)) | ||
} | ||
|
||
fn nth(&mut self, n: usize) -> Option<T> { | ||
self.it.nth(n).copied() | ||
} | ||
|
||
fn last(self) -> Option<T> { | ||
self.it.last().copied() | ||
} | ||
|
||
fn count(self) -> usize { | ||
self.it.count() | ||
} | ||
|
||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T | ||
where | ||
Self: TrustedRandomAccess, | ||
{ | ||
// SAFETY: the caller must uphold the contract for | ||
// `Iterator::__iterator_get_unchecked`. | ||
*unsafe { try_get_unchecked(&mut self.it, idx) } | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I> | ||
where | ||
I: DoubleEndedIterator<Item = &'a T>, | ||
T: Copy, | ||
{ | ||
fn next_back(&mut self) -> Option<T> { | ||
self.it.next_back().copied() | ||
} | ||
|
||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R | ||
where | ||
Self: Sized, | ||
F: FnMut(B, Self::Item) -> R, | ||
R: Try<Ok = B>, | ||
{ | ||
self.it.try_rfold(init, copy_try_fold(f)) | ||
} | ||
|
||
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc | ||
where | ||
F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
self.it.rfold(init, copy_fold(f)) | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
impl<'a, I, T: 'a> ExactSizeIterator for Copied<I> | ||
where | ||
I: ExactSizeIterator<Item = &'a T>, | ||
T: Copy, | ||
{ | ||
fn len(&self) -> usize { | ||
self.it.len() | ||
} | ||
|
||
fn is_empty(&self) -> bool { | ||
self.it.is_empty() | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
impl<'a, I, T: 'a> FusedIterator for Copied<I> | ||
where | ||
I: FusedIterator<Item = &'a T>, | ||
T: Copy, | ||
{ | ||
} | ||
|
||
#[doc(hidden)] | ||
#[unstable(feature = "trusted_random_access", issue = "none")] | ||
unsafe impl<I> TrustedRandomAccess for Copied<I> | ||
where | ||
I: TrustedRandomAccess, | ||
{ | ||
#[inline] | ||
fn may_have_side_effect() -> bool { | ||
I::may_have_side_effect() | ||
} | ||
} | ||
|
||
#[stable(feature = "iter_copied", since = "1.36.0")] | ||
unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I> | ||
where | ||
I: TrustedLen<Item = &'a T>, | ||
T: Copy, | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
use crate::{iter::FusedIterator, ops::Try}; | ||
|
||
/// An iterator that repeats endlessly. | ||
/// | ||
/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its | ||
/// documentation for more. | ||
/// | ||
/// [`cycle`]: Iterator::cycle | ||
/// [`Iterator`]: trait.Iterator.html | ||
#[derive(Clone, Debug)] | ||
#[must_use = "iterators are lazy and do nothing unless consumed"] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct Cycle<I> { | ||
orig: I, | ||
iter: I, | ||
} | ||
|
||
impl<I: Clone> Cycle<I> { | ||
pub(in crate::iter) fn new(iter: I) -> Cycle<I> { | ||
Cycle { orig: iter.clone(), iter } | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<I> Iterator for Cycle<I> | ||
where | ||
I: Clone + Iterator, | ||
{ | ||
type Item = <I as Iterator>::Item; | ||
|
||
#[inline] | ||
fn next(&mut self) -> Option<<I as Iterator>::Item> { | ||
match self.iter.next() { | ||
None => { | ||
self.iter = self.orig.clone(); | ||
self.iter.next() | ||
} | ||
y => y, | ||
} | ||
} | ||
|
||
#[inline] | ||
fn size_hint(&self) -> (usize, Option<usize>) { | ||
// the cycle iterator is either empty or infinite | ||
match self.orig.size_hint() { | ||
sz @ (0, Some(0)) => sz, | ||
(0, _) => (0, None), | ||
_ => (usize::MAX, None), | ||
} | ||
} | ||
|
||
#[inline] | ||
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R | ||
where | ||
F: FnMut(Acc, Self::Item) -> R, | ||
R: Try<Ok = Acc>, | ||
{ | ||
// fully iterate the current iterator. this is necessary because | ||
// `self.iter` may be empty even when `self.orig` isn't | ||
acc = self.iter.try_fold(acc, &mut f)?; | ||
self.iter = self.orig.clone(); | ||
|
||
// complete a full cycle, keeping track of whether the cycled | ||
// iterator is empty or not. we need to return early in case | ||
// of an empty iterator to prevent an infinite loop | ||
let mut is_empty = true; | ||
acc = self.iter.try_fold(acc, |acc, x| { | ||
is_empty = false; | ||
f(acc, x) | ||
})?; | ||
|
||
if is_empty { | ||
return try { acc }; | ||
} | ||
|
||
loop { | ||
self.iter = self.orig.clone(); | ||
acc = self.iter.try_fold(acc, &mut f)?; | ||
} | ||
} | ||
|
||
// No `fold` override, because `fold` doesn't make much sense for `Cycle`, | ||
// and we can't do anything better than the default. | ||
} | ||
|
||
#[stable(feature = "fused", since = "1.26.0")] | ||
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {} |
Oops, something went wrong.