| use super::plumbing::*; |
| use super::*; |
| use std::iter; |
| use std::usize; |
| |
| /// Iterator adaptor for [the `repeat()` function](fn.repeat.html). |
| #[derive(Debug, Clone)] |
| pub struct Repeat<T: Clone + Send> { |
| element: T, |
| } |
| |
| /// Creates a parallel iterator that endlessly repeats `elt` (by |
| /// cloning it). Note that this iterator has "infinite" length, so |
| /// typically you would want to use `zip` or `take` or some other |
| /// means to shorten it, or consider using |
| /// [the `repeatn()` function](fn.repeatn.html) instead. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// use rayon::prelude::*; |
| /// use rayon::iter::repeat; |
| /// let x: Vec<(i32, i32)> = repeat(22).zip(0..3).collect(); |
| /// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]); |
| /// ``` |
| pub fn repeat<T: Clone + Send>(elt: T) -> Repeat<T> { |
| Repeat { element: elt } |
| } |
| |
| impl<T> Repeat<T> |
| where T: Clone + Send |
| { |
| /// Take only `n` repeats of the element, similar to the general |
| /// [`take()`](trait.IndexedParallelIterator.html#method.take). |
| /// |
| /// The resulting `RepeatN` is an `IndexedParallelIterator`, allowing |
| /// more functionality than `Repeat` alone. |
| pub fn take(self, n: usize) -> RepeatN<T> { |
| repeatn(self.element, n) |
| } |
| |
| /// Iterate tuples repeating the element with items from another |
| /// iterator, similar to the general |
| /// [`zip()`](trait.IndexedParallelIterator.html#method.zip). |
| pub fn zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter> |
| where Z: IntoParallelIterator, |
| Z::Iter: IndexedParallelIterator |
| { |
| let z = zip_op.into_par_iter(); |
| let n = z.len(); |
| self.take(n).zip(z) |
| } |
| } |
| |
| impl<T> ParallelIterator for Repeat<T> |
| where T: Clone + Send |
| { |
| type Item = T; |
| |
| fn drive_unindexed<C>(self, consumer: C) -> C::Result |
| where C: UnindexedConsumer<Self::Item> |
| { |
| let producer = RepeatProducer { element: self.element }; |
| bridge_unindexed(producer, consumer) |
| } |
| } |
| |
| /// Unindexed producer for `Repeat`. |
| struct RepeatProducer<T: Clone + Send> { |
| element: T, |
| } |
| |
| impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> { |
| type Item = T; |
| |
| fn split(self) -> (Self, Option<Self>) { |
| (RepeatProducer { element: self.element.clone() }, |
| Some(RepeatProducer { element: self.element })) |
| } |
| |
| fn fold_with<F>(self, folder: F) -> F |
| where F: Folder<T> |
| { |
| folder.consume_iter(iter::repeat(self.element)) |
| } |
| } |
| |
| |
| /// Iterator adaptor for [the `repeatn()` function](fn.repeatn.html). |
| #[derive(Debug, Clone)] |
| pub struct RepeatN<T: Clone + Send> { |
| element: T, |
| count: usize, |
| } |
| |
| /// Creates a parallel iterator that produces `n` repeats of `elt` |
| /// (by cloning it). |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// use rayon::prelude::*; |
| /// use rayon::iter::repeatn; |
| /// let x: Vec<(i32, i32)> = repeatn(22, 3).zip(0..3).collect(); |
| /// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]); |
| /// ``` |
| pub fn repeatn<T: Clone + Send>(elt: T, n: usize) -> RepeatN<T> { |
| RepeatN { element: elt, count: n } |
| } |
| |
| impl<T> ParallelIterator for RepeatN<T> |
| where T: Clone + Send |
| { |
| type Item = T; |
| |
| fn drive_unindexed<C>(self, consumer: C) -> C::Result |
| where C: UnindexedConsumer<Self::Item> |
| { |
| bridge(self, consumer) |
| } |
| |
| fn opt_len(&self) -> Option<usize> { |
| Some(self.count) |
| } |
| } |
| |
| impl<T> IndexedParallelIterator for RepeatN<T> |
| where T: Clone + Send |
| { |
| fn drive<C>(self, consumer: C) -> C::Result |
| where C: Consumer<Self::Item> |
| { |
| bridge(self, consumer) |
| } |
| |
| fn with_producer<CB>(self, callback: CB) -> CB::Output |
| where CB: ProducerCallback<Self::Item> |
| { |
| callback.callback(RepeatNProducer { element: self.element, count: self.count }) |
| } |
| |
| fn len(&self) -> usize { |
| self.count |
| } |
| } |
| |
| |
| /// Producer for `RepeatN`. |
| struct RepeatNProducer<T: Clone + Send> { |
| element: T, |
| count: usize, |
| } |
| |
| impl<T: Clone + Send> Producer for RepeatNProducer<T> { |
| type Item = T; |
| type IntoIter = Iter<T>; |
| |
| fn into_iter(self) -> Self::IntoIter { |
| Iter { element: self.element, count: self.count } |
| } |
| |
| fn split_at(self, index: usize) -> (Self, Self) { |
| (RepeatNProducer { element: self.element.clone(), count: index }, |
| RepeatNProducer { element: self.element, count: self.count - index }) |
| } |
| } |
| |
| /// Iterator for `RepeatN`. |
| /// |
| /// This is conceptually like `std::iter::Take<std::iter::Repeat<T>>`, but |
| /// we need `DoubleEndedIterator` and unconditional `ExactSizeIterator`. |
| struct Iter<T: Clone> { |
| element: T, |
| count: usize, |
| } |
| |
| impl<T: Clone> Iterator for Iter<T> { |
| type Item = T; |
| |
| #[inline] |
| fn next(&mut self) -> Option<T> { |
| if self.count > 0 { |
| self.count -= 1; |
| Some(self.element.clone()) |
| } else { |
| None |
| } |
| } |
| |
| #[inline] |
| fn size_hint(&self) -> (usize, Option<usize>) { |
| (self.count, Some(self.count)) |
| } |
| } |
| |
| impl<T: Clone> DoubleEndedIterator for Iter<T> { |
| #[inline] |
| fn next_back(&mut self) -> Option<T> { |
| self.next() |
| } |
| } |
| |
| impl<T: Clone> ExactSizeIterator for Iter<T> { |
| #[inline] |
| fn len(&self) -> usize { |
| self.count |
| } |
| } |