#![allow(clippy::type_complexity)]
use crate::infallible_use::fun::{UFnCloned, UFnCopied};
use crate::infallible_use::{
FilMapOf, FilOf, FlatMapOf, FlattenOf, InsOf, MapOf, MappedOf, XapUse,
};
use crate::option_use::ParUseOptionIter;
use crate::option_use::par_core::ParUseOptionCore;
use crate::runner::ParRunner;
use crate::sizes::{OneOne, SizePair};
use crate::{ChunkSize, IterationOrder, NumThreads, ParExtend, Sum};
use core::cmp::Ordering;
use orx_concurrent_iter::ExactSizeConcurrentIter;
pub trait ParUseOption: Sized + ParUseOptionCore {
fn runner<Q: ParRunner>(
self,
runner: Q,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = Self::Xap2,
Input = Self::Input,
Size = Self::Size,
>;
#[cfg(feature = "std")]
fn runner_with_diagnostics(
self,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = Self::Xap2,
Input = Self::Input,
Size = Self::Size,
>;
fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
fn iteration_order(self, iteration_order: IterationOrder) -> Self;
fn copied<'a, O>(
self,
) -> impl ParUseOption<
Elem = O,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, UFnCopied<'a, Self::Use, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParUseOption<Elem = &'a O>,
O: Copy + 'a,
Self::Use: 'a,
{
let (u, iter, x1, x2, exe, _, params) = self.destruct();
ParUseOptionIter::new(u, iter, x1, x2.mapped(UFnCopied::new()), exe, params)
}
fn cloned<'a, O>(
self,
) -> impl ParUseOption<
Elem = O,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, UFnCloned<'a, Self::Use, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParUseOption<Elem = &'a O>,
O: Clone + 'a,
Self::Use: 'a,
{
let (u, iter, x1, x2, exe, _, params) = self.destruct();
ParUseOptionIter::new(u, iter, x1, x2.mapped(UFnCloned::new()), exe, params)
}
fn map<Q, H>(
self,
h: H,
) -> impl ParUseOption<
Elem = Q,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MapOf<Self::Xap2, Q, H>,
Input = Self::Input,
Size = Self::Size,
>
where
H: Fn(&mut Self::Use, Self::Elem) -> Q + Copy + Send;
fn inspect<H>(
self,
h: H,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = InsOf<Self::Xap2, H>,
Input = Self::Input,
Size = Self::Size,
>
where
H: Fn(&mut Self::Use, &Self::Elem) + Copy + Send;
fn filter<H>(
self,
h: H,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FilOf<Self::Xap2, H>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenBin,
>
where
H: Fn(&mut Self::Use, &Self::Elem) -> bool + Copy + Send;
fn filter_map<Q, H>(
self,
h: H,
) -> impl ParUseOption<
Elem = Q,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FilMapOf<Self::Xap2, Q, H>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenBin,
>
where
H: Fn(&mut Self::Use, Self::Elem) -> Option<Q> + Copy + Send;
fn flat_map<V, H>(
self,
h: H,
) -> impl ParUseOption<
Elem = V::Item,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FlatMapOf<Self::Xap2, V, H>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenMany,
>
where
V: IntoIterator,
H: Fn(&mut Self::Use, Self::Elem) -> V + Copy + Send;
fn flatten(
self,
) -> impl ParUseOption<
Elem = <Self::Elem as IntoIterator>::Item,
Use = Self::Use,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FlattenOf<Self::Xap2>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenMany,
>
where
Self::Elem: IntoIterator;
fn size_hint(&self) -> (usize, Option<usize>);
fn len(&self) -> usize
where
Self::Input: ExactSizeConcurrentIter,
Self: ParUseOption<Size = OneOne>,
{
self.size_hint().0
}
fn is_empty(&self) -> bool
where
Self::Input: ExactSizeConcurrentIter,
Self: ParUseOption<Size = OneOne>,
{
self.len() == 0
}
fn first(self) -> Option<Option<Self::Elem>>
where
Self::Elem: Send;
fn reduce<F>(self, f: F) -> Option<Option<Self::Elem>>
where
F: Fn(&mut Self::Use, Self::Elem, Self::Elem) -> Self::Elem + Send + Copy,
Self::Elem: Send;
fn collect_into<P>(self, dst: &mut P) -> Option<()>
where
P: ParExtend<Self::Elem>,
Self::Elem: Send;
fn collect<P>(self) -> Option<P>
where
P: ParExtend<Self::Elem> + Default,
Self::Elem: Send,
{
let mut dst = P::default();
self.collect_into(&mut dst)?;
Some(dst)
}
fn all<F>(self, f: F) -> Option<bool>
where
Self::Elem: Send,
F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
{
self.map(|u, x| f(u, &x))
.find(|_, x| !*x)
.map(|x| x.is_none())
}
fn any<F>(self, f: F) -> Option<bool>
where
Self::Elem: Send,
F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
{
self.map(|u, x| f(u, &x))
.find(|_, x| *x)
.map(|x| x.is_some())
}
fn count(self) -> Option<usize> {
self.map(|_, _| 1)
.reduce(|_, a, b| a + b)
.map(|x| x.unwrap_or(0))
}
fn find<F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
{
self.filter(&f).first()
}
fn for_each<F>(self, f: F) -> Option<()>
where
F: Fn(&mut Self::Use, Self::Elem) + Send + Copy,
{
self.map(f).reduce(|_, _, _| {}).map(|_| ())
}
fn max(self) -> Option<Option<Self::Elem>>
where
Self::Elem: Ord + Send,
{
self.reduce(|_, a, b| Ord::max(a, b))
}
fn max_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
{
let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
Ordering::Greater | Ordering::Equal => x,
Ordering::Less => y,
};
self.reduce(reduce)
}
fn max_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
B: Ord,
F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
{
let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
Ordering::Greater | Ordering::Equal => x,
Ordering::Less => y,
};
self.reduce(reduce)
}
fn min(self) -> Option<Option<Self::Elem>>
where
Self::Elem: Ord + Send,
{
self.reduce(|_, a, b| Ord::min(a, b))
}
fn min_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
{
let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
Ordering::Less | Ordering::Equal => x,
Ordering::Greater => y,
};
self.reduce(reduce)
}
fn min_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
B: Ord,
F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
{
let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
Ordering::Less | Ordering::Equal => x,
Ordering::Greater => y,
};
self.reduce(reduce)
}
fn sum<S>(self) -> Option<S>
where
Self::Elem: Sum<S>,
S: Send,
{
self.map(|_, x| Self::Elem::owned(x))
.reduce(|_, a, b| Self::Elem::add(a, b))
.map(|x| x.unwrap_or(Self::Elem::zero()))
}
}