Use for_each to extend collections

This updates the `Extend` implementations to use `for_each` for many
collections: `BinaryHeap`, `BTreeMap`, `BTreeSet`, `LinkedList`, `Path`,
`TokenStream`, `VecDeque`, and `Wtf8Buf`.

Folding with `for_each` enables better performance than a `for`-loop for
some iterators, especially if they can just forward to internal
iterators, like `Chain` and `FlatMap` do.
This commit is contained in:
Josh Stone 2019-04-05 14:51:07 -07:00
parent acd8dd6a50
commit 0730a01c5c
8 changed files with 10 additions and 22 deletions

View File

@ -1177,9 +1177,7 @@ impl<T: Ord> BinaryHeap<T> {
self.reserve(lower); self.reserve(lower);
for elem in iterator { iterator.for_each(move |elem| self.push(elem));
self.push(elem);
}
} }
} }

View File

@ -1727,9 +1727,9 @@ impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> { impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
#[inline] #[inline]
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
for (k, v) in iter { iter.into_iter().for_each(move |(k, v)| {
self.insert(k, v); self.insert(k, v);
} });
} }
} }

View File

@ -883,9 +883,9 @@ impl<'a, T> IntoIterator for &'a BTreeSet<T> {
impl<T: Ord> Extend<T> for BTreeSet<T> { impl<T: Ord> Extend<T> for BTreeSet<T> {
#[inline] #[inline]
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) { fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
for elem in iter { iter.into_iter().for_each(move |elem| {
self.insert(elem); self.insert(elem);
} });
} }
} }

View File

@ -1107,9 +1107,7 @@ impl<T> Extend<T> for LinkedList<T> {
impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> { impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> {
default fn spec_extend(&mut self, iter: I) { default fn spec_extend(&mut self, iter: I) {
for elt in iter { iter.into_iter().for_each(move |elt| self.push_back(elt));
self.push_back(elt);
}
} }
} }

View File

@ -2677,9 +2677,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<A> Extend<A> for VecDeque<A> { impl<A> Extend<A> for VecDeque<A> {
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
for elt in iter { iter.into_iter().for_each(move |elt| self.push_back(elt));
self.push_back(elt);
}
} }
} }

View File

@ -160,9 +160,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
impl iter::FromIterator<TokenStream> for TokenStream { impl iter::FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let mut builder = bridge::client::TokenStreamBuilder::new(); let mut builder = bridge::client::TokenStreamBuilder::new();
for stream in streams { streams.into_iter().for_each(|stream| builder.push(stream.0));
builder.push(stream.0);
}
TokenStream(builder.build()) TokenStream(builder.build())
} }
} }

View File

@ -1551,9 +1551,7 @@ impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<P: AsRef<Path>> iter::Extend<P> for PathBuf { impl<P: AsRef<Path>> iter::Extend<P> for PathBuf {
fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
for p in iter { iter.into_iter().for_each(move |p| self.push(p.as_ref()));
self.push(p.as_ref())
}
} }
} }

View File

@ -388,9 +388,7 @@ impl Extend<CodePoint> for Wtf8Buf {
let (low, _high) = iterator.size_hint(); let (low, _high) = iterator.size_hint();
// Lower bound of one byte per code point (ASCII only) // Lower bound of one byte per code point (ASCII only)
self.bytes.reserve(low); self.bytes.reserve(low);
for code_point in iterator { iterator.for_each(move |code_point| self.push(code_point));
self.push(code_point);
}
} }
} }