use std::fmt::{ Display };
pub trait One {
fn get_one(&self) -> Self;
fn eq_one(&self) -> bool;
fn similar_one(&self, precision: f64) -> bool;
}
pub trait Zero {
fn get_zero(&self) -> Self;
fn eq_zero(&self) -> bool;
fn similar_zero(&self, precision: f64) -> bool;
}
pub trait Latex: Display {
fn latex(&self) -> String;
}
pub trait Similar<RHS = Self> {
fn similar(&self, other: &RHS, precision: f64) -> bool;
}
pub trait Abs {
type Output;
fn abs(&self) -> Self::Output;
}
pub trait Neg {
type Output;
fn neg(&self) -> Self::Output;
}
pub trait Rec {
type Output;
fn rec(&self) -> Self::Output;
}
pub trait Con {
type Output;
fn con(&self) -> Self::Output;
}
pub trait Pow {
type Output;
fn pow(&self, power:u32) -> Self::Output;
}
pub trait Powf {
type Output;
fn powf(&self, power:f64) -> Self::Output;
}
pub trait Powc {
type Output;
fn powc(&self, power_rel:f64, power_img:f64) -> Self::Output;
}
pub trait DivLeft<Rhs = Self> {
type Output;
fn div_left(&self, other: &Rhs) -> Self::Output;
}
#[macro_export]
macro_rules! one_for {
($($ty:ty)*) => {$(
impl One for $ty {
fn get_one(&self) -> Self {
1 as $ty
}
fn eq_one(&self) -> bool {
*self == 1 as $ty
}
fn similar_one(&self, precision: f64) -> bool {
((*self - 1 as $ty) as f64).abs() < precision.abs()
}
}
)*}
}
one_for!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);
#[macro_export]
macro_rules! zero_for {
($($ty:ty)*) => {$(
impl Zero for $ty {
fn get_zero(&self) -> Self {
0 as $ty
}
fn eq_zero(&self) -> bool {
*self == 0 as $ty
}
fn similar_zero(&self, precision: f64) -> bool {
(*self as f64).abs() < precision.abs()
}
}
)*}
}
zero_for!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);
#[macro_export]
macro_rules! latex_for {
($($ty:ty)*) => {$(
impl Latex for $ty {
fn latex(&self) -> String {
format!("{}", self)
}
}
)*}
}
latex_for!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 char bool str);
#[macro_export]
macro_rules! similar_for {
($($ty:ty)*) => {$(
impl Similar for $ty {
fn similar(&self, other: &Self, precision: f64) -> bool {
((self - other) as f64).abs() < precision.abs()
}
}
)*}
}
similar_for!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);
#[macro_export]
macro_rules! abs_for_u {
($($ty:ty)*) => {$(
impl Abs for $ty {
type Output = Self;
fn abs(&self) -> Self::Output {
*self
}
}
)*}
}
abs_for_u!(u8 u16 u32 u64 u128 usize);
#[macro_export]
macro_rules! abs_for {
($($ty:ty)*) => {$(
impl Abs for $ty {
type Output = Self;
fn abs(&self) -> Self::Output {
<$ty>::abs(*self)
}
}
)*}
}
abs_for!(i8 i16 i32 i64 i128 isize f32 f64);
#[macro_export]
macro_rules! neg_for {
($($ty:ty)*) => {$(
impl Neg for $ty {
type Output = Self;
fn neg(&self) -> Self::Output {
-*self
}
}
)*}
}
neg_for!(i8 i16 i32 i64 i128 isize f32 f64);
#[macro_export]
macro_rules! rec_for {
($($ty:ty)*) => {$(
impl Rec for $ty {
type Output = Self;
fn rec(&self) -> Self::Output {
1 as $ty / *self
}
}
)*}
}
rec_for!(f32 f64);
#[macro_export]
macro_rules! con_for {
($($ty:ty)*) => {$(
impl Con for $ty {
type Output = Self;
fn con(&self) -> Self::Output {
*self
}
}
)*}
}
con_for!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);