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 { 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(elt: T) -> Repeat { Repeat { element: elt } } impl Repeat where T: Clone + Send, { /// Takes 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 { repeatn(self.element, n) } /// Iterates tuples, repeating the element with items from another /// iterator, similar to the general /// [`zip()`](trait.IndexedParallelIterator.html#method.zip). pub fn zip(self, zip_op: Z) -> Zip, 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 ParallelIterator for Repeat where T: Clone + Send, { type Item = T; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { let producer = RepeatProducer { element: self.element, }; bridge_unindexed(producer, consumer) } } /// Unindexed producer for `Repeat`. struct RepeatProducer { element: T, } impl UnindexedProducer for RepeatProducer { type Item = T; fn split(self) -> (Self, Option) { ( RepeatProducer { element: self.element.clone(), }, Some(RepeatProducer { element: self.element, }), ) } fn fold_with(self, folder: F) -> F where F: Folder, { folder.consume_iter(iter::repeat(self.element)) } } /// Iterator adaptor for [the `repeatn()` function](fn.repeatn.html). #[derive(Debug, Clone)] pub struct RepeatN { 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(elt: T, n: usize) -> RepeatN { RepeatN { element: elt, count: n, } } impl ParallelIterator for RepeatN where T: Clone + Send, { type Item = T; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.count) } } impl IndexedParallelIterator for RepeatN where T: Clone + Send, { fn drive(self, consumer: C) -> C::Result where C: Consumer, { bridge(self, consumer) } fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback, { callback.callback(RepeatNProducer { element: self.element, count: self.count, }) } fn len(&self) -> usize { self.count } } /// Producer for `RepeatN`. struct RepeatNProducer { element: T, count: usize, } impl Producer for RepeatNProducer { type Item = T; type IntoIter = Iter; 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>`, but /// we need `DoubleEndedIterator` and unconditional `ExactSizeIterator`. struct Iter { element: T, count: usize, } impl Iterator for Iter { type Item = T; #[inline] fn next(&mut self) -> Option { if self.count > 0 { self.count -= 1; Some(self.element.clone()) } else { None } } #[inline] fn size_hint(&self) -> (usize, Option) { (self.count, Some(self.count)) } } impl DoubleEndedIterator for Iter { #[inline] fn next_back(&mut self) -> Option { self.next() } } impl ExactSizeIterator for Iter { #[inline] fn len(&self) -> usize { self.count } }