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