use core::{
fmt::Debug,
iter::Sum,
ops::{Add, Sub},
};
use crate::{OneTwo, ZeroOneTwo};
pub(crate) mod forwarding;
pub(crate) use forwarding::impl_co_forwarding;
mod sealed;
pub trait IntPrimitive: sealed::Int + Copy + Ord + Eq + Debug {}
impl<T> IntPrimitive for T where T: sealed::Int + Copy + Ord + Eq + Debug {}
pub trait UnsignedPrimitive:
sealed::Unsigned
+ Copy
+ Ord
+ Eq
+ Debug
+ Default
+ Add<Output = Self>
+ Sub<Output = Self>
+ Sum<Self>
{
}
impl<T> UnsignedPrimitive for T where
T: sealed::Unsigned
+ Copy
+ Ord
+ Eq
+ Debug
+ Default
+ Add<Output = Self>
+ Sub<Output = Self>
+ Sum<Self>
{
}
pub trait COPrimitive {
type CoordType: IntPrimitive;
type MeasureType: UnsignedPrimitive;
}
pub trait COConstruct: COPrimitive + Sized {
fn try_new(start: Self::CoordType, end_excl: Self::CoordType) -> Option<Self>;
unsafe fn new_unchecked(start: Self::CoordType, end_excl: Self::CoordType) -> Self;
}
pub trait COMidpointConstruct: COConstruct {
fn checked_from_midpoint_len(mid: Self::CoordType, len: Self::MeasureType) -> Option<Self>;
fn saturating_from_midpoint_len(mid: Self::CoordType, len: Self::MeasureType) -> Option<Self>;
}
pub trait COBounds: COPrimitive + Copy + Ord + Eq + core::fmt::Debug {
fn start(self) -> Self::CoordType;
fn end_excl(self) -> Self::CoordType;
fn end_incl(self) -> Self::CoordType;
}
pub trait COPredicates: COBounds {
fn contains(self, x: Self::CoordType) -> bool;
fn contains_interval(self, other: Self) -> bool;
fn intersects(self, other: Self) -> bool;
fn is_adjacent(self, other: Self) -> bool;
fn is_contiguous_with(self, other: Self) -> bool;
}
pub trait CORange: COBounds + Sized {
fn to_range(self) -> core::ops::Range<Self::CoordType>;
#[inline]
fn iter(self) -> core::ops::Range<Self::CoordType> {
self.to_range()
}
}
pub trait COAlgebra: COConstruct + COBounds + COPredicates {
fn intersection(self, other: Self) -> Option<Self>;
fn convex_hull(self, other: Self) -> Self;
fn between(self, other: Self) -> Option<Self>;
fn union(self, other: Self) -> OneTwo<Self>;
fn difference(self, other: Self) -> ZeroOneTwo<Self>;
fn symmetric_difference(self, other: Self) -> ZeroOneTwo<Self>;
}
pub trait COMeasure: COPrimitive {
fn len(self) -> Self::MeasureType;
}
pub trait COMidpoint: COPrimitive {
fn midpoint(self) -> Self::CoordType;
}
pub trait COCheckedMinkowskiLinear: COPrimitive + Sized {
fn checked_minkowski_add(self, other: Self) -> Option<Self>;
fn checked_minkowski_sub(self, other: Self) -> Option<Self>;
fn checked_minkowski_add_scalar(self, scalar: Self::CoordType) -> Option<Self>;
fn checked_minkowski_sub_scalar(self, scalar: Self::CoordType) -> Option<Self>;
}
pub trait COCheckedMinkowskiHull: COPrimitive + Sized {
fn checked_minkowski_mul_hull(self, other: Self) -> Option<Self>;
fn checked_minkowski_div_hull(self, other: Self) -> Option<Self>;
fn checked_minkowski_mul_scalar_hull(self, scalar: Self::CoordType) -> Option<Self>;
fn checked_minkowski_div_scalar_hull(self, scalar: Self::CoordType) -> Option<Self>;
}
pub trait COSaturatingMinkowskiLinear: COPrimitive + Sized {
fn saturating_minkowski_add(self, other: Self) -> Option<Self>;
fn saturating_minkowski_sub(self, other: Self) -> Option<Self>;
fn saturating_minkowski_add_scalar(self, scalar: Self::CoordType) -> Option<Self>;
fn saturating_minkowski_sub_scalar(self, scalar: Self::CoordType) -> Option<Self>;
}
pub trait COSaturatingMinkowskiHull: COPrimitive + Sized {
fn saturating_minkowski_mul_hull(self, other: Self) -> Option<Self>;
fn saturating_minkowski_div_hull(self, other: Self) -> Option<Self>;
fn saturating_minkowski_mul_scalar_hull(self, scalar: Self::CoordType) -> Option<Self>;
fn saturating_minkowski_div_scalar_hull(self, scalar: Self::CoordType) -> Option<Self>;
}
pub trait IntCO: COConstruct + COBounds + COPredicates + COAlgebra + COMeasure {}
impl<T> IntCO for T where T: COConstruct + COBounds + COPredicates + COAlgebra + COMeasure {}