scsys_core/state/impls/
impl_wrapper_ops.rs

1/*
2    Appellation: impl_ops <module>
3    Contrib: @FL03
4*/
5use crate::state::{RawState, State};
6use num_traits::{Num, One, Zero};
7
8impl<Q> One for State<Q>
9where
10    Q: RawState + One,
11{
12    fn one() -> Self {
13        State(Q::one())
14    }
15}
16
17impl<Q> Zero for State<Q>
18where
19    Q: RawState + Zero,
20{
21    fn zero() -> Self {
22        State(Q::zero())
23    }
24
25    fn is_zero(&self) -> bool {
26        self.get().is_zero()
27    }
28}
29
30impl<Q> Num for State<Q>
31where
32    Q: RawState + Num,
33{
34    type FromStrRadixErr = Q::FromStrRadixErr;
35
36    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
37        Q::from_str_radix(s, radix).map(State)
38    }
39}
40
41macro_rules! impl_binary_op {
42    ($s:ident::<[$($op:ident.$call:ident),* $(,)?]>) => {
43        $(
44            impl_binary_op!(@impl $s::$op.$call);
45            impl_binary_op!(@mut $s::$op.$call);
46        )*
47    };
48    (@impl $s:ident::$op:ident.$call:ident) => {
49        impl<A, B, C> ::core::ops::$op<$s<B>> for $s<A>
50        where
51            A: ::core::ops::$op<B, Output = C>,
52        {
53            type Output = $s<C>;
54
55            fn $call(self, rhs: $s<B>) -> Self::Output {
56                $s(::core::ops::$op::$call(self.0, rhs.0))
57            }
58        }
59
60        impl<'a, A, B, C> ::core::ops::$op<$s<B>> for &'a $s<A>
61        where
62            &'a A: ::core::ops::$op<B, Output = C>,
63        {
64            type Output = $s<C>;
65
66            fn $call(self, rhs: $s<B>) -> Self::Output {
67                $s(::core::ops::$op::$call(&self.0, rhs.0))
68            }
69        }
70
71        impl<'a, A, B, C> ::core::ops::$op<&'a $s<B>> for &'a $s<A>
72        where
73            &'a A: ::core::ops::$op<&'a B, Output = C>,
74        {
75            type Output = $s<C>;
76
77            fn $call(self, rhs: &'a $s<B>) -> Self::Output {
78                $s(::core::ops::$op::$call(&self.0, &rhs.0))
79            }
80        }
81
82        impl<'a, A, B, C> ::core::ops::$op<&'a $s<B>> for $s<A>
83        where
84            A: ::core::ops::$op<&'a B, Output = C>,
85        {
86            type Output = $s<C>;
87
88            fn $call(self, rhs: &'a $s<B>) -> Self::Output {
89                $s(::core::ops::$op::$call(self.0, &rhs.0))
90            }
91        }
92
93        impl<'a, A, B, C> ::core::ops::$op<$s<B>> for &'a mut $s<A>
94        where
95            &'a A: ::core::ops::$op<B, Output = C>,
96        {
97            type Output = $s<C>;
98
99            fn $call(self, rhs: $s<B>) -> Self::Output {
100                $s(::core::ops::$op::$call(&self.0, rhs.0))
101            }
102        }
103
104        impl<'a, A, B, C> ::core::ops::$op<&'a mut $s<B>> for $s<A>
105        where
106            A: ::core::ops::$op<&'a B, Output = C>,
107        {
108            type Output = $s<C>;
109
110            fn $call(self, rhs: &'a mut $s<B>) -> Self::Output {
111                $s(::core::ops::$op::$call(self.0, &rhs.0))
112            }
113        }
114
115        impl<'a, A, B, C> ::core::ops::$op<&'a mut $s<B>> for &'a mut $s<A>
116        where
117            &'a A: ::core::ops::$op<&'a B, Output = C>,
118        {
119            type Output = $s<C>;
120
121            fn $call(self, rhs: &'a mut $s<B>) -> Self::Output {
122                $s(::core::ops::$op::$call(&self.0, &rhs.0))
123            }
124        }
125    };
126    (@mut $s:ident::$op:ident.$call:ident) => {
127        paste::paste! {
128            impl_binary_op_mut!(@impl $s::[<$op Assign>].[<$call _assign>]);
129        }
130    };
131}
132
133macro_rules! impl_binary_op_mut {
134    ($s:ident::<[$($op:ident.$call:ident),* $(,)?]>) => {
135        $(
136            impl_binary_op!(@impl $s::$op.$call);
137        )*
138    };
139    (@impl $s:ident::$op:ident.$call:ident) => {
140        impl<A, B> ::core::ops::$op<$s<B>> for &mut $s<A>
141        where
142            A: ::core::ops::$op<B>,
143        {
144
145            fn $call(&mut self, rhs: $s<B>) {
146                core::ops::$op::$call(&mut self.0, rhs.0)
147            }
148        }
149    };
150}
151
152macro_rules! impl_unary_op {
153    ($s:ident::<[$($op:ident.$call:ident),* $(,)?]>) => {
154        $(
155            impl_unary_op!(@impl $s::$op.$call);
156        )*
157    };
158    (@impl $s:ident::$op:ident.$call:ident) => {
159        impl<A> ::core::ops::$op for &mut $s<A>
160        where
161            A: Clone + ::core::ops::$op,
162        {
163            type Output = $s<A::Output>;
164
165            fn $call(self) -> Self::Output {
166                $s(core::ops::$op::$call(self.0.clone()))
167            }
168        }
169
170        impl<'a, A> ::core::ops::$op for &mut &'a $s<A>
171        where
172            A: Clone + ::core::ops::$op,
173        {
174            type Output = $s<A::Output>;
175
176            fn $call(self) -> Self::Output {
177                $s(core::ops::$op::$call(self.0.clone()))
178            }
179        }
180
181        impl<'a, A> ::core::ops::$op for &mut &'a mut $s<A>
182        where
183            A: Clone + ::core::ops::$op,
184        {
185            type Output = $s<A::Output>;
186
187            fn $call(self) -> Self::Output {
188                $s(core::ops::$op::$call(self.0.clone()))
189            }
190        }
191    };
192}
193
194impl_binary_op! {
195    State::<[
196        Add.add,
197        Sub.sub,
198        Mul.mul,
199        Div.div,
200        Rem.rem,
201        BitAnd.bitand,
202        BitOr.bitor,
203        BitXor.bitxor,
204        Shl.shl,
205        Shr.shr
206    ]>
207}
208
209impl_unary_op! {
210    State::<[
211        Neg.neg,
212        Not.not
213    ]>
214}