use num::{Bounded, FromPrimitive, Num, Signed};
use std::any::Any;
use std::fmt::{Debug, Display};
use std::ops::{AddAssign, DivAssign, MulAssign, Neg, SubAssign};
use std::{f32, f64};
use approx::{RelativeEq, UlpsEq};
use general::{Field, Lattice, SubsetOf, SupersetOf};
#[cfg(not(feature = "std"))]
use libm::F32Ext;
#[cfg(not(feature = "std"))]
use libm::F64Ext;
#[cfg(not(feature = "std"))]
use num;
#[allow(missing_docs)]
pub trait Real:
SubsetOf<Self>
+ SupersetOf<f64>
+ Field
+ Copy
+ Num
+ FromPrimitive
+ Neg<Output = Self>
+ AddAssign
+ MulAssign
+ SubAssign
+ DivAssign
+ RelativeEq<Epsilon = Self>
+ UlpsEq<Epsilon = Self>
+ Lattice
+ PartialEq
+ Signed
+ Send
+ Sync
+ Any
+ 'static
+ Debug
+ Display
+ Bounded
{
fn floor(self) -> Self;
fn ceil(self) -> Self;
fn round(self) -> Self;
fn trunc(self) -> Self;
fn fract(self) -> Self;
fn abs(self) -> Self;
fn signum(self) -> Self;
fn is_sign_positive(self) -> bool;
fn is_sign_negative(self) -> bool;
fn mul_add(self, a: Self, b: Self) -> Self;
fn recip(self) -> Self;
fn powi(self, n: i32) -> Self;
fn powf(self, n: Self) -> Self;
fn sqrt(self) -> Self;
fn exp(self) -> Self;
fn exp2(self) -> Self;
fn ln(self) -> Self;
fn log(self, base: Self) -> Self;
fn log2(self) -> Self;
fn log10(self) -> Self;
fn max(self, other: Self) -> Self;
fn min(self, other: Self) -> Self;
fn cbrt(self) -> Self;
fn hypot(self, other: Self) -> Self;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn tan(self) -> Self;
fn asin(self) -> Self;
fn acos(self) -> Self;
fn atan(self) -> Self;
fn atan2(self, other: Self) -> Self;
fn sin_cos(self) -> (Self, Self);
fn exp_m1(self) -> Self;
fn ln_1p(self) -> Self;
fn sinh(self) -> Self;
fn cosh(self) -> Self;
fn tanh(self) -> Self;
fn asinh(self) -> Self;
fn acosh(self) -> Self;
fn atanh(self) -> Self;
fn pi() -> Self;
fn two_pi() -> Self;
fn frac_pi_2() -> Self;
fn frac_pi_3() -> Self;
fn frac_pi_4() -> Self;
fn frac_pi_6() -> Self;
fn frac_pi_8() -> Self;
fn frac_1_pi() -> Self;
fn frac_2_pi() -> Self;
fn frac_2_sqrt_pi() -> Self;
fn e() -> Self;
fn log2_e() -> Self;
fn log10_e() -> Self;
fn ln_2() -> Self;
fn ln_10() -> Self;
}
macro_rules! impl_real(
($($T:ty, $M:ident, $libm: ident);*) => ($(
impl Real for $T {
#[inline]
fn floor(self) -> Self {
$libm::floor(self)
}
#[inline]
fn ceil(self) -> Self {
$libm::ceil(self)
}
#[inline]
fn round(self) -> Self {
$libm::round(self)
}
#[inline]
fn trunc(self) -> Self {
$libm::trunc(self)
}
#[inline]
fn fract(self) -> Self {
$libm::fract(self)
}
#[inline]
fn abs(self) -> Self {
$libm::abs(self)
}
#[inline]
fn signum(self) -> Self {
Signed::signum(&self)
}
#[inline]
fn is_sign_positive(self) -> bool {
$M::is_sign_positive(self)
}
#[inline]
fn is_sign_negative(self) -> bool {
$M::is_sign_negative(self)
}
#[inline]
fn mul_add(self, a: Self, b: Self) -> Self {
$libm::mul_add(self, a, b)
}
#[inline]
fn recip(self) -> Self {
$M::recip(self)
}
#[cfg(feature = "std")]
#[inline]
fn powi(self, n: i32) -> Self {
self.powi(n)
}
#[cfg(not(feature = "std"))]
#[inline]
fn powi(self, n: i32) -> Self {
num::pow(self, n as usize)
}
#[inline]
fn powf(self, n: Self) -> Self {
$libm::powf(self, n)
}
#[inline]
fn sqrt(self) -> Self {
$libm::sqrt(self)
}
#[inline]
fn exp(self) -> Self {
$libm::exp(self)
}
#[inline]
fn exp2(self) -> Self {
$libm::exp2(self)
}
#[inline]
fn ln(self) -> Self {
$libm::ln(self)
}
#[inline]
fn log(self, base: Self) -> Self {
$libm::log(self, base)
}
#[inline]
fn log2(self) -> Self {
$libm::log2(self)
}
#[inline]
fn log10(self) -> Self {
$libm::log10(self)
}
#[inline]
fn max(self, other: Self) -> Self {
$M::max(self, other)
}
#[inline]
fn min(self, other: Self) -> Self {
$M::min(self, other)
}
#[inline]
fn cbrt(self) -> Self {
$libm::cbrt(self)
}
#[inline]
fn hypot(self, other: Self) -> Self {
$libm::hypot(self, other)
}
#[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 asin(self) -> Self {
$libm::asin(self)
}
#[inline]
fn acos(self) -> Self {
$libm::acos(self)
}
#[inline]
fn atan(self) -> Self {
$libm::atan(self)
}
#[inline]
fn atan2(self, other: Self) -> Self {
$libm::atan2(self, other)
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
$libm::sin_cos(self)
}
#[inline]
fn exp_m1(self) -> Self {
$libm::exp_m1(self)
}
#[inline]
fn ln_1p(self) -> Self {
$libm::ln_1p(self)
}
#[inline]
fn sinh(self) -> Self {
$libm::sinh(self)
}
#[inline]
fn cosh(self) -> Self {
$libm::cosh(self)
}
#[inline]
fn tanh(self) -> Self {
$libm::tanh(self)
}
#[inline]
fn asinh(self) -> Self {
$libm::asinh(self)
}
#[inline]
fn acosh(self) -> Self {
$libm::acosh(self)
}
#[inline]
fn atanh(self) -> Self {
$libm::atanh(self)
}
#[inline]
fn pi() -> Self {
$M::consts::PI
}
#[inline]
fn two_pi() -> Self {
$M::consts::PI + $M::consts::PI
}
#[inline]
fn frac_pi_2() -> Self {
$M::consts::FRAC_PI_2
}
#[inline]
fn frac_pi_3() -> Self {
$M::consts::FRAC_PI_3
}
#[inline]
fn frac_pi_4() -> Self {
$M::consts::FRAC_PI_4
}
#[inline]
fn frac_pi_6() -> Self {
$M::consts::FRAC_PI_6
}
#[inline]
fn frac_pi_8() -> Self {
$M::consts::FRAC_PI_8
}
#[inline]
fn frac_1_pi() -> Self {
$M::consts::FRAC_1_PI
}
#[inline]
fn frac_2_pi() -> Self {
$M::consts::FRAC_2_PI
}
#[inline]
fn frac_2_sqrt_pi() -> Self {
$M::consts::FRAC_2_SQRT_PI
}
#[inline]
fn e() -> Self {
$M::consts::E
}
#[inline]
fn log2_e() -> Self {
$M::consts::LOG2_E
}
#[inline]
fn log10_e() -> Self {
$M::consts::LOG10_E
}
#[inline]
fn ln_2() -> Self {
$M::consts::LN_2
}
#[inline]
fn ln_10() -> Self {
$M::consts::LN_10
}
}
)*)
);
#[cfg(not(feature = "std"))]
impl_real!(f32,f32,F32Ext; f64,f64,F64Ext);
#[cfg(feature = "std")]
impl_real!(f32,f32,f32; f64,f64,f64);