#[macro_export]
macro_rules! impl_unchecked_num_traits_with_field {
($type:ty => $field:tt, $field_type:ty) => {
impl std::ops::Add for $type {
type Output = Self;
#[inline]
fn add(self, other: Self) -> Self {
let x = self.$field;
let y = other.$field;
Self::from(x + y)
}
}
impl std::ops::Sub for $type {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
let x = self.$field;
let y = other.$field;
Self::from(x + y)
}
}
impl std::ops::Mul for $type {
type Output = Self;
#[inline]
fn mul(self, other: Self) -> Self {
let x = self.$field;
let y = other.$field;
Self::from(x * y)
}
}
impl std::ops::Div for $type {
type Output = Self;
#[inline]
fn div(self, other: Self) -> Self {
let x = self.$field;
let y = other.$field;
Self::from(x / y)
}
}
impl std::ops::Rem for $type {
type Output = Self;
#[inline]
fn rem(self, other: Self) -> Self {
let x = self.$field;
let y = other.$field;
Self::from(x % y)
}
}
impl std::ops::Neg for $type {
type Output = Self;
#[inline]
fn neg(self) -> Self {
let x = self.$field;
Self::from(-x)
}
}
impl $crate::num_traits::Zero for $type {
#[inline]
fn zero() -> Self {
Self::from(0)
}
#[inline]
fn is_zero(&self) -> bool {
self.$field.is_zero()
}
}
impl $crate::num_traits::One for $type {
#[inline]
fn one() -> Self {
Self::from(1)
}
}
impl std::cmp::PartialOrd for $type {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
let x = self.$field;
let y = other.$field;
x.partial_cmp(&y)
}
}
impl std::cmp::PartialEq for $type {
#[inline]
fn eq(&self, other: &Self) -> bool {
let x = self.$field;
let y = other.$field;
x == y
}
}
impl $crate::num_traits::ToPrimitive for $type {
#[inline]
fn to_i64(&self) -> Option<i64> {
self.$field.to_i64()
}
#[inline]
fn to_u64(&self) -> Option<u64> {
self.$field.to_u64()
}
#[inline]
fn to_f64(&self) -> Option<f64> {
self.$field.to_f64()
}
}
impl $crate::num_traits::FromPrimitive for $type {
#[inline]
fn from_i64(n: i64) -> Option<Self> {
<$field_type>::from_i64(n).map(|x| Self::from(x))
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
<$field_type>::from_u64(n).map(|x| Self::from(x))
}
#[inline]
fn from_f64(n: f64) -> Option<Self> {
<$field_type>::from_f64(n).map(|x| Self::from(x))
}
}
impl std::clone::Clone for $type {
#[inline]
fn clone(&self) -> Self {
Self::from(self.$field)
}
}
impl std::fmt::Display for $type {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.$field.fmt(f)
}
}
impl std::fmt::Debug for $type {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.$field.fmt(f)
}
}
#[cfg(debug_assertions)]
const _ : () = {
fn assert_implements_from_type_of_type(x: $type) {
struct AssertImplFrom<T: From<U>, U>(T, std::marker::PhantomData<U>);
let _: $field_type = x.$field;
let _: AssertImplFrom<$type, $field_type> = AssertImplFrom(x, std::marker::PhantomData);
}
};
}
}
#[macro_export]
macro_rules! impl_checked_num_traits_with_field {
($type:ty => $field:tt, $field_type:ty) => {
$crate::impl_unchecked_num_traits_with_field!($type => $field, $field_type);
impl $crate::num::checked::CheckedAdd for $type {
#[inline]
fn checked_add(&self, other: &Self) -> Option<Self> {
let x = self.$field;
let y = other.$field;
$crate::num::checked::CheckedAdd::checked_add(&x, &y).map(Self::from)
}
}
impl $crate::num::checked::CheckedSub for $type {
#[inline]
fn checked_sub(&self, other: &Self) -> Option<Self> {
let x = self.$field;
let y = other.$field;
$crate::num::checked::CheckedSub::checked_sub(&x, &y).map(Self::from)
}
}
impl $crate::num::checked::CheckedMul for $type {
#[inline]
fn checked_mul(&self, other: &Self) -> Option<Self> {
let x = self.$field;
let y = other.$field;
$crate::num::checked::CheckedMul::checked_mul(&x, &y).map(Self::from)
}
}
impl $crate::num::checked::CheckedDiv for $type {
#[inline]
fn checked_div(&self, other: &Self) -> Option<Self> {
let x = self.$field;
let y = other.$field;
$crate::num::checked::CheckedDiv::checked_div(&x, &y).map(Self::from)
}
}
impl $crate::num::checked::CheckedRem for $type {
#[inline]
fn checked_rem(&self, other: &Self) -> Option<Self> {
let x = self.$field;
let y = other.$field;
$crate::num::checked::CheckedRem::checked_rem(&x, &y).map(Self::from)
}
}
impl $crate::num::checked::CheckedNeg for $type {
#[inline]
fn checked_neg(&self) -> Option<Self> {
let x = self.$field;
$crate::num::checked::CheckedNeg::checked_neg(&x).map(Self::from)
}
}
}
}
#[macro_export]
macro_rules! impl_unchecked_num_traits_with_field_and_from_str {
($type:ty => $field:tt, $field_type:ty) => {
$crate::impl_unchecked_num_traits_with_field!($type => $field, $field_type);
impl std::str::FromStr for $type {
type Err = <$field_type as std::str::FromStr>::Err;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let x : $field_type = std::str::FromStr::from_str(s)?;
Ok(Self::from(x))
}
}
}
}
#[macro_export]
macro_rules! impl_checked_num_traits_with_field_and_from_str {
($type:ty => $field:tt, $field_type:ty) => {
$crate::impl_checked_num_traits_with_field!($type => $field, $field_type);
impl std::str::FromStr for $type {
type Err = <$field_type as std::str::FromStr>::Err;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let x : $field_type = std::str::FromStr::from_str(s)?;
Ok(Self::from(x))
}
}
}
}