use crate::{
numeric::{Abs, BoundedMax, BoundedMin, Infinite, IsFinite, IsInfinite, IsNan, MinMax, Nan},
tuple::Tuple,
};
crate::impl_numeric_casts_wrapper!(
[T, const N: usize],
wrapper: Tuple,
Tuple<T, N> => Tuple<U, N>,
item: T,
field: inner
);
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + BoundedMin,
{
pub const MIN: Self = Self { inner: [T::MIN; N] };
}
impl<T, const N: usize> BoundedMin for Tuple<T, N>
where
T: Copy + BoundedMin,
{
const MIN: Self = Tuple::MIN;
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + BoundedMax,
{
pub const MAX: Self = Self { inner: [T::MAX; N] };
}
impl<T, const N: usize> BoundedMax for Tuple<T, N>
where
T: Copy + BoundedMax,
{
const MAX: Self = Tuple::MAX;
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + MinMax,
{
#[inline]
pub fn min(self, rhs: Self) -> Self {
Tuple::from_array(core::array::from_fn(|i| self.inner[i].minimum(rhs.inner[i])))
}
#[inline]
pub fn max(self, rhs: Self) -> Self {
Tuple::from_array(core::array::from_fn(|i| self.inner[i].maximum(rhs.inner[i])))
}
}
impl<T, const N: usize> MinMax for Tuple<T, N>
where
T: Copy + MinMax,
{
#[inline]
fn minimum(self, rhs: Self) -> Self {
Tuple::min(self, rhs)
}
#[inline]
fn maximum(self, rhs: Self) -> Self {
Tuple::max(self, rhs)
}
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + Abs,
{
#[inline]
pub fn abs(self) -> Self {
self.map(|x| x.abs())
}
}
impl<T, const N: usize> Abs for Tuple<T, N>
where
T: Copy + Abs,
{
#[inline]
fn abs(self) -> Self {
Tuple::abs(self)
}
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + IsFinite,
{
#[inline]
pub fn is_finite(self) -> bool {
self.inner.iter().all(|&x| x.is_finite())
}
}
impl<T, const N: usize> IsFinite for Tuple<T, N>
where
T: Copy + IsFinite,
{
#[inline]
fn is_finite(self) -> bool {
Tuple::is_finite(self)
}
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + Infinite,
{
pub const INFINITY: Self = Self { inner: [T::INFINITY; N] };
pub const NEG_INFINITY: Self = Self { inner: [T::NEG_INFINITY; N] };
}
impl<T, const N: usize> Infinite for Tuple<T, N>
where
T: Copy + Infinite,
{
const INFINITY: Self = Tuple::INFINITY;
const NEG_INFINITY: Self = Tuple::NEG_INFINITY;
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + IsInfinite,
{
#[inline]
pub fn is_infinite(self) -> bool {
self.inner.iter().any(|&x| x.is_infinite())
}
}
impl<T, const N: usize> IsInfinite for Tuple<T, N>
where
T: Copy + IsInfinite,
{
#[inline]
fn is_infinite(self) -> bool {
Tuple::is_infinite(self)
}
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + Nan,
{
pub const NAN: Self = Self { inner: [T::NAN; N] };
}
impl<T, const N: usize> Nan for Tuple<T, N>
where
T: Copy + Nan,
{
const NAN: Self = Tuple::NAN;
}
impl<T, const N: usize> Tuple<T, N>
where
T: Copy + IsNan,
{
#[inline]
pub fn is_nan(self) -> bool {
self.inner.iter().any(|&x| x.is_nan())
}
}
impl<T, const N: usize> IsNan for Tuple<T, N>
where
T: Copy + IsNan,
{
#[inline]
fn is_nan(self) -> bool {
Tuple::is_nan(self)
}
}