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
This commit is contained in:
The8472 2019-11-23 18:59:18 +01:00
parent 085eb20a61
commit 21a17d105c
2 changed files with 136 additions and 0 deletions

View File

@ -3,6 +3,8 @@
use crate::iter::TrustedRandomAccess;
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
use crate::ops::Try;
use crate::iter::adapters::SourceIter;
use super::InPlaceIterable;
/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
@ -517,3 +519,24 @@ fn is_empty(&self) -> bool
unchecked!(self).is_empty()
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
match self.iter {
Some(ref mut iter) => SourceIter::as_inner(iter),
// SAFETY: the specialized iterator never sets `None`
None => unsafe { intrinsics::unreachable() },
}
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}

View File

@ -1152,6 +1152,22 @@ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P> where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
/// An iterator that uses `f` to both filter and map elements from `iter`.
///
/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
@ -1278,6 +1294,23 @@ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
#[stable(feature = "fused", since = "1.26.0")]
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F> where
F: FnMut(I::Item) -> Option<B>,
I: SourceIter<Source = S>
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
/// An iterator that yields the current count and the element during iteration.
///
/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
@ -1910,6 +1943,22 @@ impl<I, P> FusedIterator for SkipWhile<I, P>
{
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P> where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where F: FnMut(&I::Item) -> bool {}
/// An iterator that only accepts elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
@ -2101,6 +2150,23 @@ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P> where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where F: FnMut(&I::Item) -> bool {}
/// An iterator that skips over `n` elements of `iter`.
///
/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
@ -2410,6 +2476,19 @@ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I> where I: SourceIter<Source = S> {
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I>
where
@ -2574,6 +2653,24 @@ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
where I: SourceIter<Source = S>,
F: FnMut(&mut St, I::Item) -> Option<B>,
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F>
where F: FnMut(&mut St, I::Item) -> Option<B>,
{}
/// An iterator that calls a function with a reference to each element before
/// yielding it.
///
@ -2720,6 +2817,22 @@ fn is_empty(&self) -> bool {
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F> where
F: FnMut(&I::Item),
I: SourceIter<Source = S>
{
type Source = S;
#[inline]
fn as_inner(&mut self) -> &mut S {
SourceIter::as_inner(&mut self.iter)
}
}
#[unstable(issue = "0", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}
/// An iterator adapter that produces output as long as the underlying
/// iterator produces `Result::Ok` values.
///