use crate::scalar::Scalar;
pub trait ScanOp<T: Scalar>: crate::private::Sealed + Copy + 'static {
fn identity() -> T;
fn combine(a: T, b: T) -> T;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScanAdd;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScanMul;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScanMin;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScanMax;
impl crate::private::Sealed for ScanAdd {}
impl crate::private::Sealed for ScanMul {}
impl crate::private::Sealed for ScanMin {}
impl crate::private::Sealed for ScanMax {}
impl<T: Scalar> ScanOp<T> for ScanAdd {
#[inline(always)]
fn identity() -> T {
T::ZERO
}
#[inline(always)]
fn combine(a: T, b: T) -> T {
a + b
}
}
impl<T: Scalar> ScanOp<T> for ScanMul {
#[inline(always)]
fn identity() -> T {
T::ONE
}
#[inline(always)]
fn combine(a: T, b: T) -> T {
a * b
}
}
impl<T: Scalar> ScanOp<T> for ScanMin {
#[inline(always)]
fn identity() -> T {
T::MAX_VALUE
}
#[inline(always)]
fn combine(a: T, b: T) -> T {
a.min_scalar(b)
}
}
impl<T: Scalar> ScanOp<T> for ScanMax {
#[inline(always)]
fn identity() -> T {
T::MIN_VALUE
}
#[inline(always)]
fn combine(a: T, b: T) -> T {
a.max_scalar(b)
}
}
pub trait ScanMode: crate::private::Sealed + Copy + 'static {
const IS_INCLUSIVE: bool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Inclusive;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Exclusive;
impl crate::private::Sealed for Inclusive {}
impl crate::private::Sealed for Exclusive {}
impl ScanMode for Inclusive {
const IS_INCLUSIVE: bool = true;
}
impl ScanMode for Exclusive {
const IS_INCLUSIVE: bool = false;
}