1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::{ error::Error, fmt::Debug };
pub trait TypeNum: Debug + Default {
const VALUE: usize;
fn value() -> usize {
Self::VALUE
}
}
#[macro_export]
macro_rules! type_num {
($value:expr => $name:ident) => (
#[derive(Debug, Default)]
pub struct $name;
impl $crate::type_math::TypeNum for $name {
const VALUE: usize = $value;
}
);
($($value:expr => $name:ident),+) => ( $(type_num!($value => $name);)+ )
}
type_num! {
0 => _0,
1 => _1, 2 => _2, 4 => _4, 8 => _8,
12 => _12, 16 => _16, 24 => _24, 32 => _32,
48 => _48, 64 => _64, 96 => _96, 128 => _128,
256 => _256, 384 => _384, 512 => _512, 1024 => _1024,
2048 => _2048, 4096 => _4096, 8192 => _8192, 16384 => _16384,
32768 => _32768, 65536 => _65536
}
pub trait Operator: Debug + Default {
fn r#do(a: usize, b: usize) -> Result<usize, Box<Error + 'static>>;
}
#[derive(Debug, Default)]
pub struct Add;
impl Operator for Add {
fn r#do(a: usize, b: usize) -> Result<usize, Box<Error + 'static>> {
Ok(a.checked_add(b).ok_or("Integer overflow")?)
}
}
#[derive(Debug, Default)]
pub struct Sub;
impl Operator for Sub {
fn r#do(a: usize, b: usize) -> Result<usize, Box<Error + 'static>> {
Ok(a.checked_sub(b).ok_or("Integer underflow")?)
}
}
#[derive(Debug, Default)]
pub struct Mul;
impl Operator for Mul {
fn r#do(a: usize, b: usize) -> Result<usize, Box<Error + 'static>> {
Ok(a.checked_mul(b).ok_or("Integer overflow")?)
}
}
#[derive(Debug, Default)]
pub struct Div;
impl Operator for Div {
fn r#do(a: usize, b: usize) -> Result<usize, Box<Error + 'static>> {
Ok(a.checked_div(b).ok_or("Division by zero")?)
}
}