use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
mod private {
pub trait Sealed {}
impl Sealed for f32 {}
impl Sealed for f64 {}
}
pub trait Float:
private::Sealed
+ Copy
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
+ Rem<Output = Self>
+ Neg<Output = Self>
+ PartialOrd
+ Sized
{
const ZERO: Self;
const ONE: Self;
const EPSILON: Self;
const DOUBLE_EPSILON: Self;
const TAU: Self;
const PI: Self;
const FRAC_PI_2: Self;
const FRAC_PI_3: Self;
const FRAC_PI_4: Self;
const FRAC_PI_6: Self;
const FRAC_PI_8: Self;
const DEG_TO_RAD: Self;
const RAD_TO_DEG: Self;
const TURNS_TO_RAD: Self;
const RAD_TO_TURNS: Self;
const GRAD_TO_RAD: Self;
const RAD_TO_GRAD: Self;
#[must_use]
fn is_nan(self) -> bool;
}
#[cfg(any(feature = "std", feature = "libm"))]
pub trait FloatMath: private::Sealed + Sized {
#[must_use = "method returns a new number and does not mutate the original value"]
fn sin(self) -> Self;
#[must_use = "method returns a new number and does not mutate the original value"]
fn cos(self) -> Self;
#[must_use = "method returns a new number and does not mutate the original value"]
fn tan(self) -> Self;
#[must_use = "method returns a new number and does not mutate the original value"]
fn sin_cos(self) -> (Self, Self);
}
impl Float for f32 {
const ZERO: Self = 0.0f32;
const ONE: Self = 1.0f32;
const EPSILON: Self = f32::EPSILON;
const DOUBLE_EPSILON: Self = 2.0 * Self::EPSILON;
const TAU: Self = core::f32::consts::TAU;
const PI: Self = core::f32::consts::PI;
const FRAC_PI_2: Self = core::f32::consts::FRAC_PI_2;
const FRAC_PI_3: Self = core::f32::consts::FRAC_PI_3;
const FRAC_PI_4: Self = core::f32::consts::FRAC_PI_4;
const FRAC_PI_6: Self = core::f32::consts::FRAC_PI_6;
const FRAC_PI_8: Self = core::f32::consts::FRAC_PI_8;
const DEG_TO_RAD: Self = core::f32::consts::PI / 180.0;
const RAD_TO_DEG: Self = 180.0 / core::f32::consts::PI;
const TURNS_TO_RAD: Self = core::f32::consts::TAU;
const RAD_TO_TURNS: Self = 1.0 / core::f32::consts::TAU;
const GRAD_TO_RAD: Self = core::f32::consts::PI / 200.0;
const RAD_TO_GRAD: Self = 200.0 / core::f32::consts::PI;
#[inline]
fn is_nan(self) -> bool {
self.is_nan()
}
}
#[cfg(feature = "std")]
impl FloatMath for f32 {
#[inline]
fn sin(self) -> Self {
self.sin()
}
#[inline]
fn cos(self) -> Self {
self.cos()
}
#[inline]
fn tan(self) -> Self {
self.tan()
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
self.sin_cos()
}
}
#[cfg(all(not(feature = "std"), feature = "libm"))]
impl FloatMath for f32 {
#[inline]
fn sin(self) -> Self {
libm::sinf(self)
}
#[inline]
fn cos(self) -> Self {
libm::cosf(self)
}
#[inline]
fn tan(self) -> Self {
libm::tanf(self)
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
(libm::sinf(self), libm::cosf(self))
}
}
impl Float for f64 {
const ZERO: Self = 0.0f64;
const ONE: Self = 1.0f64;
const EPSILON: Self = f64::EPSILON;
const DOUBLE_EPSILON: Self = 2.0 * Self::EPSILON;
const TAU: Self = core::f64::consts::TAU;
const PI: Self = core::f64::consts::PI;
const FRAC_PI_2: Self = core::f64::consts::FRAC_PI_2;
const FRAC_PI_3: Self = core::f64::consts::FRAC_PI_3;
const FRAC_PI_4: Self = core::f64::consts::FRAC_PI_4;
const FRAC_PI_6: Self = core::f64::consts::FRAC_PI_6;
const FRAC_PI_8: Self = core::f64::consts::FRAC_PI_8;
const DEG_TO_RAD: Self = core::f64::consts::PI / 180.0;
const RAD_TO_DEG: Self = 180.0 / core::f64::consts::PI;
const TURNS_TO_RAD: Self = core::f64::consts::TAU;
const RAD_TO_TURNS: Self = 1.0 / core::f64::consts::TAU;
const GRAD_TO_RAD: Self = core::f64::consts::PI / 200.0;
const RAD_TO_GRAD: Self = 200.0 / core::f64::consts::PI;
#[inline]
fn is_nan(self) -> bool {
self.is_nan()
}
}
#[cfg(feature = "std")]
impl FloatMath for f64 {
#[inline]
fn sin(self) -> Self {
self.sin()
}
#[inline]
fn cos(self) -> Self {
self.cos()
}
#[inline]
fn tan(self) -> Self {
self.tan()
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
self.sin_cos()
}
}
#[cfg(all(not(feature = "std"), feature = "libm"))]
impl FloatMath for f64 {
#[inline]
fn sin(self) -> Self {
libm::sin(self)
}
#[inline]
fn cos(self) -> Self {
libm::cos(self)
}
#[inline]
fn tan(self) -> Self {
libm::tan(self)
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
(libm::sin(self), libm::cos(self))
}
}