Skip to content

Commit 4407049

Browse files
authored
Rollup merge of #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``
2 parents 9b98f1d + 4612658 commit 4407049

33 files changed

+3574
-3466
lines changed

library/core/src/iter/adapters/chain.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
2-
use crate::ops::Try;
3-
use crate::usize;
2+
use crate::{ops::Try, usize};
43

54
/// An iterator that links two iterators together, in a chain.
65
///
+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
2+
use crate::iter::{FusedIterator, TrustedLen};
3+
use crate::ops::Try;
4+
5+
/// An iterator that clones the elements of an underlying iterator.
6+
///
7+
/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
8+
/// documentation for more.
9+
///
10+
/// [`cloned`]: Iterator::cloned
11+
/// [`Iterator`]: trait.Iterator.html
12+
#[stable(feature = "iter_cloned", since = "1.1.0")]
13+
#[must_use = "iterators are lazy and do nothing unless consumed"]
14+
#[derive(Clone, Debug)]
15+
pub struct Cloned<I> {
16+
it: I,
17+
}
18+
19+
impl<I> Cloned<I> {
20+
pub(in crate::iter) fn new(it: I) -> Cloned<I> {
21+
Cloned { it }
22+
}
23+
}
24+
25+
fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
26+
move |acc, elt| f(acc, elt.clone())
27+
}
28+
29+
#[stable(feature = "iter_cloned", since = "1.1.0")]
30+
impl<'a, I, T: 'a> Iterator for Cloned<I>
31+
where
32+
I: Iterator<Item = &'a T>,
33+
T: Clone,
34+
{
35+
type Item = T;
36+
37+
fn next(&mut self) -> Option<T> {
38+
self.it.next().cloned()
39+
}
40+
41+
fn size_hint(&self) -> (usize, Option<usize>) {
42+
self.it.size_hint()
43+
}
44+
45+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
46+
where
47+
Self: Sized,
48+
F: FnMut(B, Self::Item) -> R,
49+
R: Try<Ok = B>,
50+
{
51+
self.it.try_fold(init, clone_try_fold(f))
52+
}
53+
54+
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
55+
where
56+
F: FnMut(Acc, Self::Item) -> Acc,
57+
{
58+
self.it.map(T::clone).fold(init, f)
59+
}
60+
61+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
62+
where
63+
Self: TrustedRandomAccess,
64+
{
65+
// SAFETY: the caller must uphold the contract for
66+
// `Iterator::__iterator_get_unchecked`.
67+
unsafe { try_get_unchecked(&mut self.it, idx).clone() }
68+
}
69+
}
70+
71+
#[stable(feature = "iter_cloned", since = "1.1.0")]
72+
impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
73+
where
74+
I: DoubleEndedIterator<Item = &'a T>,
75+
T: Clone,
76+
{
77+
fn next_back(&mut self) -> Option<T> {
78+
self.it.next_back().cloned()
79+
}
80+
81+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
82+
where
83+
Self: Sized,
84+
F: FnMut(B, Self::Item) -> R,
85+
R: Try<Ok = B>,
86+
{
87+
self.it.try_rfold(init, clone_try_fold(f))
88+
}
89+
90+
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
91+
where
92+
F: FnMut(Acc, Self::Item) -> Acc,
93+
{
94+
self.it.map(T::clone).rfold(init, f)
95+
}
96+
}
97+
98+
#[stable(feature = "iter_cloned", since = "1.1.0")]
99+
impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
100+
where
101+
I: ExactSizeIterator<Item = &'a T>,
102+
T: Clone,
103+
{
104+
fn len(&self) -> usize {
105+
self.it.len()
106+
}
107+
108+
fn is_empty(&self) -> bool {
109+
self.it.is_empty()
110+
}
111+
}
112+
113+
#[stable(feature = "fused", since = "1.26.0")]
114+
impl<'a, I, T: 'a> FusedIterator for Cloned<I>
115+
where
116+
I: FusedIterator<Item = &'a T>,
117+
T: Clone,
118+
{
119+
}
120+
121+
#[doc(hidden)]
122+
#[unstable(feature = "trusted_random_access", issue = "none")]
123+
unsafe impl<I> TrustedRandomAccess for Cloned<I>
124+
where
125+
I: TrustedRandomAccess,
126+
{
127+
#[inline]
128+
fn may_have_side_effect() -> bool {
129+
true
130+
}
131+
}
132+
133+
#[unstable(feature = "trusted_len", issue = "37572")]
134+
unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
135+
where
136+
I: TrustedLen<Item = &'a T>,
137+
T: Clone,
138+
{
139+
}
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
2+
use crate::iter::{FusedIterator, TrustedLen};
3+
use crate::ops::Try;
4+
5+
/// An iterator that copies the elements of an underlying iterator.
6+
///
7+
/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
8+
/// documentation for more.
9+
///
10+
/// [`copied`]: Iterator::copied
11+
/// [`Iterator`]: trait.Iterator.html
12+
#[stable(feature = "iter_copied", since = "1.36.0")]
13+
#[must_use = "iterators are lazy and do nothing unless consumed"]
14+
#[derive(Clone, Debug)]
15+
pub struct Copied<I> {
16+
it: I,
17+
}
18+
19+
impl<I> Copied<I> {
20+
pub(in crate::iter) fn new(it: I) -> Copied<I> {
21+
Copied { it }
22+
}
23+
}
24+
25+
fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
26+
move |acc, &elt| f(acc, elt)
27+
}
28+
29+
fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
30+
move |acc, &elt| f(acc, elt)
31+
}
32+
33+
#[stable(feature = "iter_copied", since = "1.36.0")]
34+
impl<'a, I, T: 'a> Iterator for Copied<I>
35+
where
36+
I: Iterator<Item = &'a T>,
37+
T: Copy,
38+
{
39+
type Item = T;
40+
41+
fn next(&mut self) -> Option<T> {
42+
self.it.next().copied()
43+
}
44+
45+
fn size_hint(&self) -> (usize, Option<usize>) {
46+
self.it.size_hint()
47+
}
48+
49+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
50+
where
51+
Self: Sized,
52+
F: FnMut(B, Self::Item) -> R,
53+
R: Try<Ok = B>,
54+
{
55+
self.it.try_fold(init, copy_try_fold(f))
56+
}
57+
58+
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
59+
where
60+
F: FnMut(Acc, Self::Item) -> Acc,
61+
{
62+
self.it.fold(init, copy_fold(f))
63+
}
64+
65+
fn nth(&mut self, n: usize) -> Option<T> {
66+
self.it.nth(n).copied()
67+
}
68+
69+
fn last(self) -> Option<T> {
70+
self.it.last().copied()
71+
}
72+
73+
fn count(self) -> usize {
74+
self.it.count()
75+
}
76+
77+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
78+
where
79+
Self: TrustedRandomAccess,
80+
{
81+
// SAFETY: the caller must uphold the contract for
82+
// `Iterator::__iterator_get_unchecked`.
83+
*unsafe { try_get_unchecked(&mut self.it, idx) }
84+
}
85+
}
86+
87+
#[stable(feature = "iter_copied", since = "1.36.0")]
88+
impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
89+
where
90+
I: DoubleEndedIterator<Item = &'a T>,
91+
T: Copy,
92+
{
93+
fn next_back(&mut self) -> Option<T> {
94+
self.it.next_back().copied()
95+
}
96+
97+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
98+
where
99+
Self: Sized,
100+
F: FnMut(B, Self::Item) -> R,
101+
R: Try<Ok = B>,
102+
{
103+
self.it.try_rfold(init, copy_try_fold(f))
104+
}
105+
106+
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
107+
where
108+
F: FnMut(Acc, Self::Item) -> Acc,
109+
{
110+
self.it.rfold(init, copy_fold(f))
111+
}
112+
}
113+
114+
#[stable(feature = "iter_copied", since = "1.36.0")]
115+
impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
116+
where
117+
I: ExactSizeIterator<Item = &'a T>,
118+
T: Copy,
119+
{
120+
fn len(&self) -> usize {
121+
self.it.len()
122+
}
123+
124+
fn is_empty(&self) -> bool {
125+
self.it.is_empty()
126+
}
127+
}
128+
129+
#[stable(feature = "iter_copied", since = "1.36.0")]
130+
impl<'a, I, T: 'a> FusedIterator for Copied<I>
131+
where
132+
I: FusedIterator<Item = &'a T>,
133+
T: Copy,
134+
{
135+
}
136+
137+
#[doc(hidden)]
138+
#[unstable(feature = "trusted_random_access", issue = "none")]
139+
unsafe impl<I> TrustedRandomAccess for Copied<I>
140+
where
141+
I: TrustedRandomAccess,
142+
{
143+
#[inline]
144+
fn may_have_side_effect() -> bool {
145+
I::may_have_side_effect()
146+
}
147+
}
148+
149+
#[stable(feature = "iter_copied", since = "1.36.0")]
150+
unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
151+
where
152+
I: TrustedLen<Item = &'a T>,
153+
T: Copy,
154+
{
155+
}
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use crate::{iter::FusedIterator, ops::Try};
2+
3+
/// An iterator that repeats endlessly.
4+
///
5+
/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its
6+
/// documentation for more.
7+
///
8+
/// [`cycle`]: Iterator::cycle
9+
/// [`Iterator`]: trait.Iterator.html
10+
#[derive(Clone, Debug)]
11+
#[must_use = "iterators are lazy and do nothing unless consumed"]
12+
#[stable(feature = "rust1", since = "1.0.0")]
13+
pub struct Cycle<I> {
14+
orig: I,
15+
iter: I,
16+
}
17+
18+
impl<I: Clone> Cycle<I> {
19+
pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
20+
Cycle { orig: iter.clone(), iter }
21+
}
22+
}
23+
24+
#[stable(feature = "rust1", since = "1.0.0")]
25+
impl<I> Iterator for Cycle<I>
26+
where
27+
I: Clone + Iterator,
28+
{
29+
type Item = <I as Iterator>::Item;
30+
31+
#[inline]
32+
fn next(&mut self) -> Option<<I as Iterator>::Item> {
33+
match self.iter.next() {
34+
None => {
35+
self.iter = self.orig.clone();
36+
self.iter.next()
37+
}
38+
y => y,
39+
}
40+
}
41+
42+
#[inline]
43+
fn size_hint(&self) -> (usize, Option<usize>) {
44+
// the cycle iterator is either empty or infinite
45+
match self.orig.size_hint() {
46+
sz @ (0, Some(0)) => sz,
47+
(0, _) => (0, None),
48+
_ => (usize::MAX, None),
49+
}
50+
}
51+
52+
#[inline]
53+
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
54+
where
55+
F: FnMut(Acc, Self::Item) -> R,
56+
R: Try<Ok = Acc>,
57+
{
58+
// fully iterate the current iterator. this is necessary because
59+
// `self.iter` may be empty even when `self.orig` isn't
60+
acc = self.iter.try_fold(acc, &mut f)?;
61+
self.iter = self.orig.clone();
62+
63+
// complete a full cycle, keeping track of whether the cycled
64+
// iterator is empty or not. we need to return early in case
65+
// of an empty iterator to prevent an infinite loop
66+
let mut is_empty = true;
67+
acc = self.iter.try_fold(acc, |acc, x| {
68+
is_empty = false;
69+
f(acc, x)
70+
})?;
71+
72+
if is_empty {
73+
return try { acc };
74+
}
75+
76+
loop {
77+
self.iter = self.orig.clone();
78+
acc = self.iter.try_fold(acc, &mut f)?;
79+
}
80+
}
81+
82+
// No `fold` override, because `fold` doesn't make much sense for `Cycle`,
83+
// and we can't do anything better than the default.
84+
}
85+
86+
#[stable(feature = "fused", since = "1.26.0")]
87+
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}

0 commit comments

Comments
 (0)