use super::noop::NoopConsumer; use super::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator}; use std::borrow::Cow; use std::collections::LinkedList; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BinaryHeap, VecDeque}; use std::hash::{BuildHasher, Hash}; use std::rc::Rc; use std::sync::Arc; /// Creates an empty default collection and extends it. fn collect_extended(par_iter: I) -> C where I: IntoParallelIterator, C: ParallelExtend + Default, { let mut collection = C::default(); collection.par_extend(par_iter); collection } /// Collects items from a parallel iterator into a vector. impl FromParallelIterator for Vec where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects items from a parallel iterator into a boxed slice. impl FromParallelIterator for Box<[T]> where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Vec::from_par_iter(par_iter).into() } } /// Collects items from a parallel iterator into a reference-counted slice. impl FromParallelIterator for Rc<[T]> where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Vec::from_par_iter(par_iter).into() } } /// Collects items from a parallel iterator into an atomically-reference-counted slice. impl FromParallelIterator for Arc<[T]> where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Vec::from_par_iter(par_iter).into() } } /// Collects items from a parallel iterator into a vecdeque. impl FromParallelIterator for VecDeque where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Vec::from_par_iter(par_iter).into() } } /// Collects items from a parallel iterator into a binaryheap. /// The heap-ordering is calculated serially after all items are collected. impl FromParallelIterator for BinaryHeap where T: Ord + Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Vec::from_par_iter(par_iter).into() } } /// Collects items from a parallel iterator into a freshly allocated /// linked list. impl FromParallelIterator for LinkedList where T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects (key, value) pairs from a parallel iterator into a /// hashmap. If multiple pairs correspond to the same key, then the /// ones produced earlier in the parallel iterator will be /// overwritten, just as with a sequential iterator. impl FromParallelIterator<(K, V)> for HashMap where K: Eq + Hash + Send, V: Send, S: BuildHasher + Default + Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects (key, value) pairs from a parallel iterator into a /// btreemap. If multiple pairs correspond to the same key, then the /// ones produced earlier in the parallel iterator will be /// overwritten, just as with a sequential iterator. impl FromParallelIterator<(K, V)> for BTreeMap where K: Ord + Send, V: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects values from a parallel iterator into a hashset. impl FromParallelIterator for HashSet where V: Eq + Hash + Send, S: BuildHasher + Default + Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects values from a parallel iterator into a btreeset. impl FromParallelIterator for BTreeSet where V: Send + Ord, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects characters from a parallel iterator into a string. impl FromParallelIterator for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects characters from a parallel iterator into a string. impl<'a> FromParallelIterator<&'a char> for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects string slices from a parallel iterator into a string. impl<'a> FromParallelIterator<&'a str> for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects strings from a parallel iterator into one large string. impl FromParallelIterator for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { collect_extended(par_iter) } } /// Collects boxed strings from a parallel iterator into one large string. impl FromParallelIterator> for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator>, { collect_extended(par_iter) } } /// Collects string slices from a parallel iterator into a string. impl<'a> FromParallelIterator> for String { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator>, { collect_extended(par_iter) } } /// Collects an arbitrary `Cow` collection. /// /// Note, the standard library only has `FromIterator` for `Cow<'a, str>` and /// `Cow<'a, [T]>`, because no one thought to add a blanket implementation /// before it was stabilized. impl<'a, C: ?Sized, T> FromParallelIterator for Cow<'a, C> where C: ToOwned, C::Owned: FromParallelIterator, T: Send, { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { Cow::Owned(C::Owned::from_par_iter(par_iter)) } } /// Collapses all unit items from a parallel iterator into one. /// /// This is more useful when combined with higher-level abstractions, like /// collecting to a `Result<(), E>` where you only care about errors: /// /// ``` /// use std::io::*; /// use rayon::prelude::*; /// /// let data = vec![1, 2, 3, 4, 5]; /// let res: Result<()> = data.par_iter() /// .map(|x| writeln!(stdout(), "{}", x)) /// .collect(); /// assert!(res.is_ok()); /// ``` impl FromParallelIterator<()> for () { fn from_par_iter(par_iter: I) -> Self where I: IntoParallelIterator, { par_iter.into_par_iter().drive_unindexed(NoopConsumer) } }