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::hash::{BuildHasher, Hash};
9
10/// Creates an empty default collection and extends it.
11fn collect_extended<C, I>(par_iter: I) -> C
12where
13    I: IntoParallelIterator,
14    C: ParallelExtend<I::Item> + Default,
15{
16    let mut collection = C::default();
17    collection.par_extend(par_iter);
18    collection
19}
20
21/// Collects items from a parallel iterator into a vector.
22impl<T> FromParallelIterator<T> for Vec<T>
23where
24    T: Send,
25{
26    fn from_par_iter<I>(par_iter: I) -> Self
27    where
28        I: IntoParallelIterator<Item = T>,
29    {
30        collect_extended(par_iter)
31    }
32}
33
34/// Collects items from a parallel iterator into a vecdeque.
35impl<T> FromParallelIterator<T> for VecDeque<T>
36where
37    T: Send,
38{
39    fn from_par_iter<I>(par_iter: I) -> Self
40    where
41        I: IntoParallelIterator<Item = T>,
42    {
43        Vec::from_par_iter(par_iter).into()
44    }
45}
46
47/// Collects items from a parallel iterator into a binaryheap.
48/// The heap-ordering is calculated serially after all items are collected.
49impl<T> FromParallelIterator<T> for BinaryHeap<T>
50where
51    T: Ord + Send,
52{
53    fn from_par_iter<I>(par_iter: I) -> Self
54    where
55        I: IntoParallelIterator<Item = T>,
56    {
57        Vec::from_par_iter(par_iter).into()
58    }
59}
60
61/// Collects items from a parallel iterator into a freshly allocated
62/// linked list.
63impl<T> FromParallelIterator<T> for LinkedList<T>
64where
65    T: Send,
66{
67    fn from_par_iter<I>(par_iter: I) -> Self
68    where
69        I: IntoParallelIterator<Item = T>,
70    {
71        collect_extended(par_iter)
72    }
73}
74
75/// Collects (key, value) pairs from a parallel iterator into a
76/// hashmap. If multiple pairs correspond to the same key, then the
77/// ones produced earlier in the parallel iterator will be
78/// overwritten, just as with a sequential iterator.
79impl<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S>
80where
81    K: Eq + Hash + Send,
82    V: Send,
83    S: BuildHasher + Default + Send,
84{
85    fn from_par_iter<I>(par_iter: I) -> Self
86    where
87        I: IntoParallelIterator<Item = (K, V)>,
88    {
89        collect_extended(par_iter)
90    }
91}
92
93/// Collects (key, value) pairs from a parallel iterator into a
94/// btreemap. If multiple pairs correspond to the same key, then the
95/// ones produced earlier in the parallel iterator will be
96/// overwritten, just as with a sequential iterator.
97impl<K, V> FromParallelIterator<(K, V)> for BTreeMap<K, V>
98where
99    K: Ord + Send,
100    V: Send,
101{
102    fn from_par_iter<I>(par_iter: I) -> Self
103    where
104        I: IntoParallelIterator<Item = (K, V)>,
105    {
106        collect_extended(par_iter)
107    }
108}
109
110/// Collects values from a parallel iterator into a hashset.
111impl<V, S> FromParallelIterator<V> for HashSet<V, S>
112where
113    V: Eq + Hash + Send,
114    S: BuildHasher + Default + Send,
115{
116    fn from_par_iter<I>(par_iter: I) -> Self
117    where
118        I: IntoParallelIterator<Item = V>,
119    {
120        collect_extended(par_iter)
121    }
122}
123
124/// Collects values from a parallel iterator into a btreeset.
125impl<V> FromParallelIterator<V> for BTreeSet<V>
126where
127    V: Send + Ord,
128{
129    fn from_par_iter<I>(par_iter: I) -> Self
130    where
131        I: IntoParallelIterator<Item = V>,
132    {
133        collect_extended(par_iter)
134    }
135}
136
137/// Collects characters from a parallel iterator into a string.
138impl FromParallelIterator<char> for String {
139    fn from_par_iter<I>(par_iter: I) -> Self
140    where
141        I: IntoParallelIterator<Item = char>,
142    {
143        collect_extended(par_iter)
144    }
145}
146
147/// Collects characters from a parallel iterator into a string.
148impl<'a> FromParallelIterator<&'a char> for String {
149    fn from_par_iter<I>(par_iter: I) -> Self
150    where
151        I: IntoParallelIterator<Item = &'a char>,
152    {
153        collect_extended(par_iter)
154    }
155}
156
157/// Collects string slices from a parallel iterator into a string.
158impl<'a> FromParallelIterator<&'a str> for String {
159    fn from_par_iter<I>(par_iter: I) -> Self
160    where
161        I: IntoParallelIterator<Item = &'a str>,
162    {
163        collect_extended(par_iter)
164    }
165}
166
167/// Collects strings from a parallel iterator into one large string.
168impl FromParallelIterator<String> for String {
169    fn from_par_iter<I>(par_iter: I) -> Self
170    where
171        I: IntoParallelIterator<Item = String>,
172    {
173        collect_extended(par_iter)
174    }
175}
176
177/// Collects string slices from a parallel iterator into a string.
178impl<'a> FromParallelIterator<Cow<'a, str>> for String {
179    fn from_par_iter<I>(par_iter: I) -> Self
180    where
181        I: IntoParallelIterator<Item = Cow<'a, str>>,
182    {
183        collect_extended(par_iter)
184    }
185}
186
187/// Collects an arbitrary `Cow` collection.
188///
189/// Note, the standard library only has `FromIterator` for `Cow<'a, str>` and
190/// `Cow<'a, [T]>`, because no one thought to add a blanket implementation
191/// before it was stabilized.
192impl<'a, C: ?Sized, T> FromParallelIterator<T> for Cow<'a, C>
193where
194    C: ToOwned,
195    C::Owned: FromParallelIterator<T>,
196    T: Send,
197{
198    fn from_par_iter<I>(par_iter: I) -> Self
199    where
200        I: IntoParallelIterator<Item = T>,
201    {
202        Cow::Owned(C::Owned::from_par_iter(par_iter))
203    }
204}
205
206/// Collapses all unit items from a parallel iterator into one.
207///
208/// This is more useful when combined with higher-level abstractions, like
209/// collecting to a `Result<(), E>` where you only care about errors:
210///
211/// ```
212/// use std::io::*;
213/// use rayon::prelude::*;
214///
215/// let data = vec![1, 2, 3, 4, 5];
216/// let res: Result<()> = data.par_iter()
217///     .map(|x| writeln!(stdout(), "{}", x))
218///     .collect();
219/// assert!(res.is_ok());
220/// ```
221impl FromParallelIterator<()> for () {
222    fn from_par_iter<I>(par_iter: I) -> Self
223    where
224        I: IntoParallelIterator<Item = ()>,
225    {
226        par_iter.into_par_iter().drive_unindexed(NoopConsumer)
227    }
228}