#![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::result::ParResultIter;
use crate::result::par_core::ParResultCore;
use crate::result_use::ParUseResultIter;
use crate::runner::ParRunner;
use crate::sizes::{OneOne, SizePair};
use crate::use_var::{UseSlice, UseVec};
use crate::{ChunkSize, IterationOrder, NumThreads, ParExtend, ParUseResult, Sum};
use alloc::vec::Vec;
use core::cmp::Ordering;
use orx_concurrent_iter::ExactSizeConcurrentIter;
pub trait ParResult: Sized + ParResultCore {
fn runner<Q: ParRunner>(
self,
runner: Q,
) -> impl ParResult<
Elem = Self::Elem,
Error = Self::Error,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = Self::Xap2,
Input = Self::Input,
Size = Self::Size,
>;
#[cfg(feature = "std")]
fn runner_with_diagnostics(
self,
) -> impl ParResult<
Elem = Self::Elem,
Error = Self::Error,
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 ParUseResult<
Elem = Self::Elem,
Error = Self::Error,
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);
ParUseResultIter::new(u, iter, x1, x2, exe, params)
}
fn use_vec<U, F>(
self,
use_vec: &mut UseVec<U, F>,
) -> impl ParUseResult<
Elem = Self::Elem,
Error = Self::Error,
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);
ParUseResultIter::new(use_vec, iter, x1, x2, exe, params)
}
fn use_slice<'a, U>(
self,
slice: &'a mut [U],
) -> impl ParUseResult<
Elem = Self::Elem,
Error = Self::Error,
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);
ParUseResultIter::new(u, iter, x1, x2, exe, params)
}
fn copied<'a, O>(
self,
) -> impl ParResult<
Elem = O,
Error = Self::Error,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, FnCopied<'a, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParResult<Elem = &'a O>,
O: Copy + 'a,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
ParResultIter::new(iter, x1, x2.mapped(FnCopied::new()), exe, params)
}
fn cloned<'a, O>(
self,
) -> impl ParResult<
Elem = O,
Error = Self::Error,
Xap1 = Self::Xap1,
M = Self::M,
Xap2 = MappedOf<Self::Xap2, FnCloned<'a, O>>,
Input = Self::Input,
Size = Self::Size,
>
where
Self: ParResult<Elem = &'a O>,
O: Clone + 'a,
{
let (iter, x1, x2, exe, _, params) = self.destruct();
ParResultIter::new(iter, x1, x2.mapped(FnCloned::new()), exe, params)
}
fn map<Q, H>(
self,
h: H,
) -> impl ParResult<
Elem = Q,
Error = Self::Error,
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 ParResult<
Elem = Self::Elem,
Error = Self::Error,
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 ParResult<
Elem = Self::Elem,
Error = Self::Error,
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 ParResult<
Elem = Q,
Error = Self::Error,
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 ParResult<
Elem = V::Item,
Error = Self::Error,
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 ParResult<
Elem = <Self::Elem as IntoIterator>::Item,
Error = Self::Error,
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: ParResult<Size = OneOne>,
{
self.size_hint().0
}
fn is_empty(&self) -> bool
where
Self::Input: ExactSizeConcurrentIter,
Self: ParResult<Size = OneOne>,
{
self.len() == 0
}
fn first(self) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
Self::Error: Send;
fn reduce<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
where
F: Fn(Self::Elem, Self::Elem) -> Self::Elem + Send + Copy,
Self::Elem: Send,
Self::Error: Send;
fn collect_into<P>(self, dst: &mut P) -> Result<(), Self::Error>
where
P: ParExtend<Self::Elem>,
Self::Elem: Send,
Self::Error: Send;
fn collect<P>(self) -> Result<P, Self::Error>
where
P: ParExtend<Self::Elem> + Default,
Self::Elem: Send,
Self::Error: Send,
{
let mut dst = P::default();
self.collect_into(&mut dst)?;
Ok(dst)
}
fn all<F>(self, f: F) -> Result<bool, Self::Error>
where
Self::Elem: Send,
F: Fn(&Self::Elem) -> bool + Sync,
Self::Error: Send,
{
self.map(|x| f(&x))
.find(|x| !*x)
.map(|x| x.map(|_| false).unwrap_or(true))
}
fn any<F>(self, f: F) -> Result<bool, Self::Error>
where
Self::Elem: Send,
F: Fn(&Self::Elem) -> bool + Sync,
Self::Error: Send,
{
self.map(|x| f(&x)).find(|x| *x).map(|x| x.is_some())
}
fn count(self) -> Result<usize, Self::Error>
where
Self::Elem: Send,
Self::Error: Send,
{
self.map(|_| 1).reduce(|a, b| a + b).map(|x| x.unwrap_or(0))
}
fn find<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
F: Fn(&Self::Elem) -> bool + Sync,
Self::Error: Send,
{
self.filter(&f).first()
}
fn fold<B, I, F>(self, init: I, f: F) -> Result<Vec<B>, Self::Error>
where
B: Send,
I: Fn() -> B + Sync,
F: Fn(&mut B, Self::Elem) + Copy + Send,
Self::Error: 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) -> Result<(), Self::Error>
where
F: Fn(Self::Elem) + Send + Copy,
Self::Error: Send,
{
self.map(f).reduce(|_, _| {}).map(|_| ())
}
fn max(self) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Ord + Send,
Self::Error: Send,
{
self.reduce(Ord::max)
}
fn max_by<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,
Self::Error: Send,
{
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) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
B: Ord,
F: Fn(&Self::Elem) -> B + Sync,
Self::Error: Send,
{
let reduce = |x, y| match f(&x).cmp(&f(&y)) {
Ordering::Greater | Ordering::Equal => x,
Ordering::Less => y,
};
self.reduce(reduce)
}
fn min(self) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Ord + Send,
Self::Error: Send,
{
self.reduce(Ord::min)
}
fn min_by<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,
Self::Error: Send,
{
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) -> Result<Option<Self::Elem>, Self::Error>
where
Self::Elem: Send,
B: Ord,
F: Fn(&Self::Elem) -> B + Sync,
Self::Error: Send,
{
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) -> Result<S, Self::Error>
where
Self::Elem: Sum<S>,
S: Send,
Self::Error: Send,
{
self.map(Self::Elem::owned)
.reduce(Self::Elem::add)
.map(|x| x.unwrap_or(Self::Elem::zero()))
}
}