Rollup merge of #93057 - frengor:iter_collect_into, r=m-ou-se

Add Iterator::collect_into

This PR adds `Iterator::collect_into` as proposed by ``@cormacrelf`` in #48597 (see https://github.com/rust-lang/rust/pull/48597#issuecomment-842083688).
Followup of #92982.

This adds the following method to the Iterator trait:

```rust
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
```
This commit is contained in:
Matthias Krüger 2022-03-09 23:14:11 +01:00 committed by GitHub
commit d5c05fcc8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 0 deletions

View File

@ -1859,6 +1859,77 @@ pub trait Iterator {
try_process(self, |i| i.collect()) try_process(self, |i| i.collect())
} }
/// Collects all the items from an iterator into a collection.
///
/// This method consumes the iterator and adds all its items to the
/// passed collection. The collection is then returned, so the call chain
/// can be continued.
///
/// This is useful when you already have a collection and wants to add
/// the iterator items to it.
///
/// This method is a convenience method to call [Extend::extend](trait.Extend.html),
/// but instead of being called on a collection, it's called on an iterator.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iter_collect_into)]
///
/// let a = [1, 2, 3];
/// let mut vec: Vec::<i32> = vec![0, 1];
///
/// a.iter().map(|&x| x * 2).collect_into(&mut vec);
/// a.iter().map(|&x| x * 10).collect_into(&mut vec);
///
/// assert_eq!(vec![0, 1, 2, 4, 6, 10, 20, 30], vec);
/// ```
///
/// `Vec` can have a manual set capacity to avoid reallocating it:
///
/// ```
/// #![feature(iter_collect_into)]
///
/// let a = [1, 2, 3];
/// let mut vec: Vec::<i32> = Vec::with_capacity(6);
///
/// a.iter().map(|&x| x * 2).collect_into(&mut vec);
/// a.iter().map(|&x| x * 10).collect_into(&mut vec);
///
/// assert_eq!(6, vec.capacity());
/// println!("{:?}", vec);
/// ```
///
/// The returned mutable reference can be used to continue the call chain:
///
/// ```
/// #![feature(iter_collect_into)]
///
/// let a = [1, 2, 3];
/// let mut vec: Vec::<i32> = Vec::with_capacity(6);
///
/// let count = a.iter().collect_into(&mut vec).iter().count();
///
/// assert_eq!(count, vec.len());
/// println!("Vec len is {}", count);
///
/// let count = a.iter().collect_into(&mut vec).iter().count();
///
/// assert_eq!(count, vec.len());
/// println!("Vec len now is {}", count);
/// ```
#[inline]
#[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")]
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
where
Self: Sized,
{
collection.extend(self);
collection
}
/// Consumes an iterator, creating two collections from it. /// Consumes an iterator, creating two collections from it.
/// ///
/// The predicate passed to `partition()` can return `true`, or `false`. /// The predicate passed to `partition()` can return `true`, or `false`.

View File

@ -543,6 +543,14 @@ fn test_try_collect() {
assert_eq!(v, Continue(vec![4, 5])); assert_eq!(v, Continue(vec![4, 5]));
} }
#[test]
fn test_collect_into() {
let a = vec![1, 2, 3, 4, 5];
let mut b = Vec::new();
a.iter().cloned().collect_into(&mut b);
assert!(a == b);
}
// just tests by whether or not this compiles // just tests by whether or not this compiles
fn _empty_impl_all_auto_traits<T>() { fn _empty_impl_all_auto_traits<T>() {
use std::panic::{RefUnwindSafe, UnwindSafe}; use std::panic::{RefUnwindSafe, UnwindSafe};

View File

@ -62,6 +62,7 @@
#![feature(slice_partition_dedup)] #![feature(slice_partition_dedup)]
#![feature(int_log)] #![feature(int_log)]
#![feature(iter_advance_by)] #![feature(iter_advance_by)]
#![feature(iter_collect_into)]
#![feature(iter_partition_in_place)] #![feature(iter_partition_in_place)]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]
#![feature(iter_is_partitioned)] #![feature(iter_is_partitioned)]