use super::*;
use core::{
num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8},
ops::{Add, Rem, Sub}, };
macro_rules! impl_integer_ops {
($($t:ident, $inner:ident),+) => {
$(
impl_integer_ops![ops: $t, $inner];
)+
};
(ops: $t:ident, $inner:ident) => {
impl_integer_ops![bin_ops: $t, $inner, Add, add, Sub, sub, Rem, rem];
};
(bin_ops: $t:ident, $inner:ident, $($op:ident, $fn:ident),+) => {
$(
impl_integer_ops![bin_op: $t, $inner, $op, $fn];
)+
};
(bin_op: $t:ident, $inner:ident, $op:ident, $fn:ident) => {
impl $op for $t {
type Output = $t;
fn $fn(self, rhs: Self::Output) -> Self::Output {
$t($inner::new(self.0.get().$fn(rhs.0.get())).expect("Invalid value 0."))
}
}
};
(un_op: $t:ident, $inner:ident, $op:ident, $fn:ident) => {
impl $op for $t {
type Output = $t;
fn $fn(self) -> Self::Output {
$t($inner::new(self.0.get().$fn()).expect("Invalid value 0."))
}
}
};
}
impl_integer_ops![
NegativeInteger8,
NonZeroU8,
NegativeInteger16,
NonZeroU16,
NegativeInteger32,
NonZeroU32,
NegativeInteger64,
NonZeroU64,
NegativeInteger128,
NonZeroU128
];
#[cfg(test)]
mod tests {
use crate::all::*;
#[test]
fn nz_ops() -> NumeraResult<()> {
let _n5 = Nz8::new_neg(5)?;
let _n7 = Nz8::new_neg(7)?;
assert_eq![_n7 + _n5, Nz8::new_neg(12)?];
assert_eq![_n7 - _n5, Nz8::new_neg(2)?];
#[cfg(feature = "std")]
{
use std::panic::catch_unwind;
assert![catch_unwind(|| _n5 - _n7).is_err()];
assert![catch_unwind(|| _n7 - _n7).is_err()];
}
Ok(())
}
#[test]
#[should_panic]
fn nz_ops_panic_underflow() {
let _min = Nz8::MIN;
let _res = _min + Nz8::new_neg(8).expect("new_neg(8)");
assert_eq![_res, Nz8::new_neg(2).unwrap()];
}
#[test]
#[should_panic]
fn nz_ops_panic_overflow() {
let _max = Nz8::MAX;
let _ = _max - Nz8::new_neg(9).expect("new_neg(9)");
}
}