use core::{
fmt::Debug,
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use core_maths::CoreFloat;
use super::macros::with_all_scalar_types;
macro_rules! define_from_all_scalars_trait {
($($ty:ty),+ $(,)?) => {
pub trait FromAllScalars: $(FromScalar<$ty> +)+ {}
impl<T> FromAllScalars for T where T: $(FromScalar<$ty> +)+ {}
};
}
with_all_scalar_types!(define_from_all_scalars_trait);
pub trait Scalar:
Copy
+ Debug
+ PartialEq
+ PartialOrd
+ MinMax
+ FromAllScalars
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
{
const ZERO: Self;
const ONE: Self;
#[inline]
fn from_scalar<T: Scalar>(value: T) -> Self
where
Self: FromScalar<T>,
{
<Self as FromScalar<T>>::from_scalar_impl(value)
}
#[inline]
fn as_scalar<T: Scalar>(&self) -> T
where
Self: FromScalar<T>,
{
<Self as FromScalar<T>>::as_scalar_impl(self)
}
}
pub trait FloatScalar:
Scalar
+ CoreFloat
+ Neg
+ AbsDiffEq<Epsilon = Self>
+ RelativeEq<Epsilon = Self>
+ UlpsEq<Epsilon = Self>
{
const INFINITY: Self;
const NEG_INFINITY: Self;
const NAN: Self;
fn is_nan(self) -> bool;
fn is_finite(self) -> bool;
fn is_infinite(self) -> bool;
fn is_zero(self) -> bool;
}
pub trait IntScalar: Scalar {}
pub trait MinMax {
fn min(self, other: Self) -> Self;
fn max(self, other: Self) -> Self;
}
pub trait FromScalar<T>: Sized {
fn from_scalar_impl(value: T) -> Self;
fn as_scalar_impl(&self) -> T;
}