multiversx_sc/types/managed/basic/
big_int_operators.rs1use 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}