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