use crate::infallible::recursive::par_core::ParRecCore;
use crate::infallible::xap::FlattenOf;
use crate::infallible::{FilMapOf, FilOf, FlatMapOf, InsOf, MapOf};
use crate::runner::ParRunner;
use crate::{ChunkSize, IterationOrder, NumThreads};
use crate::{ParExtend, Sum};
use alloc::vec::Vec;
use core::cmp::Ordering;
pub trait ParRec: Sized + ParRecCore {
fn runner<Q: ParRunner>(
self,
runner: Q,
) -> impl ParRec<Item = Self::Item, Xap = Self::Xap, Input = Self::Input>;
#[cfg(feature = "std")]
fn runner_with_diagnostics(
self,
) -> impl ParRec<Item = Self::Item, Xap = Self::Xap, Input = Self::Input>;
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 map<Q, H>(
self,
h: H,
) -> impl ParRec<Item = Q, Xap = MapOf<Self::Xap, Q, H>, Input = Self::Input>
where
H: Fn(Self::Item) -> Q + Copy + Send;
fn inspect<H>(
self,
h: H,
) -> impl ParRec<Item = Self::Item, Xap = InsOf<Self::Xap, H>, Input = Self::Input>
where
H: Fn(&Self::Item) + Copy + Send;
fn filter<H>(
self,
h: H,
) -> impl ParRec<Item = Self::Item, Xap = FilOf<Self::Xap, H>, Input = Self::Input>
where
H: Fn(&Self::Item) -> bool + Copy + Send;
fn filter_map<Q, H>(
self,
h: H,
) -> impl ParRec<Item = Q, Xap = FilMapOf<Self::Xap, Q, H>, Input = Self::Input>
where
H: Fn(Self::Item) -> Option<Q> + Copy + Send;
fn flat_map<V, H>(
self,
h: H,
) -> impl ParRec<Item = V::Item, Xap = FlatMapOf<Self::Xap, V, H>, Input = Self::Input>
where
V: IntoIterator,
H: Fn(Self::Item) -> V + Copy + Send;
fn flatten(
self,
) -> impl ParRec<
Item = <Self::Item as IntoIterator>::Item,
Xap = FlattenOf<Self::Xap>,
Input = Self::Input,
>
where
Self::Item: IntoIterator;
fn first(self) -> Option<Self::Item>
where
Self::Item: Send,
<Self::Input as IntoIterator>::Item: Send;
fn reduce<F>(self, f: F) -> Option<Self::Item>
where
F: Fn(Self::Item, Self::Item) -> Self::Item + Send + Copy,
Self::Item: Send,
<Self::Input as IntoIterator>::Item: Send;
fn collect_into<P>(self, dst: &mut P)
where
P: ParExtend<Self::Item>,
Self::Item: Send,
<Self::Input as IntoIterator>::Item: Send;
fn collect<P>(self) -> P
where
P: ParExtend<Self::Item> + Default,
Self::Item: Send,
<Self::Input as IntoIterator>::Item: Send,
{
let mut dst = P::default();
self.collect_into(&mut dst);
dst
}
fn all<F>(self, f: F) -> bool
where
F: Fn(&Self::Item) -> bool + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.map(move |x| f(&x)).find(|x| !*x).is_none()
}
fn any<F>(self, f: F) -> bool
where
F: Fn(&Self::Item) -> bool + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.map(move |x| f(&x)).find(|x| *x).is_some()
}
fn count(self) -> usize
where
<Self::Input as IntoIterator>::Item: Send,
{
self.map(|_| 1).reduce(|a, b| a + b).unwrap_or(0)
}
fn find<F>(self, f: F) -> Option<Self::Item>
where
Self::Item: Send,
F: Fn(&Self::Item) -> bool + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.filter(f).first()
}
fn fold<B, I, F>(self, init: I, f: F) -> Vec<B>
where
B: Send,
I: Fn() -> B,
F: Fn(&mut B, Self::Item) + Copy + Send,
<Self::Input as IntoIterator>::Item: Send;
fn for_each<F>(self, f: F)
where
F: Fn(Self::Item) + Send + Copy,
<Self::Input as IntoIterator>::Item: Send,
{
let _ = self.map(f).reduce(|_, _| {});
}
fn max(self) -> Option<Self::Item>
where
Self::Item: Ord + Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.reduce(Ord::max)
}
fn max_by<F>(self, f: F) -> Option<Self::Item>
where
Self::Item: Send,
F: Fn(&Self::Item, &Self::Item) -> Ordering + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
let reduce = move |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<Self::Item>
where
Self::Item: Send,
B: Ord,
F: Fn(&Self::Item) -> B + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
let reduce = move |x, y| match f(&x).cmp(&f(&y)) {
Ordering::Greater | Ordering::Equal => x,
Ordering::Less => y,
};
self.reduce(reduce)
}
fn min(self) -> Option<Self::Item>
where
Self::Item: Ord + Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.reduce(Ord::min)
}
fn min_by<F>(self, f: F) -> Option<Self::Item>
where
Self::Item: Send,
F: Fn(&Self::Item, &Self::Item) -> Ordering + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
let reduce = move |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<Self::Item>
where
Self::Item: Send,
B: Ord,
F: Fn(&Self::Item) -> B + Copy + Send,
<Self::Input as IntoIterator>::Item: Send,
{
let reduce = move |x, y| match f(&x).cmp(&f(&y)) {
Ordering::Less | Ordering::Equal => x,
Ordering::Greater => y,
};
self.reduce(reduce)
}
fn sum<S>(self) -> S
where
Self::Item: Sum<S>,
S: Send,
<Self::Input as IntoIterator>::Item: Send,
{
self.map(Self::Item::owned)
.reduce(Self::Item::add)
.unwrap_or(Self::Item::zero())
}
}