aboutsummaryrefslogtreecommitdiff
path: root/src/iter/from_par_iter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/iter/from_par_iter.rs')
-rw-r--r--src/iter/from_par_iter.rs228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/iter/from_par_iter.rs b/src/iter/from_par_iter.rs
new file mode 100644
index 0000000..3240f32
--- /dev/null
+++ b/src/iter/from_par_iter.rs
@@ -0,0 +1,228 @@
+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};
+
+/// Creates an empty default collection and extends it.
+fn collect_extended<C, I>(par_iter: I) -> C
+where
+ I: IntoParallelIterator,
+ C: ParallelExtend<I::Item> + Default,
+{
+ let mut collection = C::default();
+ collection.par_extend(par_iter);
+ collection
+}
+
+/// Collects items from a parallel iterator into a vector.
+impl<T> FromParallelIterator<T> for Vec<T>
+where
+ T: Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = T>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects items from a parallel iterator into a vecdeque.
+impl<T> FromParallelIterator<T> for VecDeque<T>
+where
+ T: Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = T>,
+ {
+ 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<T> FromParallelIterator<T> for BinaryHeap<T>
+where
+ T: Ord + Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = T>,
+ {
+ Vec::from_par_iter(par_iter).into()
+ }
+}
+
+/// Collects items from a parallel iterator into a freshly allocated
+/// linked list.
+impl<T> FromParallelIterator<T> for LinkedList<T>
+where
+ T: Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = T>,
+ {
+ 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<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S>
+where
+ K: Eq + Hash + Send,
+ V: Send,
+ S: BuildHasher + Default + Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = (K, V)>,
+ {
+ 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<K, V> FromParallelIterator<(K, V)> for BTreeMap<K, V>
+where
+ K: Ord + Send,
+ V: Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = (K, V)>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects values from a parallel iterator into a hashset.
+impl<V, S> FromParallelIterator<V> for HashSet<V, S>
+where
+ V: Eq + Hash + Send,
+ S: BuildHasher + Default + Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = V>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects values from a parallel iterator into a btreeset.
+impl<V> FromParallelIterator<V> for BTreeSet<V>
+where
+ V: Send + Ord,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = V>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects characters from a parallel iterator into a string.
+impl FromParallelIterator<char> for String {
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = char>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects characters from a parallel iterator into a string.
+impl<'a> FromParallelIterator<&'a char> for String {
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = &'a char>,
+ {
+ 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<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = &'a str>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects strings from a parallel iterator into one large string.
+impl FromParallelIterator<String> for String {
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = String>,
+ {
+ collect_extended(par_iter)
+ }
+}
+
+/// Collects string slices from a parallel iterator into a string.
+impl<'a> FromParallelIterator<Cow<'a, str>> for String {
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = Cow<'a, str>>,
+ {
+ 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<T> for Cow<'a, C>
+where
+ C: ToOwned,
+ C::Owned: FromParallelIterator<T>,
+ T: Send,
+{
+ fn from_par_iter<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = T>,
+ {
+ 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<I>(par_iter: I) -> Self
+ where
+ I: IntoParallelIterator<Item = ()>,
+ {
+ par_iter.into_par_iter().drive_unindexed(NoopConsumer)
+ }
+}