//! This module contains the parallel iterator types for double-ended queues //! (`VecDeque`). You will rarely need to interact with it directly //! unless you have need to name one of the iterator types. use std::collections::VecDeque; use std::ops::{Range, RangeBounds}; use crate::iter::plumbing::*; use crate::iter::*; use crate::math::simplify_range; use crate::slice; use crate::vec; /// Parallel iterator over a double-ended queue #[derive(Debug, Clone)] pub struct IntoIter { inner: vec::IntoIter, } impl IntoParallelIterator for VecDeque { type Item = T; type Iter = IntoIter; fn into_par_iter(self) -> Self::Iter { // NOTE: requires data movement if the deque doesn't start at offset 0. let inner = Vec::from(self).into_par_iter(); IntoIter { inner } } } delegate_indexed_iterator! { IntoIter => T, impl } /// Parallel iterator over an immutable reference to a double-ended queue #[derive(Debug)] pub struct Iter<'a, T: Sync> { inner: Chain, slice::Iter<'a, T>>, } impl<'a, T: Sync> Clone for Iter<'a, T> { fn clone(&self) -> Self { Iter { inner: self.inner.clone(), } } } impl<'a, T: Sync> IntoParallelIterator for &'a VecDeque { type Item = &'a T; type Iter = Iter<'a, T>; fn into_par_iter(self) -> Self::Iter { let (a, b) = self.as_slices(); Iter { inner: a.into_par_iter().chain(b), } } } delegate_indexed_iterator! { Iter<'a, T> => &'a T, impl<'a, T: Sync + 'a> } /// Parallel iterator over a mutable reference to a double-ended queue #[derive(Debug)] pub struct IterMut<'a, T: Send> { inner: Chain, slice::IterMut<'a, T>>, } impl<'a, T: Send> IntoParallelIterator for &'a mut VecDeque { type Item = &'a mut T; type Iter = IterMut<'a, T>; fn into_par_iter(self) -> Self::Iter { let (a, b) = self.as_mut_slices(); IterMut { inner: a.into_par_iter().chain(b), } } } delegate_indexed_iterator! { IterMut<'a, T> => &'a mut T, impl<'a, T: Send + 'a> } /// Draining parallel iterator that moves a range out of a double-ended queue, /// but keeps the total capacity. #[derive(Debug)] pub struct Drain<'a, T: Send> { deque: &'a mut VecDeque, range: Range, orig_len: usize, } impl<'a, T: Send> ParallelDrainRange for &'a mut VecDeque { type Iter = Drain<'a, T>; type Item = T; fn par_drain>(self, range: R) -> Self::Iter { Drain { orig_len: self.len(), range: simplify_range(range, self.len()), deque: self, } } } impl<'a, T: Send> ParallelIterator for Drain<'a, T> { type Item = T; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.len()) } } impl<'a, T: Send> IndexedParallelIterator for Drain<'a, T> { fn drive(self, consumer: C) -> C::Result where C: Consumer, { bridge(self, consumer) } fn len(&self) -> usize { self.range.len() } fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback, { // NOTE: requires data movement if the deque doesn't start at offset 0. super::DrainGuard::new(self.deque) .par_drain(self.range.clone()) .with_producer(callback) } } impl<'a, T: Send> Drop for Drain<'a, T> { fn drop(&mut self) { if self.deque.len() != self.orig_len - self.range.len() { // We must not have produced, so just call a normal drain to remove the items. assert_eq!(self.deque.len(), self.orig_len); self.deque.drain(self.range.clone()); } } }