use self::plumbing::*;
use self::private::Try;
pub use either::Either;
use std::cmp::{self, Ordering};
use std::iter::{Product, Sum};
use std::ops::Fn;
mod par_bridge;
pub use self::par_bridge::{IterBridge, ParallelBridge};
mod chain;
mod find;
mod find_first_last;
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 fold;
mod for_each;
mod from_par_iter;
pub mod plumbing;
pub use self::fold::{Fold, FoldWith};
mod try_fold;
pub use self::try_fold::{TryFold, TryFoldWith};
mod reduce;
mod skip;
mod try_reduce;
mod try_reduce_with;
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::{MapInit, 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::{MaxLen, MinLen};
mod cloned;
mod product;
mod sum;
pub use self::cloned::Cloned;
mod inspect;
pub use self::inspect::Inspect;
mod panic_fuse;
pub use self::panic_fuse::PanicFuse;
mod while_some;
pub use self::while_some::WhileSome;
mod extend;
mod repeat;
mod unzip;
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 for_each_init<OP, INIT, T>(self, init: INIT, op: OP)
where
OP: Fn(&mut T, Self::Item) + Sync + Send,
INIT: Fn() -> T + Sync + Send,
{
self.map_init(init, op).for_each(|()| ())
}
fn try_for_each<OP, R>(self, op: OP) -> R
where
OP: Fn(Self::Item) -> R + Sync + Send,
R: Try<Ok = ()> + Send,
{
self.map(op).try_reduce(|| (), |(), ()| R::from_ok(()))
}
fn try_for_each_with<OP, T, R>(self, init: T, op: OP) -> R
where
OP: Fn(&mut T, Self::Item) -> R + Sync + Send,
T: Send + Clone,
R: Try<Ok = ()> + Send,
{
self.map_with(init, op)
.try_reduce(|| (), |(), ()| R::from_ok(()))
}
fn try_for_each_init<OP, INIT, T, R>(self, init: INIT, op: OP) -> R
where
OP: Fn(&mut T, Self::Item) -> R + Sync + Send,
INIT: Fn() -> T + Sync + Send,
R: Try<Ok = ()> + Send,
{
self.map_init(init, op)
.try_reduce(|| (), |(), ()| R::from_ok(()))
}
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,
{
MapWith::new(self, init, map_op)
}
fn map_init<F, INIT, T, R>(self, init: INIT, map_op: F) -> MapInit<Self, INIT, F>
where
F: Fn(&mut T, Self::Item) -> R + Sync + Send,
INIT: Fn() -> T + Sync + Send,
R: Send,
{
MapInit::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,
{
FilterMap::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,
{
FlatMap::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 try_reduce<T, OP, ID>(self, identity: ID, op: OP) -> Self::Item
where
OP: Fn(T, T) -> Self::Item + Sync + Send,
ID: Fn() -> T + Sync + Send,
Self::Item: Try<Ok = T>,
{
try_reduce::try_reduce(self, identity, op)
}
fn try_reduce_with<T, OP>(self, op: OP) -> Option<Self::Item>
where
OP: Fn(T, T) -> Self::Item + Sync + Send,
Self::Item: Try<Ok = T>,
{
try_reduce_with::try_reduce_with(self, op)
}
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::new(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,
{
FoldWith::new(self, init, fold_op)
}
fn try_fold<T, R, ID, F>(self, identity: ID, fold_op: F) -> TryFold<Self, R, ID, F>
where
F: Fn(T, Self::Item) -> R + Sync + Send,
ID: Fn() -> T + Sync + Send,
R: Try<Ok = T> + Send,
{
TryFold::new(self, identity, fold_op)
}
fn try_fold_with<F, T, R>(self, init: T, fold_op: F) -> TryFoldWith<Self, R, F>
where
F: Fn(T, Self::Item) -> R + Sync + Send,
R: Try<Ok = T> + Send,
T: Clone + Send,
{
TryFoldWith::new(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,
{
let (_, x) = self.map(|x| (f(&x), x)).min_by(|a, b| (a.0).cmp(&b.0))?;
Some(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,
{
let (_, x) = self.map(|x| (f(&x), x)).max_by(|a, b| (a.0).cmp(&b.0))?;
Some(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)
}
fn find_map_any<P, R>(self, predicate: P) -> Option<R>
where
P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send,
{
self.filter_map(predicate).find_any(|_| true)
}
fn find_map_first<P, R>(self, predicate: P) -> Option<R>
where
P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send,
{
self.filter_map(predicate).find_first(|_| true)
}
fn find_map_last<P, R>(self, predicate: P) -> Option<R>
where
P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send,
{
self.filter_map(predicate).find_last(|_| true)
}
#[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,
{
WhileSome::new(self)
}
fn panic_fuse(self) -> PanicFuse<Self> {
PanicFuse::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());
ZipEq::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>,
{
InterleaveShortest::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 = Some(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(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,
{
let (i, _) = self.map(predicate).enumerate().find_any(|&(_, p)| p)?;
Some(i)
}
fn position_first<P>(self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
let (i, _) = self.map(predicate).enumerate().find_first(|&(_, p)| p)?;
Some(i)
}
fn position_last<P>(self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
let (i, _) = self.map(predicate).enumerate().find_last(|&(_, p)| p)?;
Some(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> {
MinLen::new(self, min)
}
fn with_max_len(self, max: usize) -> MaxLen<Self> {
MaxLen::new(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>;
}
mod private {
pub trait Try {
private_decl! {}
type Ok;
type Error;
fn into_result(self) -> Result<Self::Ok, Self::Error>;
fn from_ok(v: Self::Ok) -> Self;
fn from_error(v: Self::Error) -> Self;
}
impl<T> Try for Option<T> {
private_impl! {}
type Ok = T;
type Error = ();
fn into_result(self) -> Result<T, ()> {
self.ok_or(())
}
fn from_ok(v: T) -> Self {
Some(v)
}
fn from_error(_: ()) -> Self {
None
}
}
impl<T, E> Try for Result<T, E> {
private_impl! {}
type Ok = T;
type Error = E;
fn into_result(self) -> Result<T, E> {
self
}
fn from_ok(v: T) -> Self {
Ok(v)
}
fn from_error(v: E) -> Self {
Err(v)
}
}
}