use super::plumbing::*;
use super::*;
use std::iter;
use std::usize;
#[derive(Debug, Clone)]
pub struct Repeat<T: Clone + Send> {
element: T,
}
pub fn repeat<T: Clone + Send>(elt: T) -> Repeat<T> {
Repeat { element: elt }
}
impl<T> Repeat<T>
where
T: Clone + Send,
{
pub fn take(self, n: usize) -> RepeatN<T> {
repeatn(self.element, n)
}
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)
}
}
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))
}
}
#[derive(Debug, Clone)]
pub struct RepeatN<T: Clone + Send> {
element: T,
count: usize,
}
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
}
}
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,
},
)
}
}
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
}
}