multiversx_sc/types/managed/basic/
big_int_operators.rs

1use core::ops::{
2    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
3};
4
5use crate::{
6    api::{BigIntApiImpl, ManagedTypeApi},
7    types::{BigInt, BigUint, ManagedType, Sign},
8};
9
10macro_rules! binary_operator {
11    ($trait:ident, $method:ident, $api_func:ident) => {
12        impl<M: ManagedTypeApi> $trait for BigInt<M> {
13            type Output = BigInt<M>;
14
15            fn $method(self, other: BigInt<M>) -> BigInt<M> {
16                let api = M::managed_type_impl();
17                api.$api_func(
18                    self.handle.clone(),
19                    self.handle.clone(),
20                    other.handle.clone(),
21                );
22                self
23            }
24        }
25
26        impl<M: ManagedTypeApi> $trait<BigUint<M>> for BigInt<M> {
27            type Output = BigInt<M>;
28
29            fn $method(self, other: BigUint<M>) -> BigInt<M> {
30                self.$method(BigInt::from_biguint(Sign::Plus, other))
31            }
32        }
33
34        impl<M: ManagedTypeApi> $trait<BigInt<M>> for BigUint<M> {
35            type Output = BigInt<M>;
36
37            fn $method(self, other: BigInt<M>) -> BigInt<M> {
38                BigInt::from_biguint(Sign::Plus, self).$method(other)
39            }
40        }
41
42        impl<'a, 'b, M: ManagedTypeApi> $trait<&'b BigInt<M>> for &'a BigInt<M> {
43            type Output = BigInt<M>;
44
45            fn $method(self, other: &BigInt<M>) -> BigInt<M> {
46                let api = M::managed_type_impl();
47                unsafe {
48                    let result = BigInt::new_uninit();
49                    api.$api_func(
50                        result.get_handle(),
51                        self.handle.clone(),
52                        other.handle.clone(),
53                    );
54                    result
55                }
56            }
57        }
58
59        impl<'a, 'b, M: ManagedTypeApi> $trait<&'b BigUint<M>> for &'a BigInt<M> {
60            type Output = BigInt<M>;
61
62            fn $method(self, other: &BigUint<M>) -> BigInt<M> {
63                self.$method(other.as_big_int())
64            }
65        }
66
67        impl<'a, 'b, M: ManagedTypeApi> $trait<&'b BigInt<M>> for &'a BigUint<M> {
68            type Output = BigInt<M>;
69
70            fn $method(self, other: &BigInt<M>) -> BigInt<M> {
71                self.as_big_int().$method(other)
72            }
73        }
74    };
75}
76
77binary_operator! {Add, add, bi_add}
78binary_operator! {Sub, sub, bi_sub}
79binary_operator! {Mul, mul, bi_mul}
80binary_operator! {Div, div, bi_t_div}
81binary_operator! {Rem, rem, bi_t_mod}
82
83macro_rules! binary_assign_operator {
84    ($trait:ident, $method:ident, $api_func:ident) => {
85        impl<M: ManagedTypeApi> $trait<BigInt<M>> for BigInt<M> {
86            #[inline]
87            fn $method(&mut self, other: Self) {
88                let api = M::managed_type_impl();
89                api.$api_func(
90                    self.handle.clone(),
91                    self.handle.clone(),
92                    other.handle.clone(),
93                );
94            }
95        }
96
97        impl<M: ManagedTypeApi> $trait<&BigInt<M>> for BigInt<M> {
98            #[inline]
99            fn $method(&mut self, other: &BigInt<M>) {
100                let api = M::managed_type_impl();
101                api.$api_func(
102                    self.handle.clone(),
103                    self.handle.clone(),
104                    other.handle.clone(),
105                );
106            }
107        }
108    };
109}
110
111binary_assign_operator! {AddAssign, add_assign, bi_add}
112binary_assign_operator! {SubAssign, sub_assign, bi_sub}
113binary_assign_operator! {MulAssign, mul_assign, bi_mul}
114binary_assign_operator! {DivAssign, div_assign, bi_t_div}
115binary_assign_operator! {RemAssign, rem_assign, bi_t_mod}
116
117impl<M: ManagedTypeApi> Neg for BigInt<M> {
118    type Output = BigInt<M>;
119
120    fn neg(self) -> Self::Output {
121        unsafe {
122            let result = BigInt::new_uninit();
123            M::managed_type_impl().bi_neg(result.get_handle(), self.handle);
124            result
125        }
126    }
127}