im/vector/
rayon.rs

1//! Parallel iterators.
2//!
3//! These are only available when using the `rayon` feature flag.
4
5use super::*;
6use ::rayon::iter::plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer};
7use ::rayon::iter::{
8    IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
9};
10
11impl<'a, A> IntoParallelRefIterator<'a> for Vector<A>
12where
13    A: Clone + Send + Sync + 'a,
14{
15    type Item = &'a A;
16    type Iter = ParIter<'a, A>;
17
18    fn par_iter(&'a self) -> Self::Iter {
19        ParIter {
20            focus: self.focus(),
21        }
22    }
23}
24
25impl<'a, A> IntoParallelRefMutIterator<'a> for Vector<A>
26where
27    A: Clone + Send + Sync + 'a,
28{
29    type Item = &'a mut A;
30    type Iter = ParIterMut<'a, A>;
31
32    fn par_iter_mut(&'a mut self) -> Self::Iter {
33        ParIterMut {
34            focus: self.focus_mut(),
35        }
36    }
37}
38
39/// A parallel iterator for [`Vector`][Vector].
40///
41/// [Vector]: ../struct.Vector.html
42pub struct ParIter<'a, A>
43where
44    A: Clone + Send + Sync,
45{
46    focus: Focus<'a, A>,
47}
48
49impl<'a, A> ParallelIterator for ParIter<'a, A>
50where
51    A: Clone + Send + Sync + 'a,
52{
53    type Item = &'a A;
54
55    fn drive_unindexed<C>(self, consumer: C) -> C::Result
56    where
57        C: UnindexedConsumer<Self::Item>,
58    {
59        bridge(self, consumer)
60    }
61}
62
63impl<'a, A> IndexedParallelIterator for ParIter<'a, A>
64where
65    A: Clone + Send + Sync + 'a,
66{
67    fn drive<C>(self, consumer: C) -> C::Result
68    where
69        C: Consumer<Self::Item>,
70    {
71        bridge(self, consumer)
72    }
73
74    fn len(&self) -> usize {
75        self.focus.len()
76    }
77
78    fn with_producer<CB>(self, callback: CB) -> CB::Output
79    where
80        CB: ProducerCallback<Self::Item>,
81    {
82        callback.callback(VectorProducer { focus: self.focus })
83    }
84}
85
86/// A mutable parallel iterator for [`Vector`][Vector].
87///
88/// [Vector]: ../struct.Vector.html
89pub struct ParIterMut<'a, A>
90where
91    A: Clone + Send + Sync,
92{
93    focus: FocusMut<'a, A>,
94}
95
96impl<'a, A> ParallelIterator for ParIterMut<'a, A>
97where
98    A: Clone + Send + Sync + 'a,
99{
100    type Item = &'a mut A;
101
102    fn drive_unindexed<C>(self, consumer: C) -> C::Result
103    where
104        C: UnindexedConsumer<Self::Item>,
105    {
106        bridge(self, consumer)
107    }
108}
109
110impl<'a, A> IndexedParallelIterator for ParIterMut<'a, A>
111where
112    A: Clone + Send + Sync + 'a,
113{
114    fn drive<C>(self, consumer: C) -> C::Result
115    where
116        C: Consumer<Self::Item>,
117    {
118        bridge(self, consumer)
119    }
120
121    fn len(&self) -> usize {
122        self.focus.len()
123    }
124
125    fn with_producer<CB>(self, callback: CB) -> CB::Output
126    where
127        CB: ProducerCallback<Self::Item>,
128    {
129        callback.callback(VectorMutProducer { focus: self.focus })
130    }
131}
132
133struct VectorProducer<'a, A>
134where
135    A: Clone + Send + Sync,
136{
137    focus: Focus<'a, A>,
138}
139
140impl<'a, A> Producer for VectorProducer<'a, A>
141where
142    A: Clone + Send + Sync + 'a,
143{
144    type Item = &'a A;
145    type IntoIter = Iter<'a, A>;
146
147    fn into_iter(self) -> Self::IntoIter {
148        self.focus.into_iter()
149    }
150
151    fn split_at(self, index: usize) -> (Self, Self) {
152        let (left, right) = self.focus.split_at(index);
153        (
154            VectorProducer { focus: left },
155            VectorProducer { focus: right },
156        )
157    }
158}
159
160struct VectorMutProducer<'a, A>
161where
162    A: Clone + Send + Sync,
163{
164    focus: FocusMut<'a, A>,
165}
166
167impl<'a, A> Producer for VectorMutProducer<'a, A>
168where
169    A: Clone + Send + Sync + 'a,
170{
171    type Item = &'a mut A;
172    type IntoIter = IterMut<'a, A>;
173
174    fn into_iter(self) -> Self::IntoIter {
175        self.focus.into_iter()
176    }
177
178    fn split_at(self, index: usize) -> (Self, Self) {
179        let (left, right) = self.focus.split_at(index);
180        (
181            VectorMutProducer { focus: left },
182            VectorMutProducer { focus: right },
183        )
184    }
185}
186
187#[cfg(test)]
188mod test {
189    use super::super::*;
190    use super::proptest::vector;
191    use ::proptest::num::i32;
192    use ::proptest::proptest;
193    use ::rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
194
195    proptest! {
196        #[test]
197        fn par_iter(ref mut input in vector(i32::ANY, 0..10000)) {
198            assert_eq!(input.iter().max(), input.par_iter().max())
199        }
200
201        #[test]
202        fn par_mut_iter(ref mut input in vector(i32::ANY, 0..10000)) {
203            let mut vec = input.clone();
204            vec.par_iter_mut().for_each(|i| *i = i.overflowing_add(1).0);
205            let expected: Vector<i32> = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
206            assert_eq!(expected, vec);
207        }
208    }
209}