rayon/iter/
from_par_iter.rs1use 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
13fn 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
24impl<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
37impl<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
50impl<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
63impl<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
76impl<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
89impl<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
103impl<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
117impl<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
135impl<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
152impl<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
166impl<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
179macro_rules! collect_string {
180    ($desc:literal, $item:ty $(, $a:lifetime)?) => {
181        #[doc = concat!("Collects ", $desc, " from a parallel iterator into a string.")]
182        impl$(<$a>)? FromParallelIterator<$item> for String {
183            fn from_par_iter<I>(par_iter: I) -> Self
184            where
185                I: IntoParallelIterator<Item = $item>,
186            {
187                collect_extended(par_iter)
188            }
189        }
190
191        #[doc = concat!("Collects ", $desc, " from a parallel iterator into a boxed string.")]
192        impl$(<$a>)? FromParallelIterator<$item> for Box<str> {
193            fn from_par_iter<I>(par_iter: I) -> Self
194            where
195                I: IntoParallelIterator<Item = $item>,
196            {
197                String::from_par_iter(par_iter).into_boxed_str()
198            }
199        }
200    }
201}
202
203collect_string!("characters", char);
204collect_string!("characters", &'a char, 'a);
205collect_string!("string slices", &'a str, 'a);
206collect_string!("string slices", Cow<'a, str>, 'a);
207collect_string!("boxed strings", Box<str>);
208collect_string!("strings", String);
209
210impl<'a> FromParallelIterator<&'a OsStr> for OsString {
212    fn from_par_iter<I>(par_iter: I) -> Self
213    where
214        I: IntoParallelIterator<Item = &'a OsStr>,
215    {
216        collect_extended(par_iter)
217    }
218}
219
220impl FromParallelIterator<OsString> for OsString {
222    fn from_par_iter<I>(par_iter: I) -> Self
223    where
224        I: IntoParallelIterator<Item = OsString>,
225    {
226        collect_extended(par_iter)
227    }
228}
229
230impl<'a> FromParallelIterator<Cow<'a, OsStr>> for OsString {
232    fn from_par_iter<I>(par_iter: I) -> Self
233    where
234        I: IntoParallelIterator<Item = Cow<'a, OsStr>>,
235    {
236        collect_extended(par_iter)
237    }
238}
239
240impl<'a, C, T> FromParallelIterator<T> for Cow<'a, C>
246where
247    C: ToOwned<Owned: FromParallelIterator<T>> + ?Sized,
248    T: Send,
249{
250    fn from_par_iter<I>(par_iter: I) -> Self
251    where
252        I: IntoParallelIterator<Item = T>,
253    {
254        Cow::Owned(C::Owned::from_par_iter(par_iter))
255    }
256}
257
258impl FromParallelIterator<()> for () {
274    fn from_par_iter<I>(par_iter: I) -> Self
275    where
276        I: IntoParallelIterator<Item = ()>,
277    {
278        par_iter.into_par_iter().drive_unindexed(NoopConsumer)
279    }
280}