#![allow(clippy::type_complexity)]
use crate::infallible::fun::{FnCloned, FnCopied};
use crate::infallible::{FilMapOf, FilOf, FlatMapOf, FlattenOf, InsOf, MapOf, MappedOf, Xap};
use crate::infallible_use::xap_variants::IdUse;
use crate::option::ParOptionIter;
use crate::option::par_core::ParOptionCore;
use crate::option_use::ParUseOptionIter;
use crate::runner::ParRunner;
use crate::sizes::{OneOne, SizePair};
use crate::use_var::{UseSlice, UseVec};
use crate::{ChunkSize, IterationOrder, NumThreads, ParExtend, ParUseOption, Sum};
use alloc::vec::Vec;
use core::cmp::Ordering;
use orx_concurrent_iter::ExactSizeConcurrentIter;
pub trait ParOption: Sized + ParOptionCore {
fn runner<Q: ParRunner>(
self,
runner: Q,
) -> impl ParOption<
Elem = Self::Elem,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = Self::Xap2,
Input = Self::Input,
Size = Self::Size,
>;
#[cfg(feature = "std")]
fn runner_with_diagnostics(
self,
) -> impl ParOption<
Elem = Self::Elem,
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, collect: IterationOrder) -> Self;
fn use_new<U, F>(
self,
f: F,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = U,
Xap1 = IdUse<Self::Xap1, U>,
M = Self::M,
Xap2 = IdUse<Self::Xap2, U>,
Input = Self::Input,
Size = Self::Size,
>
where
U: Send,
F: Fn(usize) -> U + Sync,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
let x1 = IdUse::<_, U>::new(x1);
let x2 = IdUse::<_, U>::new(x2);
let u = UseVec::new(f);
ParUseOptionIter::new(u, iter, x1, x2, exe, params)
}
fn use_vec<U, F>(
self,
use_vec: &mut UseVec<U, F>,
) -> impl ParUseOption<
Elem = Self::Elem,
Use = U,
Xap1 = IdUse<Self::Xap1, U>,
M = Self::M,
Xap2 = IdUse<Self::Xap2, U>,
Input = Self::Input,
Size = Self::Size,
>
where
U: Send,
F: Fn(usize) -> U + Sync,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
let x1 = IdUse::<_, U>::new(x1);
let x2 = IdUse::<_, U>::new(x2);
ParUseOptionIter::new(use_vec, iter, x1, x2, exe, params)
}
fn use_slice<'a, U>(
self,
slice: &'a mut [U],
) -> impl ParUseOption<
Elem = Self::Elem,
Use = U,
Xap1 = IdUse<Self::Xap1, U>,
M = Self::M,
Xap2 = IdUse<Self::Xap2, U>,
Input = Self::Input,
Size = Self::Size,
>
where
U: Send + 'a,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
let x1 = IdUse::<_, U>::new(x1);
let x2 = IdUse::<_, U>::new(x2);
let u = UseSlice::new(slice);
ParUseOptionIter::new(u, iter, x1, x2, exe, params)
}
fn copied<'a, O>(
self,
) -> impl ParOption<
Elem = O,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, FnCopied<'a, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParOption<Elem = &'a O>,
O: Copy + 'a,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
ParOptionIter::new(iter, x1, x2.mapped(FnCopied::new()), exe, params)
}
fn cloned<'a, O>(
self,
) -> impl ParOption<
Elem = O,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, FnCloned<'a, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParOption<Elem = &'a O>,
O: Clone + 'a,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
ParOptionIter::new(iter, x1, x2.mapped(FnCloned::new()), exe, params)
}
fn map<Q, H>(
self,
h: H,
) -> impl ParOption<
Elem = Q,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MapOf<Self::Xap2, Q, H>,
Input = Self::Input,
Size = Self::Size,
>
where
H: Fn(Self::Elem) -> Q + Copy + Send;
fn inspect<H>(
self,
h: H,
) -> impl ParOption<
Elem = Self::Elem,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = InsOf<Self::Xap2, H>,
Input = Self::Input,
Size = Self::Size,
>
where
H: Fn(&Self::Elem) + Copy + Send;
fn filter<H>(
self,
h: H,
) -> impl ParOption<
Elem = Self::Elem,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FilOf<Self::Xap2, H>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenBin,
>
where
H: Fn(&Self::Elem) -> bool + Copy + Send;
fn filter_map<Q, H>(
self,
h: H,
) -> impl ParOption<
Elem = Q,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = FilMapOf<Self::Xap2, Q, H>,
Input = Self::Input,
Size = <Self::Size as SizePair>::ThenBin,
>
where
H: Fn(Self::Elem) -> Option<Q> + Copy + Send;
fn flat_map<V, H>(
self,
h: H,
) -> impl ParOption<
Elem = V::Item,
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(Self::Elem) -> V + Copy + Send;
fn flatten(
self,
) -> impl ParOption<
Elem = <Self::Elem as IntoIterator>::Item,
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: ParOption<Size = OneOne>,
{
self.size_hint().0
}
fn is_empty(&self) -> bool
where
Self::Input: ExactSizeConcurrentIter,
Self: ParOption<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(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(&Self::Elem) -> bool + Sync,
{
self.map(|x| f(&x)).find(|x| !*x).map(|x| x.is_none())
}
fn any<F>(self, f: F) -> Option<bool>
where
Self::Elem: Send,
F: Fn(&Self::Elem) -> bool + Sync,
{
self.map(|x| f(&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(&Self::Elem) -> bool + Sync,
{
self.filter(&f).first()
}
fn fold<B, I, F>(self, init: I, f: F) -> Option<Vec<B>>
where
B: Send,
I: Fn() -> B + Sync,
F: Fn(&mut B, Self::Elem) + Copy + Send,
{
let mut use_vec = UseVec::new(|_| init());
let par_use = self.use_vec(&mut use_vec);
let result = par_use.for_each(move |u: &mut B, x| f(u, x));
result.map(|_| use_vec.into_vec())
}
fn for_each<F>(self, f: F) -> Option<()>
where
F: Fn(Self::Elem) + Send + Copy,
{
self.map(f).reduce(|_, _| {}).map(|_| ())
}
fn max(self) -> Option<Option<Self::Elem>>
where
Self::Elem: Ord + Send,
{
self.reduce(Ord::max)
}
fn max_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,
{
let reduce = |x, y| match f(&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(&Self::Elem) -> B + Sync,
{
let reduce = |x, y| match f(&x).cmp(&f(&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(Ord::min)
}
fn min_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where
Self::Elem: Send,
F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,
{
let reduce = |x, y| match f(&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(&Self::Elem) -> B + Sync,
{
let reduce = |x, y| match f(&x).cmp(&f(&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(Self::Elem::owned)
.reduce(Self::Elem::add)
.map(|x| x.unwrap_or(Self::Elem::zero()))
}
}