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};
9use std::rc::Rc;
10use std::sync::Arc;
11
12/// Creates an empty default collection and extends it.
13fn collect_extended<C, I>(par_iter: I) -> C
14where
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.
24impl<T> FromParallelIterator<T> for Vec<T>
25where
26 T: Send,
27{
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.
37impl<T> FromParallelIterator<T> for Box<[T]>
38where
39 T: Send,
40{
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.
50impl<T> FromParallelIterator<T> for Rc<[T]>
51where
52 T: Send,
53{
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.
63impl<T> FromParallelIterator<T> for Arc<[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 Vec::from_par_iter(par_iter).into()
72 }
73}
74
75/// Collects items from a parallel iterator into a vecdeque.
76impl<T> FromParallelIterator<T> for VecDeque<T>
77where
78 T: Send,
79{
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.
90impl<T> FromParallelIterator<T> for BinaryHeap<T>
91where
92 T: Ord + Send,
93{
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.
104impl<T> FromParallelIterator<T> for LinkedList<T>
105where
106 T: Send,
107{
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.
120impl<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S>
121where
122 K: Eq + Hash + Send,
123 V: Send,
124 S: BuildHasher + Default + Send,
125{
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.
138impl<K, V> FromParallelIterator<(K, V)> for BTreeMap<K, V>
139where
140 K: Ord + Send,
141 V: Send,
142{
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.
152impl<V, S> FromParallelIterator<V> for HashSet<V, S>
153where
154 V: Eq + Hash + Send,
155 S: BuildHasher + Default + Send,
156{
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.
166impl<V> FromParallelIterator<V> for BTreeSet<V>
167where
168 V: Send + Ord,
169{
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.
179impl FromParallelIterator<char> for String {
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.
189impl<'a> FromParallelIterator<&'a char> for String {
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.
199impl<'a> FromParallelIterator<&'a str> for String {
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.
209impl FromParallelIterator<String> for 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.
219impl FromParallelIterator<Box<str>> for String {
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.
229impl<'a> FromParallelIterator<Cow<'a, str>> for String {
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.
243impl<'a, C: ?Sized, T> FromParallelIterator<T> for Cow<'a, C>
244where
245 C: ToOwned,
246 C::Owned: FromParallelIterator<T>,
247 T: Send,
248{
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/// ```
272impl FromParallelIterator<()> for () {
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