rayon/iter/
from_par_iter.rs

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