pub use either::Either;
use std::cmp::{self, Ordering};
use std::iter::{Sum, Product};
use std::ops::Fn;
use self::plumbing::*;
mod find;
mod find_first_last;
mod chain;
pub use self::chain::Chain;
mod chunks;
pub use self::chunks::Chunks;
mod collect;
mod enumerate;
pub use self::enumerate::Enumerate;
mod filter;
pub use self::filter::Filter;
mod filter_map;
pub use self::filter_map::FilterMap;
mod flat_map;
pub use self::flat_map::FlatMap;
mod flatten;
pub use self::flatten::Flatten;
mod from_par_iter;
pub mod plumbing;
mod for_each;
mod fold;
pub use self::fold::{Fold, FoldWith};
mod reduce;
mod skip;
pub use self::skip::Skip;
mod splitter;
pub use self::splitter::{split, Split};
mod take;
pub use self::take::Take;
mod map;
pub use self::map::Map;
mod map_with;
pub use self::map_with::MapWith;
mod zip;
pub use self::zip::Zip;
mod zip_eq;
pub use self::zip_eq::ZipEq;
mod interleave;
pub use self::interleave::Interleave;
mod interleave_shortest;
pub use self::interleave_shortest::InterleaveShortest;
mod intersperse;
pub use self::intersperse::Intersperse;
mod update;
pub use self::update::Update;
mod noop;
mod rev;
pub use self::rev::Rev;
mod len;
pub use self::len::{MinLen, MaxLen};
mod sum;
mod product;
mod cloned;
pub use self::cloned::Cloned;
mod inspect;
pub use self::inspect::Inspect;
mod while_some;
pub use self::while_some::WhileSome;
mod extend;
mod unzip;
mod repeat;
pub use self::repeat::{Repeat, repeat};
pub use self::repeat::{RepeatN, repeatn};
mod empty;
pub use self::empty::{Empty, empty};
mod once;
pub use self::once::{Once, once};
#[cfg(test)]
mod test;
pub trait IntoParallelIterator {
type Iter: ParallelIterator<Item = Self::Item>;
type Item: Send;
fn into_par_iter(self) -> Self::Iter;
}
pub trait IntoParallelRefIterator<'data> {
type Iter: ParallelIterator<Item = Self::Item>;
type Item: Send + 'data;
fn par_iter(&'data self) -> Self::Iter;
}
impl<'data, I: 'data + ?Sized> IntoParallelRefIterator<'data> for I
where &'data I: IntoParallelIterator
{
type Iter = <&'data I as IntoParallelIterator>::Iter;
type Item = <&'data I as IntoParallelIterator>::Item;
fn par_iter(&'data self) -> Self::Iter {
self.into_par_iter()
}
}
pub trait IntoParallelRefMutIterator<'data> {
type Iter: ParallelIterator<Item = Self::Item>;
type Item: Send + 'data;
fn par_iter_mut(&'data mut self) -> Self::Iter;
}
impl<'data, I: 'data + ?Sized> IntoParallelRefMutIterator<'data> for I
where &'data mut I: IntoParallelIterator
{
type Iter = <&'data mut I as IntoParallelIterator>::Iter;
type Item = <&'data mut I as IntoParallelIterator>::Item;
fn par_iter_mut(&'data mut self) -> Self::Iter {
self.into_par_iter()
}
}
pub trait ParallelIterator: Sized + Send {
type Item: Send;
fn for_each<OP>(self, op: OP)
where OP: Fn(Self::Item) + Sync + Send
{
for_each::for_each(self, &op)
}
fn for_each_with<OP, T>(self, init: T, op: OP)
where OP: Fn(&mut T, Self::Item) + Sync + Send,
T: Send + Clone
{
self.map_with(init, op).for_each(|()| ())
}
fn count(self) -> usize {
self.map(|_| 1).sum()
}
fn map<F, R>(self, map_op: F) -> Map<Self, F>
where F: Fn(Self::Item) -> R + Sync + Send,
R: Send
{
map::new(self, map_op)
}
fn map_with<F, T, R>(self, init: T, map_op: F) -> MapWith<Self, T, F>
where F: Fn(&mut T, Self::Item) -> R + Sync + Send,
T: Send + Clone,
R: Send
{
map_with::new(self, init, map_op)
}
fn cloned<'a, T>(self) -> Cloned<Self>
where T: 'a + Clone + Send,
Self: ParallelIterator<Item = &'a T>
{
cloned::new(self)
}
fn inspect<OP>(self, inspect_op: OP) -> Inspect<Self, OP>
where OP: Fn(&Self::Item) + Sync + Send
{
inspect::new(self, inspect_op)
}
fn update<F>(self, update_op: F) -> Update<Self, F>
where F: Fn(&mut Self::Item) + Sync + Send
{
update::new(self, update_op)
}
fn filter<P>(self, filter_op: P) -> Filter<Self, P>
where P: Fn(&Self::Item) -> bool + Sync + Send
{
filter::new(self, filter_op)
}
fn filter_map<P, R>(self, filter_op: P) -> FilterMap<Self, P>
where P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send
{
filter_map::new(self, filter_op)
}
fn flat_map<F, PI>(self, map_op: F) -> FlatMap<Self, F>
where F: Fn(Self::Item) -> PI + Sync + Send,
PI: IntoParallelIterator
{
flat_map::new(self, map_op)
}
fn flatten(self) -> Flatten<Self>
where Self::Item: IntoParallelIterator
{
flatten::new(self)
}
fn reduce<OP, ID>(self, identity: ID, op: OP) -> Self::Item
where OP: Fn(Self::Item, Self::Item) -> Self::Item + Sync + Send,
ID: Fn() -> Self::Item + Sync + Send
{
reduce::reduce(self, identity, op)
}
fn reduce_with<OP>(self, op: OP) -> Option<Self::Item>
where OP: Fn(Self::Item, Self::Item) -> Self::Item + Sync + Send
{
self.fold(|| None, |opt_a, b| match opt_a {
Some(a) => Some(op(a, b)),
None => Some(b),
})
.reduce(|| None, |opt_a, opt_b| match (opt_a, opt_b) {
(Some(a), Some(b)) => Some(op(a, b)),
(Some(v), None) | (None, Some(v)) => Some(v),
(None, None) => None,
})
}
fn fold<T, ID, F>(self, identity: ID, fold_op: F) -> Fold<Self, ID, F>
where F: Fn(T, Self::Item) -> T + Sync + Send,
ID: Fn() -> T + Sync + Send,
T: Send
{
fold::fold(self, identity, fold_op)
}
fn fold_with<F, T>(self, init: T, fold_op: F) -> FoldWith<Self, T, F>
where F: Fn(T, Self::Item) -> T + Sync + Send,
T: Send + Clone
{
fold::fold_with(self, init, fold_op)
}
fn sum<S>(self) -> S
where S: Send + Sum<Self::Item> + Sum<S>
{
sum::sum(self)
}
fn product<P>(self) -> P
where P: Send + Product<Self::Item> + Product<P>
{
product::product(self)
}
fn min(self) -> Option<Self::Item>
where Self::Item: Ord
{
self.reduce_with(cmp::min)
}
fn min_by<F>(self, f: F) -> Option<Self::Item>
where F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering
{
self.reduce_with(|a, b| match f(&a, &b) {
Ordering::Greater => b,
_ => a,
})
}
fn min_by_key<K, F>(self, f: F) -> Option<Self::Item>
where K: Ord + Send,
F: Sync + Send + Fn(&Self::Item) -> K
{
self.map(|x| (f(&x), x))
.min_by(|a, b| (a.0).cmp(&b.0))
.map(|(_, x)| x)
}
fn max(self) -> Option<Self::Item>
where Self::Item: Ord
{
self.reduce_with(cmp::max)
}
fn max_by<F>(self, f: F) -> Option<Self::Item>
where F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering
{
self.reduce_with(|a, b| match f(&a, &b) {
Ordering::Greater => a,
_ => b,
})
}
fn max_by_key<K, F>(self, f: F) -> Option<Self::Item>
where K: Ord + Send,
F: Sync + Send + Fn(&Self::Item) -> K
{
self.map(|x| (f(&x), x))
.max_by(|a, b| (a.0).cmp(&b.0))
.map(|(_, x)| x)
}
fn chain<C>(self, chain: C) -> Chain<Self, C::Iter>
where C: IntoParallelIterator<Item = Self::Item>
{
chain::new(self, chain.into_par_iter())
}
fn find_any<P>(self, predicate: P) -> Option<Self::Item>
where P: Fn(&Self::Item) -> bool + Sync + Send
{
find::find(self, predicate)
}
fn find_first<P>(self, predicate: P) -> Option<Self::Item>
where P: Fn(&Self::Item) -> bool + Sync + Send
{
find_first_last::find_first(self, predicate)
}
fn find_last<P>(self, predicate: P) -> Option<Self::Item>
where P: Fn(&Self::Item) -> bool + Sync + Send
{
find_first_last::find_last(self, predicate)
}
#[doc(hidden)]
#[deprecated(note = "parallel `find` does not search in order -- use `find_any`, \\
`find_first`, or `find_last`")]
fn find<P>(self, predicate: P) -> Option<Self::Item>
where P: Fn(&Self::Item) -> bool + Sync + Send
{
self.find_any(predicate)
}
fn any<P>(self, predicate: P) -> bool
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.map(predicate).find_any(|&p| p).is_some()
}
fn all<P>(self, predicate: P) -> bool
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.map(predicate).find_any(|&p| !p).is_none()
}
fn while_some<T>(self) -> WhileSome<Self>
where Self: ParallelIterator<Item = Option<T>>,
T: Send
{
while_some::new(self)
}
fn collect<C>(self) -> C
where C: FromParallelIterator<Self::Item>
{
C::from_par_iter(self)
}
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where Self: ParallelIterator<Item = (A, B)>,
FromA: Default + Send + ParallelExtend<A>,
FromB: Default + Send + ParallelExtend<B>,
A: Send,
B: Send
{
unzip::unzip(self)
}
fn partition<A, B, P>(self, predicate: P) -> (A, B)
where A: Default + Send + ParallelExtend<Self::Item>,
B: Default + Send + ParallelExtend<Self::Item>,
P: Fn(&Self::Item) -> bool + Sync + Send
{
unzip::partition(self, predicate)
}
fn partition_map<A, B, P, L, R>(self, predicate: P) -> (A, B)
where A: Default + Send + ParallelExtend<L>,
B: Default + Send + ParallelExtend<R>,
P: Fn(Self::Item) -> Either<L, R> + Sync + Send,
L: Send,
R: Send
{
unzip::partition_map(self, predicate)
}
fn intersperse(self, element: Self::Item) -> Intersperse<Self>
where Self::Item: Clone
{
intersperse::new(self, element)
}
fn drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>;
fn opt_len(&self) -> Option<usize> {
None
}
}
impl<T: ParallelIterator> IntoParallelIterator for T {
type Iter = T;
type Item = T::Item;
fn into_par_iter(self) -> T {
self
}
}
pub trait IndexedParallelIterator: ParallelIterator {
fn collect_into_vec(self, target: &mut Vec<Self::Item>) {
collect::collect_into_vec(self, target);
}
fn unzip_into_vecs<A, B>(self, left: &mut Vec<A>, right: &mut Vec<B>)
where Self: IndexedParallelIterator<Item = (A, B)>,
A: Send,
B: Send
{
collect::unzip_into_vecs(self, left, right);
}
fn zip<Z>(self, zip_op: Z) -> Zip<Self, Z::Iter>
where Z: IntoParallelIterator,
Z::Iter: IndexedParallelIterator
{
zip::new(self, zip_op.into_par_iter())
}
fn zip_eq<Z>(self, zip_op: Z) -> ZipEq<Self, Z::Iter>
where Z: IntoParallelIterator,
Z::Iter: IndexedParallelIterator
{
let zip_op_iter = zip_op.into_par_iter();
assert_eq!(self.len(), zip_op_iter.len());
zip_eq::new(self, zip_op_iter)
}
fn interleave<I>(self, other: I) -> Interleave<Self, I::Iter>
where I: IntoParallelIterator<Item = Self::Item>,
I::Iter: IndexedParallelIterator<Item = Self::Item>
{
interleave::new(self, other.into_par_iter())
}
fn interleave_shortest<I>(self, other: I) -> InterleaveShortest<Self, I::Iter>
where I: IntoParallelIterator<Item = Self::Item>,
I::Iter: IndexedParallelIterator<Item = Self::Item>
{
interleave_shortest::new(self, other.into_par_iter())
}
fn chunks(self, chunk_size: usize) -> Chunks<Self> {
assert!(chunk_size != 0, "chunk_size must not be zero");
chunks::new(self, chunk_size)
}
fn cmp<I>(self, other: I) -> Ordering
where I: IntoParallelIterator<Item = Self::Item>,
I::Iter: IndexedParallelIterator,
Self::Item: Ord
{
let other = other.into_par_iter();
let ord_len = self.len().cmp(&other.len());
self.zip(other)
.map(|(x, y)| Ord::cmp(&x, &y))
.find_first(|&ord| ord != Ordering::Equal)
.unwrap_or(ord_len)
}
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialOrd<I::Item>
{
let other = other.into_par_iter();
let ord_len = self.len().cmp(&other.len());
self.zip(other)
.map(|(x, y)| PartialOrd::partial_cmp(&x, &y))
.find_first(|&ord| ord != Some(Ordering::Equal))
.unwrap_or(Some(ord_len))
}
fn eq<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialEq<I::Item>
{
let other = other.into_par_iter();
self.len() == other.len() && self.zip(other).all(|(x, y)| x.eq(&y))
}
fn ne<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialEq<I::Item>
{
!self.eq(other)
}
fn lt<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialOrd<I::Item>
{
self.partial_cmp(other) == Some(Ordering::Less)
}
fn le<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialOrd<I::Item>
{
let ord = self.partial_cmp(other);
ord == Some(Ordering::Equal) || ord == Some(Ordering::Less)
}
fn gt<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialOrd<I::Item>
{
self.partial_cmp(other) == Some(Ordering::Greater)
}
fn ge<I>(self, other: I) -> bool
where I: IntoParallelIterator,
I::Iter: IndexedParallelIterator,
Self::Item: PartialOrd<I::Item>
{
let ord = self.partial_cmp(other);
ord == Some(Ordering::Equal) || ord == Some(Ordering::Greater)
}
fn enumerate(self) -> Enumerate<Self> {
enumerate::new(self)
}
fn skip(self, n: usize) -> Skip<Self> {
skip::new(self, n)
}
fn take(self, n: usize) -> Take<Self> {
take::new(self, n)
}
fn position_any<P>(self, predicate: P) -> Option<usize>
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.map(predicate)
.enumerate()
.find_any(|&(_, p)| p)
.map(|(i, _)| i)
}
fn position_first<P>(self, predicate: P) -> Option<usize>
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.map(predicate)
.enumerate()
.find_first(|&(_, p)| p)
.map(|(i, _)| i)
}
fn position_last<P>(self, predicate: P) -> Option<usize>
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.map(predicate)
.enumerate()
.find_last(|&(_, p)| p)
.map(|(i, _)| i)
}
#[doc(hidden)]
#[deprecated(note = "parallel `position` does not search in order -- use `position_any`, \\
`position_first`, or `position_last`")]
fn position<P>(self, predicate: P) -> Option<usize>
where P: Fn(Self::Item) -> bool + Sync + Send
{
self.position_any(predicate)
}
fn rev(self) -> Rev<Self> {
rev::new(self)
}
fn with_min_len(self, min: usize) -> MinLen<Self> {
len::new_min_len(self, min)
}
fn with_max_len(self, max: usize) -> MaxLen<Self> {
len::new_max_len(self, max)
}
fn len(&self) -> usize;
fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result;
fn with_producer<CB: ProducerCallback<Self::Item>>(self, callback: CB) -> CB::Output;
}
pub trait FromParallelIterator<T>
where T: Send
{
fn from_par_iter<I>(par_iter: I) -> Self where I: IntoParallelIterator<Item = T>;
}
pub trait ParallelExtend<T>
where T: Send
{
fn par_extend<I>(&mut self, par_iter: I) where I: IntoParallelIterator<Item = T>;
}