[go: up one dir, main page]

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