//! Parallel iterators.
//!
//! These are only available when using the `rayon` feature flag.
use super::*;
use ::rayon::iter::plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer};
use ::rayon::iter::{
IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
};
impl<'a, A> IntoParallelRefIterator<'a> for Vector
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a A;
type Iter = ParIter<'a, A>;
fn par_iter(&'a self) -> Self::Iter {
ParIter {
focus: self.focus(),
}
}
}
impl<'a, A> IntoParallelRefMutIterator<'a> for Vector
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a mut A;
type Iter = ParIterMut<'a, A>;
fn par_iter_mut(&'a mut self) -> Self::Iter {
ParIterMut {
focus: self.focus_mut(),
}
}
}
/// A parallel iterator for [`Vector`][Vector].
///
/// [Vector]: ../struct.Vector.html
pub struct ParIter<'a, A>
where
A: Clone + Send + Sync,
{
focus: Focus<'a, A>,
}
impl<'a, A> ParallelIterator for ParIter<'a, A>
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a A;
fn drive_unindexed(self, consumer: C) -> C::Result
where
C: UnindexedConsumer,
{
bridge(self, consumer)
}
}
impl<'a, A> IndexedParallelIterator for ParIter<'a, A>
where
A: Clone + Send + Sync + 'a,
{
fn drive(self, consumer: C) -> C::Result
where
C: Consumer,
{
bridge(self, consumer)
}
fn len(&self) -> usize {
self.focus.len()
}
fn with_producer(self, callback: CB) -> CB::Output
where
CB: ProducerCallback,
{
callback.callback(VectorProducer { focus: self.focus })
}
}
/// A mutable parallel iterator for [`Vector`][Vector].
///
/// [Vector]: ../struct.Vector.html
pub struct ParIterMut<'a, A>
where
A: Clone + Send + Sync,
{
focus: FocusMut<'a, A>,
}
impl<'a, A> ParallelIterator for ParIterMut<'a, A>
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a mut A;
fn drive_unindexed(self, consumer: C) -> C::Result
where
C: UnindexedConsumer,
{
bridge(self, consumer)
}
}
impl<'a, A> IndexedParallelIterator for ParIterMut<'a, A>
where
A: Clone + Send + Sync + 'a,
{
fn drive(self, consumer: C) -> C::Result
where
C: Consumer,
{
bridge(self, consumer)
}
fn len(&self) -> usize {
self.focus.len()
}
fn with_producer(self, callback: CB) -> CB::Output
where
CB: ProducerCallback,
{
callback.callback(VectorMutProducer { focus: self.focus })
}
}
struct VectorProducer<'a, A>
where
A: Clone + Send + Sync,
{
focus: Focus<'a, A>,
}
impl<'a, A> Producer for VectorProducer<'a, A>
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a A;
type IntoIter = Iter<'a, A>;
fn into_iter(self) -> Self::IntoIter {
self.focus.into_iter()
}
fn split_at(self, index: usize) -> (Self, Self) {
let (left, right) = self.focus.split_at(index);
(
VectorProducer { focus: left },
VectorProducer { focus: right },
)
}
}
struct VectorMutProducer<'a, A>
where
A: Clone + Send + Sync,
{
focus: FocusMut<'a, A>,
}
impl<'a, A> Producer for VectorMutProducer<'a, A>
where
A: Clone + Send + Sync + 'a,
{
type Item = &'a mut A;
type IntoIter = IterMut<'a, A>;
fn into_iter(self) -> Self::IntoIter {
self.focus.into_iter()
}
fn split_at(self, index: usize) -> (Self, Self) {
let (left, right) = self.focus.split_at(index);
(
VectorMutProducer { focus: left },
VectorMutProducer { focus: right },
)
}
}
#[cfg(test)]
mod test {
use super::super::*;
use super::proptest::vector;
use ::proptest::num::i32;
use ::proptest::proptest;
use ::rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
proptest! {
#[test]
fn par_iter(ref mut input in vector(i32::ANY, 0..10000)) {
assert_eq!(input.iter().max(), input.par_iter().max())
}
#[test]
fn par_mut_iter(ref mut input in vector(i32::ANY, 0..10000)) {
let mut vec = input.clone();
vec.par_iter_mut().for_each(|i| *i = i.overflowing_add(1).0);
let expected: Vector = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
assert_eq!(expected, vec);
}
}
}