diff --git a/src/iter/extend.rs b/src/iter/extend.rs index f38c795ac..e2ade9344 100644 --- a/src/iter/extend.rs +++ b/src/iter/extend.rs @@ -1,5 +1,6 @@ use super::{ParallelExtend, IntoParallelIterator, ParallelIterator}; +use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::{BuildHasher, Hash}; use std::collections::LinkedList; @@ -262,6 +263,36 @@ impl ParallelExtend for String { } } +/// Extend a string with string slices from a parallel iterator. +impl<'a> ParallelExtend> for String { + fn par_extend(&mut self, par_iter: I) + where I: IntoParallelIterator> + { + // This is like `extend`, but `Extend> for String` + // wasn't added until Rust 1.19, so we can't use it directly yet. + let list = par_iter + .into_par_iter() + .fold(Vec::new, |mut vec, elem| { + vec.push(elem); + vec + }) + .map(|vec| { + let mut list = LinkedList::new(); + list.push_back(vec); + list + }) + .reduce(LinkedList::new, |mut list1, mut list2| { + list1.append(&mut list2); + list1 + }); + + self.reserve(str_len(&list)); + for vec in list { + self.extend(vec.iter().map(|cow| &**cow)); + } + } +} + /// Extend a deque with items from a parallel iterator. impl ParallelExtend for VecDeque diff --git a/src/iter/from_par_iter.rs b/src/iter/from_par_iter.rs index 13176f7ac..3c4a211f4 100644 --- a/src/iter/from_par_iter.rs +++ b/src/iter/from_par_iter.rs @@ -154,6 +154,15 @@ impl FromParallelIterator for String { } } +/// Collect 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) + } +} + /// Collect an arbitrary `Cow` collection. /// /// Note, the standard library only has `FromIterator` for `Cow<'a, str>` and