par_iter/iter/
from_par_iter.rs

1use std::{
2    borrow::Cow,
3    collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
4    ffi::{OsStr, OsString},
5    hash::{BuildHasher, Hash},
6    rc::Rc,
7    sync::Arc,
8};
9
10use super::{
11    noop::NoopConsumer, FromParallelIterator, IntoParallelIterator, ParallelExtend,
12    ParallelIterator,
13};
14
15/// Creates an empty default collection and extends it.
16fn collect_extended<C, I>(par_iter: I) -> C
17where
18    I: IntoParallelIterator,
19    C: ParallelExtend<I::Item> + Default,
20{
21    let mut collection = C::default();
22    collection.par_extend(par_iter);
23    collection
24}
25
26/// Collects items from a parallel iterator into a vector.
27impl<T> FromParallelIterator<T> for Vec<T>
28where
29    T: Send,
30{
31    fn from_par_iter<I>(par_iter: I) -> Self
32    where
33        I: IntoParallelIterator<Item = T>,
34    {
35        collect_extended(par_iter)
36    }
37}
38
39/// Collects items from a parallel iterator into a boxed slice.
40impl<T> FromParallelIterator<T> for Box<[T]>
41where
42    T: Send,
43{
44    fn from_par_iter<I>(par_iter: I) -> Self
45    where
46        I: IntoParallelIterator<Item = T>,
47    {
48        Vec::from_par_iter(par_iter).into()
49    }
50}
51
52/// Collects items from a parallel iterator into a reference-counted slice.
53impl<T> FromParallelIterator<T> for Rc<[T]>
54where
55    T: Send,
56{
57    fn from_par_iter<I>(par_iter: I) -> Self
58    where
59        I: IntoParallelIterator<Item = T>,
60    {
61        Vec::from_par_iter(par_iter).into()
62    }
63}
64
65/// Collects items from a parallel iterator into an atomically-reference-counted
66/// slice.
67impl<T> FromParallelIterator<T> for Arc<[T]>
68where
69    T: Send,
70{
71    fn from_par_iter<I>(par_iter: I) -> Self
72    where
73        I: IntoParallelIterator<Item = T>,
74    {
75        Vec::from_par_iter(par_iter).into()
76    }
77}
78
79/// Collects items from a parallel iterator into a vecdeque.
80impl<T> FromParallelIterator<T> for VecDeque<T>
81where
82    T: Send,
83{
84    fn from_par_iter<I>(par_iter: I) -> Self
85    where
86        I: IntoParallelIterator<Item = T>,
87    {
88        Vec::from_par_iter(par_iter).into()
89    }
90}
91
92/// Collects items from a parallel iterator into a binaryheap.
93/// The heap-ordering is calculated serially after all items are collected.
94impl<T> FromParallelIterator<T> for BinaryHeap<T>
95where
96    T: Ord + Send,
97{
98    fn from_par_iter<I>(par_iter: I) -> Self
99    where
100        I: IntoParallelIterator<Item = T>,
101    {
102        Vec::from_par_iter(par_iter).into()
103    }
104}
105
106/// Collects items from a parallel iterator into a freshly allocated
107/// linked list.
108impl<T> FromParallelIterator<T> for LinkedList<T>
109where
110    T: Send,
111{
112    fn from_par_iter<I>(par_iter: I) -> Self
113    where
114        I: IntoParallelIterator<Item = T>,
115    {
116        collect_extended(par_iter)
117    }
118}
119
120/// Collects (key, value) pairs from a parallel iterator into a
121/// hashmap. If multiple pairs correspond to the same key, then the
122/// ones produced earlier in the parallel iterator will be
123/// overwritten, just as with a sequential iterator.
124impl<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S>
125where
126    K: Eq + Hash + Send,
127    V: Send,
128    S: BuildHasher + Default + Send,
129{
130    fn from_par_iter<I>(par_iter: I) -> Self
131    where
132        I: IntoParallelIterator<Item = (K, V)>,
133    {
134        collect_extended(par_iter)
135    }
136}
137
138/// Collects (key, value) pairs from a parallel iterator into a
139/// btreemap. If multiple pairs correspond to the same key, then the
140/// ones produced earlier in the parallel iterator will be
141/// overwritten, just as with a sequential iterator.
142impl<K, V> FromParallelIterator<(K, V)> for BTreeMap<K, V>
143where
144    K: Ord + Send,
145    V: Send,
146{
147    fn from_par_iter<I>(par_iter: I) -> Self
148    where
149        I: IntoParallelIterator<Item = (K, V)>,
150    {
151        collect_extended(par_iter)
152    }
153}
154
155/// Collects values from a parallel iterator into a hashset.
156impl<V, S> FromParallelIterator<V> for HashSet<V, S>
157where
158    V: Eq + Hash + Send,
159    S: BuildHasher + Default + Send,
160{
161    fn from_par_iter<I>(par_iter: I) -> Self
162    where
163        I: IntoParallelIterator<Item = V>,
164    {
165        collect_extended(par_iter)
166    }
167}
168
169/// Collects values from a parallel iterator into a btreeset.
170impl<V> FromParallelIterator<V> for BTreeSet<V>
171where
172    V: Send + Ord,
173{
174    fn from_par_iter<I>(par_iter: I) -> Self
175    where
176        I: IntoParallelIterator<Item = V>,
177    {
178        collect_extended(par_iter)
179    }
180}
181
182/// Collects characters from a parallel iterator into a string.
183impl FromParallelIterator<char> for String {
184    fn from_par_iter<I>(par_iter: I) -> Self
185    where
186        I: IntoParallelIterator<Item = char>,
187    {
188        collect_extended(par_iter)
189    }
190}
191
192/// Collects characters from a parallel iterator into a string.
193impl<'a> FromParallelIterator<&'a char> for String {
194    fn from_par_iter<I>(par_iter: I) -> Self
195    where
196        I: IntoParallelIterator<Item = &'a char>,
197    {
198        collect_extended(par_iter)
199    }
200}
201
202/// Collects string slices from a parallel iterator into a string.
203impl<'a> FromParallelIterator<&'a str> for String {
204    fn from_par_iter<I>(par_iter: I) -> Self
205    where
206        I: IntoParallelIterator<Item = &'a str>,
207    {
208        collect_extended(par_iter)
209    }
210}
211
212/// Collects strings from a parallel iterator into one large string.
213impl FromParallelIterator<String> for String {
214    fn from_par_iter<I>(par_iter: I) -> Self
215    where
216        I: IntoParallelIterator<Item = String>,
217    {
218        collect_extended(par_iter)
219    }
220}
221
222/// Collects boxed strings from a parallel iterator into one large string.
223impl FromParallelIterator<Box<str>> for String {
224    fn from_par_iter<I>(par_iter: I) -> Self
225    where
226        I: IntoParallelIterator<Item = Box<str>>,
227    {
228        collect_extended(par_iter)
229    }
230}
231
232/// Collects string slices from a parallel iterator into a string.
233impl<'a> FromParallelIterator<Cow<'a, str>> for String {
234    fn from_par_iter<I>(par_iter: I) -> Self
235    where
236        I: IntoParallelIterator<Item = Cow<'a, str>>,
237    {
238        collect_extended(par_iter)
239    }
240}
241
242/// Collects OS-string slices from a parallel iterator into an OS-string.
243impl<'a> FromParallelIterator<&'a OsStr> for OsString {
244    fn from_par_iter<I>(par_iter: I) -> Self
245    where
246        I: IntoParallelIterator<Item = &'a OsStr>,
247    {
248        collect_extended(par_iter)
249    }
250}
251
252/// Collects OS-strings from a parallel iterator into one large OS-string.
253impl FromParallelIterator<OsString> for OsString {
254    fn from_par_iter<I>(par_iter: I) -> Self
255    where
256        I: IntoParallelIterator<Item = OsString>,
257    {
258        collect_extended(par_iter)
259    }
260}
261
262/// Collects OS-string slices from a parallel iterator into an OS-string.
263impl<'a> FromParallelIterator<Cow<'a, OsStr>> for OsString {
264    fn from_par_iter<I>(par_iter: I) -> Self
265    where
266        I: IntoParallelIterator<Item = Cow<'a, OsStr>>,
267    {
268        collect_extended(par_iter)
269    }
270}
271
272/// Collects an arbitrary `Cow` collection.
273///
274/// Note, the standard library only has `FromIterator` for `Cow<'a, str>` and
275/// `Cow<'a, [T]>`, because no one thought to add a blanket implementation
276/// before it was stabilized.
277impl<'a, C: ?Sized, T> FromParallelIterator<T> for Cow<'a, C>
278where
279    C: ToOwned,
280    C::Owned: FromParallelIterator<T>,
281    T: Send,
282{
283    fn from_par_iter<I>(par_iter: I) -> Self
284    where
285        I: IntoParallelIterator<Item = T>,
286    {
287        Cow::Owned(C::Owned::from_par_iter(par_iter))
288    }
289}
290
291/// Collapses all unit items from a parallel iterator into one.
292///
293/// This is more useful when combined with higher-level abstractions, like
294/// collecting to a `Result<(), E>` where you only care about errors:
295///
296/// ```
297/// use std::io::*;
298/// use par_iter::prelude::*;
299///
300/// let data = vec![1, 2, 3, 4, 5];
301/// let res: Result<()> = data.par_iter()
302///     .map(|x| writeln!(stdout(), "{}", x))
303///     .collect();
304/// assert!(res.is_ok());
305/// ```
306impl FromParallelIterator<()> for () {
307    fn from_par_iter<I>(par_iter: I) -> Self
308    where
309        I: IntoParallelIterator<Item = ()>,
310    {
311        par_iter.into_par_iter().drive_unindexed(NoopConsumer)
312    }
313}