gemath 0.1.0

Type-safe game math with type-level units/spaces, typed angles, and explicit fallible ops (plus optional geometry/collision).
Documentation
//! Numeric traits for extensibility.
//!
//! `gemath`’s core types are currently `f32`-based, but the transformation plan calls for
//! “plug-and-play” numeric extensibility (e.g. fixed-point or custom float types).
//!
//! This module provides a **small, explicit trait surface** that future generic code can target.
//! It is intentionally conservative: it covers the operations that appear across core algorithms.
//!
//! ## Example (generic lerp on `GemathFloat`)
//!
//! ```rust
//! use gemath::GemathFloat;
//!
//! #[inline]
//! fn lerp<T: GemathFloat>(a: T, b: T, t: T) -> T {
//!     a + (b - a) * t
//! }
//!
//! let x: f32 = lerp(10.0f32, 20.0f32, 0.25f32);
//! assert!((x - 12.5).abs() < 1e-6);
//! ```

use core::ops::{Add, Div, Mul, Neg, Sub};

/// A minimal “math scalar” trait for algorithms that need floating-point style operations.
///
/// This is **not** yet used to parameterize the crate’s core `Vec*`/`Mat*` types; it exists so
/// we can gradually introduce generic algorithms without committing to a full generic rewrite.
pub trait GemathFloat:
    Copy
    + PartialEq
    + PartialOrd
    + Add<Output = Self>
    + Sub<Output = Self>
    + Mul<Output = Self>
    + Div<Output = Self>
    + Neg<Output = Self>
{
    const ZERO: Self;
    const ONE: Self;

    fn is_finite(self) -> bool;
    fn is_nan(self) -> bool;
    fn abs(self) -> Self;

    fn sqrt(self) -> Self;
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn sin_cos(self) -> (Self, Self);
    fn tan(self) -> Self;
    fn acos(self) -> Self;
    fn asin(self) -> Self;
    fn atan2(self, x: Self) -> Self;
    fn exp(self) -> Self;
    fn floor(self) -> Self;
    fn ceil(self) -> Self;
    fn copysign(self, sign: Self) -> Self;

    #[inline]
    fn clamp(self, min: Self, max: Self) -> Self {
        if self < min {
            min
        } else if self > max {
            max
        } else {
            self
        }
    }
}

impl GemathFloat for f32 {
    const ZERO: Self = 0.0;
    const ONE: Self = 1.0;

    #[inline]
    fn is_finite(self) -> bool {
        self.is_finite()
    }

    #[inline]
    fn is_nan(self) -> bool {
        self.is_nan()
    }

    #[inline]
    fn abs(self) -> Self {
        self.abs()
    }

    #[inline]
    fn sqrt(self) -> Self {
        crate::math::sqrt(self)
    }

    #[inline]
    fn sin(self) -> Self {
        crate::math::sin(self)
    }

    #[inline]
    fn cos(self) -> Self {
        crate::math::cos(self)
    }

    #[inline]
    fn sin_cos(self) -> (Self, Self) {
        crate::math::sin_cos(self)
    }

    #[inline]
    fn tan(self) -> Self {
        crate::math::tan(self)
    }

    #[inline]
    fn acos(self) -> Self {
        crate::math::acos(self)
    }

    #[inline]
    fn asin(self) -> Self {
        crate::math::asin(self)
    }

    #[inline]
    fn atan2(self, x: Self) -> Self {
        crate::math::atan2(self, x)
    }

    #[inline]
    fn exp(self) -> Self {
        crate::math::exp(self)
    }

    #[inline]
    fn floor(self) -> Self {
        crate::math::floor(self)
    }

    #[inline]
    fn ceil(self) -> Self {
        crate::math::ceil(self)
    }

    #[inline]
    fn copysign(self, sign: Self) -> Self {
        crate::math::copysign(self, sign)
    }
}