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::ffi::{OsStr, OsString};
use std::hash::{BuildHasher, Hash};
use std::rc::Rc;
use std::sync::Arc;
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
}
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)
}
}
impl<T> FromParallelIterator<T> for Box<[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()
}
}
impl<T> FromParallelIterator<T> for Rc<[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()
}
}
impl<T> FromParallelIterator<T> for Arc<[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()
}
}
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()
}
}
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()
}
}
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)
}
}
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)
}
}
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)
}
}
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)
}
}
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)
}
}
macro_rules! collect_string {
($desc:literal, $item:ty $(, $a:lifetime)?) => {
#[doc = concat!("Collects ", $desc, " from a parallel iterator into a string.")]
impl$(<$a>)? FromParallelIterator<$item> for String {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = $item>,
{
collect_extended(par_iter)
}
}
#[doc = concat!("Collects ", $desc, " from a parallel iterator into a boxed string.")]
impl$(<$a>)? FromParallelIterator<$item> for Box<str> {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = $item>,
{
String::from_par_iter(par_iter).into_boxed_str()
}
}
}
}
collect_string!("characters", char);
collect_string!("characters", &'a char, 'a);
collect_string!("string slices", &'a str, 'a);
collect_string!("string slices", Cow<'a, str>, 'a);
collect_string!("boxed strings", Box<str>);
collect_string!("strings", String);
impl<'a> FromParallelIterator<&'a OsStr> for OsString {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = &'a OsStr>,
{
collect_extended(par_iter)
}
}
impl FromParallelIterator<OsString> for OsString {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = OsString>,
{
collect_extended(par_iter)
}
}
impl<'a> FromParallelIterator<Cow<'a, OsStr>> for OsString {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = Cow<'a, OsStr>>,
{
collect_extended(par_iter)
}
}
impl<'a, C, T> FromParallelIterator<T> for Cow<'a, C>
where
C: ToOwned<Owned: FromParallelIterator<T>> + ?Sized,
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))
}
}
impl FromParallelIterator<()> for () {
fn from_par_iter<I>(par_iter: I) -> Self
where
I: IntoParallelIterator<Item = ()>,
{
par_iter.into_par_iter().drive_unindexed(NoopConsumer)
}
}