Skip to content

Commit 21a17d1

Browse files
committed
support in-place iteration for most adapters
`Take` is not included since users probably call it with small constants and it doesn't make sense to hold onto huge allocations in that case
1 parent 085eb20 commit 21a17d1

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use crate::iter::adapters::zip::try_get_unchecked;
33
use crate::iter::TrustedRandomAccess;
44
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
55
use crate::ops::Try;
6+
use crate::iter::adapters::SourceIter;
7+
use super::InPlaceIterable;
68

79
/// An iterator that yields `None` forever after the underlying iterator
810
/// yields `None` once.
@@ -517,3 +519,24 @@ where
517519
unchecked!(self).is_empty()
518520
}
519521
}
522+
523+
524+
#[unstable(issue = "0", feature = "inplace_iteration")]
525+
unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
526+
where
527+
I: SourceIter<Source = S>,
528+
{
529+
type Source = S;
530+
531+
#[inline]
532+
fn as_inner(&mut self) -> &mut S {
533+
match self.iter {
534+
Some(ref mut iter) => SourceIter::as_inner(iter),
535+
// SAFETY: the specialized iterator never sets `None`
536+
None => unsafe { intrinsics::unreachable() },
537+
}
538+
}
539+
}
540+
541+
#[unstable(issue = "0", feature = "inplace_iteration")]
542+
unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}

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

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,22 @@ where
11521152
#[stable(feature = "fused", since = "1.26.0")]
11531153
impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
11541154

1155+
#[unstable(issue = "0", feature = "inplace_iteration")]
1156+
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P> where
1157+
P: FnMut(&I::Item) -> bool,
1158+
I: SourceIter<Source = S>
1159+
{
1160+
type Source = S;
1161+
1162+
#[inline]
1163+
fn as_inner(&mut self) -> &mut S {
1164+
SourceIter::as_inner(&mut self.iter)
1165+
}
1166+
}
1167+
1168+
#[unstable(issue = "0", feature = "inplace_iteration")]
1169+
unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
1170+
11551171
/// An iterator that uses `f` to both filter and map elements from `iter`.
11561172
///
11571173
/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
@@ -1278,6 +1294,23 @@ where
12781294
#[stable(feature = "fused", since = "1.26.0")]
12791295
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
12801296

1297+
#[unstable(issue = "0", feature = "inplace_iteration")]
1298+
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F> where
1299+
F: FnMut(I::Item) -> Option<B>,
1300+
I: SourceIter<Source = S>
1301+
{
1302+
type Source = S;
1303+
1304+
#[inline]
1305+
fn as_inner(&mut self) -> &mut S {
1306+
SourceIter::as_inner(&mut self.iter)
1307+
}
1308+
}
1309+
1310+
#[unstable(issue = "0", feature = "inplace_iteration")]
1311+
unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
1312+
1313+
12811314
/// An iterator that yields the current count and the element during iteration.
12821315
///
12831316
/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
@@ -1910,6 +1943,22 @@ where
19101943
{
19111944
}
19121945

1946+
#[unstable(issue = "0", feature = "inplace_iteration")]
1947+
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P> where
1948+
P: FnMut(&I::Item) -> bool,
1949+
I: SourceIter<Source = S>
1950+
{
1951+
type Source = S;
1952+
1953+
#[inline]
1954+
fn as_inner(&mut self) -> &mut S {
1955+
SourceIter::as_inner(&mut self.iter)
1956+
}
1957+
}
1958+
1959+
#[unstable(issue = "0", feature = "inplace_iteration")]
1960+
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where F: FnMut(&I::Item) -> bool {}
1961+
19131962
/// An iterator that only accepts elements while `predicate` returns `true`.
19141963
///
19151964
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
@@ -2101,6 +2150,23 @@ where
21012150
}
21022151
}
21032152

2153+
#[unstable(issue = "0", feature = "inplace_iteration")]
2154+
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P> where
2155+
P: FnMut(&I::Item) -> bool,
2156+
I: SourceIter<Source = S>
2157+
{
2158+
type Source = S;
2159+
2160+
#[inline]
2161+
fn as_inner(&mut self) -> &mut S {
2162+
SourceIter::as_inner(&mut self.iter)
2163+
}
2164+
}
2165+
2166+
#[unstable(issue = "0", feature = "inplace_iteration")]
2167+
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where F: FnMut(&I::Item) -> bool {}
2168+
2169+
21042170
/// An iterator that skips over `n` elements of `iter`.
21052171
///
21062172
/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
@@ -2410,6 +2476,19 @@ where
24102476
}
24112477
}
24122478

2479+
#[unstable(issue = "0", feature = "inplace_iteration")]
2480+
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I> where I: SourceIter<Source = S> {
2481+
type Source = S;
2482+
2483+
#[inline]
2484+
fn as_inner(&mut self) -> &mut S {
2485+
SourceIter::as_inner(&mut self.iter)
2486+
}
2487+
}
2488+
2489+
#[unstable(issue = "0", feature = "inplace_iteration")]
2490+
unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
2491+
24132492
#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
24142493
impl<I> DoubleEndedIterator for Take<I>
24152494
where
@@ -2574,6 +2653,24 @@ where
25742653
}
25752654
}
25762655

2656+
#[unstable(issue = "0", feature = "inplace_iteration")]
2657+
unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
2658+
where I: SourceIter<Source = S>,
2659+
F: FnMut(&mut St, I::Item) -> Option<B>,
2660+
{
2661+
type Source = S;
2662+
2663+
#[inline]
2664+
fn as_inner(&mut self) -> &mut S {
2665+
SourceIter::as_inner(&mut self.iter)
2666+
}
2667+
}
2668+
2669+
#[unstable(issue = "0", feature = "inplace_iteration")]
2670+
unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F>
2671+
where F: FnMut(&mut St, I::Item) -> Option<B>,
2672+
{}
2673+
25772674
/// An iterator that calls a function with a reference to each element before
25782675
/// yielding it.
25792676
///
@@ -2720,6 +2817,22 @@ where
27202817
#[stable(feature = "fused", since = "1.26.0")]
27212818
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
27222819

2820+
#[unstable(issue = "0", feature = "inplace_iteration")]
2821+
unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F> where
2822+
F: FnMut(&I::Item),
2823+
I: SourceIter<Source = S>
2824+
{
2825+
type Source = S;
2826+
2827+
#[inline]
2828+
fn as_inner(&mut self) -> &mut S {
2829+
SourceIter::as_inner(&mut self.iter)
2830+
}
2831+
}
2832+
2833+
#[unstable(issue = "0", feature = "inplace_iteration")]
2834+
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}
2835+
27232836
/// An iterator adapter that produces output as long as the underlying
27242837
/// iterator produces `Result::Ok` values.
27252838
///

0 commit comments

Comments
 (0)