use self::plumbing::*;
use self::private::Try;
pub use either::Either;
use std::cmp::Ordering;
use std::collections::LinkedList;
use std::iter::{Product, Sum};
use std::ops::{Fn, RangeBounds};
pub mod plumbing;
#[cfg(test)]
mod test;
mod blocks;
mod chain;
mod chunks;
mod cloned;
mod collect;
mod copied;
mod empty;
mod enumerate;
mod extend;
mod filter;
mod filter_map;
mod find;
mod find_first_last;
mod flat_map;
mod flat_map_iter;
mod flatten;
mod flatten_iter;
mod fold;
mod fold_chunks;
mod fold_chunks_with;
mod for_each;
mod from_par_iter;
mod inspect;
mod interleave;
mod interleave_shortest;
mod intersperse;
mod len;
mod map;
mod map_with;
mod multizip;
mod noop;
mod once;
mod panic_fuse;
mod par_bridge;
mod positions;
mod product;
mod reduce;
mod repeat;
mod rev;
mod skip;
mod skip_any;
mod skip_any_while;
mod splitter;
mod step_by;
mod sum;
mod take;
mod take_any;
mod take_any_while;
mod try_fold;
mod try_reduce;
mod try_reduce_with;
mod unzip;
mod update;
mod walk_tree;
mod while_some;
mod zip;
mod zip_eq;
pub use self::{
blocks::{ExponentialBlocks, UniformBlocks},
chain::Chain,
chunks::Chunks,
cloned::Cloned,
copied::Copied,
empty::{empty, Empty},
enumerate::Enumerate,
filter::Filter,
filter_map::FilterMap,
flat_map::FlatMap,
flat_map_iter::FlatMapIter,
flatten::Flatten,
flatten_iter::FlattenIter,
fold::{Fold, FoldWith},
fold_chunks::FoldChunks,
fold_chunks_with::FoldChunksWith,
inspect::Inspect,
interleave::Interleave,
interleave_shortest::InterleaveShortest,
intersperse::Intersperse,
len::{MaxLen, MinLen},
map::Map,
map_with::{MapInit, MapWith},
multizip::MultiZip,
once::{once, Once},
panic_fuse::PanicFuse,
par_bridge::{IterBridge, ParallelBridge},
positions::Positions,
repeat::{repeat, repeat_n, Repeat, RepeatN},
rev::Rev,
skip::Skip,
skip_any::SkipAny,
skip_any_while::SkipAnyWhile,
splitter::{split, Split},
step_by::StepBy,
take::Take,
take_any::TakeAny,
take_any_while::TakeAnyWhile,
try_fold::{TryFold, TryFoldWith},
update::Update,
walk_tree::{
walk_tree, walk_tree_postfix, walk_tree_prefix, WalkTree, WalkTreePostfix, WalkTreePrefix,
},
while_some::WhileSome,
zip::Zip,
zip_eq::ZipEq,
};
#[allow(deprecated)]
pub use repeat::repeatn;
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).collect()
}
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).collect()
}
fn try_for_each<OP, R>(self, op: OP) -> R
where
OP: Fn(Self::Item) -> R + Sync + Send,
R: Try<Output = ()> + Send,
{
fn ok<R: Try<Output = ()>>(_: (), _: ()) -> R {
R::from_output(())
}
self.map(op).try_reduce(<()>::default, 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<Output = ()> + Send,
{
fn ok<R: Try<Output = ()>>(_: (), _: ()) -> R {
R::from_output(())
}
self.map_with(init, op).try_reduce(<()>::default, 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<Output = ()> + Send,
{
fn ok<R: Try<Output = ()>>(_: (), _: ()) -> R {
R::from_output(())
}
self.map_init(init, op).try_reduce(<()>::default, ok)
}
fn count(self) -> usize {
fn one<T>(_: T) -> usize {
1
}
self.map(one).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 copied<'a, T>(self) -> Copied<Self>
where
T: 'a + Copy + Send,
Self: ParallelIterator<Item = &'a T>,
{
Copied::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 flat_map_iter<F, SI>(self, map_op: F) -> FlatMapIter<Self, F>
where
F: Fn(Self::Item) -> SI + Sync + Send,
SI: IntoIterator<Item: Send>,
{
FlatMapIter::new(self, map_op)
}
fn flatten(self) -> Flatten<Self>
where
Self::Item: IntoParallelIterator,
{
Flatten::new(self)
}
fn flatten_iter(self) -> FlattenIter<Self>
where
Self::Item: IntoIterator<Item: Send>,
{
FlattenIter::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,
{
fn opt_fold<T>(op: impl Fn(T, T) -> T) -> impl Fn(Option<T>, T) -> Option<T> {
move |opt_a, b| match opt_a {
Some(a) => Some(op(a, b)),
None => Some(b),
}
}
fn opt_reduce<T>(op: impl Fn(T, T) -> T) -> impl Fn(Option<T>, Option<T>) -> Option<T> {
move |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,
}
}
self.fold(<_>::default, opt_fold(&op))
.reduce(<_>::default, opt_reduce(&op))
}
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<Output = 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<Output = 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<Output = 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<Output = 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(Ord::min)
}
fn min_by<F>(self, f: F) -> Option<Self::Item>
where
F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering,
{
fn min<T>(f: impl Fn(&T, &T) -> Ordering) -> impl Fn(T, T) -> T {
move |a, b| match f(&a, &b) {
Ordering::Greater => b,
_ => a,
}
}
self.reduce_with(min(f))
}
fn min_by_key<K, F>(self, f: F) -> Option<Self::Item>
where
K: Ord + Send,
F: Sync + Send + Fn(&Self::Item) -> K,
{
fn key<T, K>(f: impl Fn(&T) -> K) -> impl Fn(T) -> (K, T) {
move |x| (f(&x), x)
}
fn min_key<T, K: Ord>(a: (K, T), b: (K, T)) -> (K, T) {
match (a.0).cmp(&b.0) {
Ordering::Greater => b,
_ => a,
}
}
let (_, x) = self.map(key(f)).reduce_with(min_key)?;
Some(x)
}
fn max(self) -> Option<Self::Item>
where
Self::Item: Ord,
{
self.reduce_with(Ord::max)
}
fn max_by<F>(self, f: F) -> Option<Self::Item>
where
F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering,
{
fn max<T>(f: impl Fn(&T, &T) -> Ordering) -> impl Fn(T, T) -> T {
move |a, b| match f(&a, &b) {
Ordering::Greater => a,
_ => b,
}
}
self.reduce_with(max(f))
}
fn max_by_key<K, F>(self, f: F) -> Option<Self::Item>
where
K: Ord + Send,
F: Sync + Send + Fn(&Self::Item) -> K,
{
fn key<T, K>(f: impl Fn(&T) -> K) -> impl Fn(T) -> (K, T) {
move |x| (f(&x), x)
}
fn max_key<T, K: Ord>(a: (K, T), b: (K, T)) -> (K, T) {
match (a.0).cmp(&b.0) {
Ordering::Greater => a,
_ => b,
}
}
let (_, x) = self.map(key(f)).reduce_with(max_key)?;
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,
{
fn yes<T>(_: &T) -> bool {
true
}
self.filter_map(predicate).find_any(yes)
}
fn find_map_first<P, R>(self, predicate: P) -> Option<R>
where
P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send,
{
fn yes<T>(_: &T) -> bool {
true
}
self.filter_map(predicate).find_first(yes)
}
fn find_map_last<P, R>(self, predicate: P) -> Option<R>
where
P: Fn(Self::Item) -> Option<R> + Sync + Send,
R: Send,
{
fn yes<T>(_: &T) -> bool {
true
}
self.filter_map(predicate).find_last(yes)
}
#[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(bool::clone).is_some()
}
fn all<P>(self, predicate: P) -> bool
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
#[inline]
fn is_false(x: &bool) -> bool {
!x
}
self.map(predicate).find_any(is_false).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 take_any(self, n: usize) -> TakeAny<Self> {
TakeAny::new(self, n)
}
fn skip_any(self, n: usize) -> SkipAny<Self> {
SkipAny::new(self, n)
}
fn take_any_while<P>(self, predicate: P) -> TakeAnyWhile<Self, P>
where
P: Fn(&Self::Item) -> bool + Sync + Send,
{
TakeAnyWhile::new(self, predicate)
}
fn skip_any_while<P>(self, predicate: P) -> SkipAnyWhile<Self, P>
where
P: Fn(&Self::Item) -> bool + Sync + Send,
{
SkipAnyWhile::new(self, predicate)
}
fn collect_vec_list(self) -> LinkedList<Vec<Self::Item>> {
match extend::fast_collect(self) {
Either::Left(vec) => {
let mut list = LinkedList::new();
if !vec.is_empty() {
list.push_back(vec);
}
list
}
Either::Right(list) => list,
}
}
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
}
}
#[allow(clippy::len_without_is_empty)]
pub trait IndexedParallelIterator: ParallelIterator {
fn by_exponential_blocks(self) -> ExponentialBlocks<Self> {
ExponentialBlocks::new(self)
}
#[track_caller]
fn by_uniform_blocks(self, block_size: usize) -> UniformBlocks<Self> {
assert!(block_size != 0, "block_size must not be zero");
UniformBlocks::new(self, block_size)
}
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<Iter: IndexedParallelIterator>,
{
Zip::new(self, zip_op.into_par_iter())
}
#[track_caller]
fn zip_eq<Z>(self, zip_op: Z) -> ZipEq<Self, Z::Iter>
where
Z: IntoParallelIterator<Iter: IndexedParallelIterator>,
{
let zip_op_iter = zip_op.into_par_iter();
assert_eq!(
self.len(),
zip_op_iter.len(),
"iterators must have the same length"
);
ZipEq::new(self, zip_op_iter)
}
fn interleave<I>(self, other: I) -> Interleave<Self, I::Iter>
where
I: IntoParallelIterator<Item = Self::Item, Iter: IndexedParallelIterator>,
{
Interleave::new(self, other.into_par_iter())
}
fn interleave_shortest<I>(self, other: I) -> InterleaveShortest<Self, I::Iter>
where
I: IntoParallelIterator<Item = Self::Item, Iter: IndexedParallelIterator>,
{
InterleaveShortest::new(self, other.into_par_iter())
}
#[track_caller]
fn chunks(self, chunk_size: usize) -> Chunks<Self> {
assert!(chunk_size != 0, "chunk_size must not be zero");
Chunks::new(self, chunk_size)
}
#[track_caller]
fn fold_chunks<T, ID, F>(
self,
chunk_size: usize,
identity: ID,
fold_op: F,
) -> FoldChunks<Self, ID, F>
where
ID: Fn() -> T + Send + Sync,
F: Fn(T, Self::Item) -> T + Send + Sync,
T: Send,
{
assert!(chunk_size != 0, "chunk_size must not be zero");
FoldChunks::new(self, chunk_size, identity, fold_op)
}
#[track_caller]
fn fold_chunks_with<T, F>(
self,
chunk_size: usize,
init: T,
fold_op: F,
) -> FoldChunksWith<Self, T, F>
where
T: Send + Clone,
F: Fn(T, Self::Item) -> T + Send + Sync,
{
assert!(chunk_size != 0, "chunk_size must not be zero");
FoldChunksWith::new(self, chunk_size, init, fold_op)
}
fn cmp<I>(self, other: I) -> Ordering
where
I: IntoParallelIterator<Item = Self::Item, Iter: IndexedParallelIterator>,
Self::Item: Ord,
{
#[inline]
fn ordering<T: Ord>((x, y): (T, T)) -> Ordering {
Ord::cmp(&x, &y)
}
#[inline]
fn inequal(&ord: &Ordering) -> bool {
ord != Ordering::Equal
}
let other = other.into_par_iter();
let ord_len = self.len().cmp(&other.len());
self.zip(other)
.map(ordering)
.find_first(inequal)
.unwrap_or(ord_len)
}
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where
I: IntoParallelIterator<Iter: IndexedParallelIterator>,
Self::Item: PartialOrd<I::Item>,
{
#[inline]
fn ordering<T: PartialOrd<U>, U>((x, y): (T, U)) -> Option<Ordering> {
PartialOrd::partial_cmp(&x, &y)
}
#[inline]
fn inequal(&ord: &Option<Ordering>) -> bool {
ord != Some(Ordering::Equal)
}
let other = other.into_par_iter();
let ord_len = self.len().cmp(&other.len());
self.zip(other)
.map(ordering)
.find_first(inequal)
.unwrap_or(Some(ord_len))
}
fn eq<I>(self, other: I) -> bool
where
I: IntoParallelIterator<Iter: IndexedParallelIterator>,
Self::Item: PartialEq<I::Item>,
{
#[inline]
fn eq<T: PartialEq<U>, U>((x, y): (T, U)) -> bool {
PartialEq::eq(&x, &y)
}
let other = other.into_par_iter();
self.len() == other.len() && self.zip(other).all(eq)
}
fn ne<I>(self, other: I) -> bool
where
I: IntoParallelIterator<Iter: IndexedParallelIterator>,
Self::Item: PartialEq<I::Item>,
{
!self.eq(other)
}
fn lt<I>(self, other: I) -> bool
where
I: IntoParallelIterator<Iter: IndexedParallelIterator>,
Self::Item: PartialOrd<I::Item>,
{
self.partial_cmp(other) == Some(Ordering::Less)
}
fn le<I>(self, other: I) -> bool
where
I: IntoParallelIterator<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<Iter: IndexedParallelIterator>,
Self::Item: PartialOrd<I::Item>,
{
self.partial_cmp(other) == Some(Ordering::Greater)
}
fn ge<I>(self, other: I) -> bool
where
I: IntoParallelIterator<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 step_by(self, step: usize) -> StepBy<Self> {
StepBy::new(self, step)
}
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,
{
#[inline]
fn check(&(_, p): &(usize, bool)) -> bool {
p
}
let (i, _) = self.map(predicate).enumerate().find_any(check)?;
Some(i)
}
fn position_first<P>(self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
#[inline]
fn check(&(_, p): &(usize, bool)) -> bool {
p
}
let (i, _) = self.map(predicate).enumerate().find_first(check)?;
Some(i)
}
fn position_last<P>(self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
#[inline]
fn check(&(_, p): &(usize, bool)) -> bool {
p
}
let (i, _) = self.map(predicate).enumerate().find_last(check)?;
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 positions<P>(self, predicate: P) -> Positions<Self, P>
where
P: Fn(Self::Item) -> bool + Sync + Send,
{
Positions::new(self, 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>;
}
pub trait ParallelDrainFull {
type Iter: ParallelIterator<Item = Self::Item>;
type Item: Send;
fn par_drain(self) -> Self::Iter;
}
pub trait ParallelDrainRange<Idx = usize> {
type Iter: ParallelIterator<Item = Self::Item>;
type Item: Send;
fn par_drain<R: RangeBounds<Idx>>(self, range: R) -> Self::Iter;
}
mod private {
use std::convert::Infallible;
use std::ops::ControlFlow::{self, Break, Continue};
use std::task::Poll;
pub trait Try {
private_decl! {}
type Output;
type Residual;
fn from_output(output: Self::Output) -> Self;
fn from_residual(residual: Self::Residual) -> Self;
fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
}
impl<B, C> Try for ControlFlow<B, C> {
private_impl! {}
type Output = C;
type Residual = ControlFlow<B, Infallible>;
fn from_output(output: Self::Output) -> Self {
Continue(output)
}
fn from_residual(residual: Self::Residual) -> Self {
match residual {
Break(b) => Break(b),
#[allow(unreachable_patterns)]
Continue(_) => unreachable!(),
}
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Continue(c) => Continue(c),
Break(b) => Break(Break(b)),
}
}
}
impl<T> Try for Option<T> {
private_impl! {}
type Output = T;
type Residual = Option<Infallible>;
fn from_output(output: Self::Output) -> Self {
Some(output)
}
fn from_residual(residual: Self::Residual) -> Self {
match residual {
None => None,
#[allow(unreachable_patterns)]
Some(_) => unreachable!(),
}
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Some(c) => Continue(c),
None => Break(None),
}
}
}
impl<T, E> Try for Result<T, E> {
private_impl! {}
type Output = T;
type Residual = Result<Infallible, E>;
fn from_output(output: Self::Output) -> Self {
Ok(output)
}
fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Err(e),
#[allow(unreachable_patterns)]
Ok(_) => unreachable!(),
}
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Ok(c) => Continue(c),
Err(e) => Break(Err(e)),
}
}
}
impl<T, E> Try for Poll<Result<T, E>> {
private_impl! {}
type Output = Poll<T>;
type Residual = Result<Infallible, E>;
fn from_output(output: Self::Output) -> Self {
output.map(Ok)
}
fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Poll::Ready(Err(e)),
#[allow(unreachable_patterns)]
Ok(_) => unreachable!(),
}
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Poll::Pending => Continue(Poll::Pending),
Poll::Ready(Ok(c)) => Continue(Poll::Ready(c)),
Poll::Ready(Err(e)) => Break(Err(e)),
}
}
}
impl<T, E> Try for Poll<Option<Result<T, E>>> {
private_impl! {}
type Output = Poll<Option<T>>;
type Residual = Result<Infallible, E>;
fn from_output(output: Self::Output) -> Self {
match output {
Poll::Ready(o) => Poll::Ready(o.map(Ok)),
Poll::Pending => Poll::Pending,
}
}
fn from_residual(residual: Self::Residual) -> Self {
match residual {
Err(e) => Poll::Ready(Some(Err(e))),
#[allow(unreachable_patterns)]
Ok(_) => unreachable!(),
}
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Poll::Pending => Continue(Poll::Pending),
Poll::Ready(None) => Continue(Poll::Ready(None)),
Poll::Ready(Some(Ok(c))) => Continue(Poll::Ready(Some(c))),
Poll::Ready(Some(Err(e))) => Break(Err(e)),
}
}
}
}