Skip to content

Commit f1eef5c

Browse files
committed
Add Iterator::collect_into and impl Extend for &mut Extend
1 parent 29f5c69 commit f1eef5c

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

src/libcore/iter/iterator.rs

+41
Original file line numberDiff line numberDiff line change
@@ -2463,6 +2463,47 @@ pub trait Iterator {
24632463
}
24642464
}
24652465
}
2466+
2467+
/// Collects all items from iterator into a collection.
2468+
///
2469+
/// This method consumes the iterator and includes all its items to the
2470+
/// passed collection. The collection is then returned, so the call chain
2471+
/// can be continued. Collections can be passed and returned either by
2472+
/// value or by mutable reference.
2473+
///
2474+
/// This method is a counter-part of [Extend::extend](trait.Extend.html),
2475+
/// but instead of being called on collection, it's called on iterator.
2476+
///
2477+
/// # Examples
2478+
/// Basic usage on collection passed by value
2479+
///
2480+
/// ```
2481+
/// let result = (3..5).collect_into(vec![1, 2]);
2482+
/// assert_eq!(vec![1, 2, 3, 4], result);
2483+
/// ```
2484+
/// More complex usage on collection passed by mutable reference
2485+
///
2486+
/// ```
2487+
/// let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43];
2488+
/// let mut vec_3 = vec![33, 53];
2489+
/// let vec_103 = primes.into_iter()
2490+
/// .cloned()
2491+
/// .filter(|p| p % 10 == 3)
2492+
/// .collect_into(&mut vec_3)
2493+
/// .iter()
2494+
/// .map(|i| i + 100)
2495+
/// .collect::<Vec<_>>();
2496+
/// assert_eq!(vec![33, 53, 3, 13, 23, 43], vec_3);
2497+
/// assert_eq!(vec![133, 153, 103, 113, 123, 143], vec_103);
2498+
/// ```
2499+
#[unstable(feature = "collect_into", issue = "0")]
2500+
fn collect_into<E>(self, mut collection: E) -> E where
2501+
E: Extend<Self::Item>,
2502+
Self: Sized
2503+
{
2504+
collection.extend(self);
2505+
collection
2506+
}
24662507
}
24672508

24682509
/// Select an element from an iterator based on the given "projection"

src/libcore/iter/traits.rs

+12
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ impl<I: Iterator> IntoIterator for I {
267267
/// or, in the case of collections that permit multiple entries with equal
268268
/// keys, that entry is inserted.
269269
///
270+
/// When extending with items from [Iterator](trait.Iterator.html), it's often
271+
/// more convenient to use
272+
/// [Iterator::collect_into](trait.Iterator.html#method.collect_into). It works
273+
/// exactly the same way, but is called on series instead of collection.
274+
///
270275
/// # Examples
271276
///
272277
/// Basic usage:
@@ -352,6 +357,13 @@ pub trait Extend<A> {
352357
fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T);
353358
}
354359

360+
#[unstable(feature = "collect_into", issue = "0")]
361+
impl <'a, A, E: Extend<A>> Extend<A> for &'a mut E {
362+
fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
363+
(*self).extend(iter)
364+
}
365+
}
366+
355367
/// An iterator able to yield elements from both ends.
356368
///
357369
/// Something that implements `DoubleEndedIterator` has one extra capability

src/libcore/tests/iter.rs

+28
Original file line numberDiff line numberDiff line change
@@ -2084,3 +2084,31 @@ fn test_monad_laws_associativity() {
20842084
assert_eq!((0..10).flat_map(f).flat_map(g).sum::<usize>(),
20852085
(0..10).flat_map(|x| f(x).flat_map(g)).sum::<usize>());
20862086
}
2087+
2088+
#[test]
2089+
fn test_collect_into_passed_by_value() {
2090+
let collection = vec![1, 2];
2091+
2092+
let result = (3..5).collect_into(collection);
2093+
2094+
assert_eq!(vec![1, 2, 3, 4], result);
2095+
}
2096+
2097+
#[test]
2098+
fn test_collect_into_passed_by_mut_ref() {
2099+
let mut collection = vec![1, 2];
2100+
2101+
let result = (3..5).collect_into(&mut collection) as * const _;
2102+
2103+
assert_eq!(&collection as *const _, result);
2104+
assert_eq!(vec![1, 2, 3, 4], collection);
2105+
}
2106+
2107+
#[test]
2108+
fn test_extend_impl_for_mut_ref_extend() {
2109+
let mut collection = vec![1, 2];
2110+
2111+
(&mut collection).extend(3..5);
2112+
2113+
assert_eq!(vec![1, 2, 3, 4], collection);
2114+
}

0 commit comments

Comments
 (0)