use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::ops::Neg;
use std::iter::Sum;
use std::cmp::PartialOrd;
use std::marker::Sized;
use std::num::Wrapping;
pub trait NumericByValue<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Neg<Output = Output>
+ Sized {}
impl <T, Rhs, Output> NumericByValue<Rhs, Output> for T where
T: Div<Rhs, Output = Output>
+ Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Neg<Output = Output>
+ Sized {}
pub trait NumericRef<T>:
NumericByValue<T, T>
+ for<'a> NumericByValue<&'a T, T> {}
impl <RefT, T> NumericRef<T> for RefT where
RefT: NumericByValue<T, T>
+ for<'a> NumericByValue<&'a T, T> {}
pub trait Numeric:
NumericByValue
+ for<'a> NumericByValue<&'a Self>
+ Clone
+ ZeroOne
+ FromUsize
+ Sum
+ PartialOrd {}
impl <T> Numeric for T where T:
NumericByValue
+ for<'a> NumericByValue<&'a T>
+ Clone
+ ZeroOne
+ FromUsize
+ Sum
+ PartialOrd {}
pub trait ZeroOne: Sized {
fn zero() -> Self;
fn one() -> Self;
}
impl <T: ZeroOne> ZeroOne for Wrapping<T> {
#[inline]
fn zero() -> Wrapping<T> {
Wrapping(T::zero())
}
#[inline]
fn one() -> Wrapping<T> {
Wrapping(T::one())
}
}
macro_rules! zero_one_integral {
($T:ty) => {
impl ZeroOne for $T {
#[inline]
fn zero() -> $T { 0 }
#[inline]
fn one() -> $T { 1 }
}
};
}
macro_rules! zero_one_float {
($T:ty) => {
impl ZeroOne for $T {
#[inline]
fn zero() -> $T { 0.0 }
#[inline]
fn one() -> $T { 1.0 }
}
};
}
zero_one_integral!(u8);
zero_one_integral!(i8);
zero_one_integral!(u16);
zero_one_integral!(i16);
zero_one_integral!(u32);
zero_one_integral!(i32);
zero_one_integral!(u64);
zero_one_integral!(i64);
zero_one_integral!(u128);
zero_one_integral!(i128);
zero_one_float!(f32);
zero_one_float!(f64);
zero_one_integral!(usize);
zero_one_integral!(isize);
pub trait FromUsize: Sized {
fn from_usize(n: usize) -> Option<Self>;
}
impl <T: FromUsize> FromUsize for Wrapping<T> {
fn from_usize(n: usize) -> Option<Wrapping<T>> {
Some(Wrapping(T::from_usize(n)?))
}
}
macro_rules! from_usize_integral {
($T:ty) => {
impl FromUsize for $T {
#[inline]
fn from_usize(n: usize) -> Option<$T> {
if n <= (<$T>::max_value() as usize) {
Some(n as $T)
} else {
None
}
}
}
}
}
macro_rules! from_usize_float {
($T:ty) => {
impl FromUsize for $T {
#[inline]
fn from_usize(n: usize) -> Option<$T> {
Some(n as $T)
}
}
}
}
from_usize_integral!(u8);
from_usize_integral!(i8);
from_usize_integral!(u16);
from_usize_integral!(i16);
from_usize_integral!(u32);
from_usize_integral!(i32);
from_usize_integral!(u64);
from_usize_integral!(i64);
from_usize_integral!(u128);
from_usize_integral!(i128);
from_usize_float!(f32);
from_usize_float!(f64);
from_usize_integral!(usize);
from_usize_integral!(isize);
pub mod extra {
pub trait Sqrt {
type Output;
fn sqrt(self) -> Self::Output;
}
macro_rules! sqrt_float {
($T:ty) => {
impl Sqrt for $T {
type Output = $T;
#[inline]
fn sqrt(self) -> Self::Output {
self.sqrt()
}
}
impl Sqrt for &$T {
type Output = $T;
#[inline]
fn sqrt(self) -> Self::Output {
self.clone().sqrt()
}
}
};
}
sqrt_float!(f32);
sqrt_float!(f64);
pub trait Exp {
type Output;
fn exp(self) -> Self::Output;
}
macro_rules! exp_float {
($T:ty) => {
impl Exp for $T {
type Output = $T;
#[inline]
fn exp(self) -> Self::Output {
self.exp()
}
}
impl Exp for &$T {
type Output = $T;
#[inline]
fn exp(self) -> Self::Output {
self.clone().exp()
}
}
};
}
exp_float!(f32);
exp_float!(f64);
pub trait Pow<Rhs = Self> {
type Output;
fn pow(self, rhs: Rhs) -> Self::Output;
}
macro_rules! pow_float {
($T:ty) => {
impl Pow<$T> for $T {
type Output = $T;
#[inline]
fn pow(self, rhs: Self) -> Self::Output {
self.powf(rhs)
}
}
impl <'a> Pow<&'a $T> for $T {
type Output = $T;
#[inline]
fn pow(self, rhs: &Self) -> Self::Output {
self.powf(rhs.clone())
}
}
impl <'a> Pow<$T> for &'a $T {
type Output = $T;
#[inline]
fn pow(self, rhs: $T) -> Self::Output {
self.powf(rhs)
}
}
impl <'a, 'b> Pow<&'b $T> for &'a $T {
type Output = $T;
#[inline]
fn pow(self, rhs: &$T) -> Self::Output {
self.powf(rhs.clone())
}
}
};
}
pow_float!(f32);
pow_float!(f64);
pub trait Pi {
fn pi() -> Self;
}
impl Pi for f32 {
fn pi() -> f32 {
std::f32::consts::PI
}
}
impl Pi for f64 {
fn pi() -> f64 {
std::f64::consts::PI
}
}
pub trait Ln {
type Output;
fn ln(self) -> Self::Output;
}
macro_rules! ln_float {
($T:ty) => {
impl Ln for $T {
type Output = $T;
#[inline]
fn ln(self) -> Self::Output {
self.ln()
}
}
impl Ln for &$T {
type Output = $T;
#[inline]
fn ln(self) -> Self::Output {
self.clone().ln()
}
}
};
}
ln_float!(f32);
ln_float!(f64);
pub trait Sin {
type Output;
fn sin(self) -> Self::Output;
}
macro_rules! sin_float {
($T:ty) => {
impl Sin for $T {
type Output = $T;
#[inline]
fn sin(self) -> Self::Output {
self.sin()
}
}
impl Sin for &$T {
type Output = $T;
#[inline]
fn sin(self) -> Self::Output {
self.clone().sin()
}
}
};
}
sin_float!(f32);
sin_float!(f64);
pub trait Cos {
type Output;
fn cos(self) -> Self::Output;
}
macro_rules! cos_float {
($T:ty) => {
impl Cos for $T {
type Output = $T;
#[inline]
fn cos(self) -> Self::Output {
self.cos()
}
}
impl Cos for &$T {
type Output = $T;
#[inline]
fn cos(self) -> Self::Output {
self.clone().cos()
}
}
};
}
cos_float!(f32);
cos_float!(f64);
pub trait RealByValue<Rhs = Self, Output = Self>:
Sqrt<Output = Output>
+ Exp<Output = Output>
+ Pow<Rhs, Output = Output>
+ Ln<Output = Output>
+ Sin<Output = Output>
+ Cos<Output = Output>
+ Sized {}
impl <T, Rhs, Output> RealByValue<Rhs, Output> for T where
T: Sqrt<Output = Output>
+ Exp<Output = Output>
+ Pow<Rhs, Output = Output>
+ Ln<Output = Output>
+ Sin<Output = Output>
+ Cos<Output = Output>
+ Sized {}
pub trait RealRef<T>:
RealByValue<T, T>
+ for<'a> RealByValue<&'a T, T> {}
impl <RefT, T> RealRef<T> for RefT where
RefT: RealByValue<T, T>
+ for<'a> RealByValue<&'a T, T> {}
pub trait Real:
RealByValue
+ for<'a> RealByValue<&'a Self>
+ Pi {}
impl <T> Real for T where T:
RealByValue
+ for<'a> RealByValue<&'a T>
+ Pi {}
}