1#[macro_export]
3#[cfg(not(doc))] #[doc(hidden)]
5macro_rules! uint {
6 ($($t:tt)*) => {
7 $crate::__private::ruint_macro::uint_with_path! { [$crate] $($t)* }
8 }
9}
10
11macro_rules! impl_bin_op {
12 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident, $fdel:ident) => {
13 impl<const BITS: usize, const LIMBS: usize> $trait_assign<Uint<BITS, LIMBS>>
14 for Uint<BITS, LIMBS>
15 {
16 #[inline(always)]
17 #[track_caller]
18 fn $fn_assign(&mut self, rhs: Uint<BITS, LIMBS>) {
19 *self = self.$fdel(rhs);
20 }
21 }
22 impl<const BITS: usize, const LIMBS: usize> $trait_assign<&Uint<BITS, LIMBS>>
23 for Uint<BITS, LIMBS>
24 {
25 #[inline(always)]
26 #[track_caller]
27 fn $fn_assign(&mut self, rhs: &Uint<BITS, LIMBS>) {
28 *self = self.$fdel(*rhs);
29 }
30 }
31 impl<const BITS: usize, const LIMBS: usize> $trait<Uint<BITS, LIMBS>>
32 for Uint<BITS, LIMBS>
33 {
34 type Output = Uint<BITS, LIMBS>;
35
36 #[inline(always)]
37 #[track_caller]
38 fn $fn(self, rhs: Uint<BITS, LIMBS>) -> Self::Output {
39 self.$fdel(rhs)
40 }
41 }
42 impl<const BITS: usize, const LIMBS: usize> $trait<&Uint<BITS, LIMBS>>
43 for Uint<BITS, LIMBS>
44 {
45 type Output = Uint<BITS, LIMBS>;
46
47 #[inline(always)]
48 #[track_caller]
49 fn $fn(self, rhs: &Uint<BITS, LIMBS>) -> Self::Output {
50 self.$fdel(*rhs)
51 }
52 }
53 impl<const BITS: usize, const LIMBS: usize> $trait<Uint<BITS, LIMBS>>
54 for &Uint<BITS, LIMBS>
55 {
56 type Output = Uint<BITS, LIMBS>;
57
58 #[inline(always)]
59 #[track_caller]
60 fn $fn(self, rhs: Uint<BITS, LIMBS>) -> Self::Output {
61 self.$fdel(rhs)
62 }
63 }
64 impl<const BITS: usize, const LIMBS: usize> $trait<&Uint<BITS, LIMBS>>
65 for &Uint<BITS, LIMBS>
66 {
67 type Output = Uint<BITS, LIMBS>;
68
69 #[inline(always)]
70 #[track_caller]
71 fn $fn(self, rhs: &Uint<BITS, LIMBS>) -> Self::Output {
72 self.$fdel(*rhs)
73 }
74 }
75 };
76}
77
78macro_rules! assume {
79 ($e:expr $(,)?) => {
80 if !$e {
81 debug_unreachable!(stringify!($e));
82 }
83 };
84
85 ($e:expr, $($t:tt)+) => {
86 if !$e {
87 debug_unreachable!($($t)+);
88 }
89 };
90}
91
92macro_rules! debug_unreachable {
93 ($($t:tt)*) => {
94 if cfg!(debug_assertions) {
95 unreachable!($($t)*);
96 } else {
97 unsafe { core::hint::unreachable_unchecked() };
98 }
99 };
100}
101
102macro_rules! let_double_bits {
104 ($id:ident) => {
105 let mut double = [[0u64; 2]; LIMBS];
108 let double_len = crate::nlimbs(2 * BITS);
109 debug_assert!(2 * LIMBS >= double_len);
110 let $id = unsafe {
112 core::slice::from_raw_parts_mut(double.as_mut_ptr().cast::<u64>(), double_len)
113 };
114 };
115}
116
117macro_rules! as_primitives {
119 ($uint:expr, { $($arm:ident $t:tt => $e:expr),* $(,)? }) => {
120 $(
121 as_primitives!(@arm $uint; $arm $t => $e);
122 )*
123 };
124
125 (@arm $uint:expr; u64($n:ident) => $e:expr) => {
126 if LIMBS == 1 {
127 let $n = $uint.limbs[0];
128 $e
129 }
130 };
131 (@arm $uint:expr; u128($n:ident) => $e:expr) => {
132 if LIMBS == 2 {
133 let $n = $uint.as_double_words()[0].get();
134 $e
135 }
136 };
137 (@arm $uint:expr; u256($lo:ident, $hi:ident) => $e:expr) => {
138 if LIMBS == 4 {
139 let &[lo, hi] = $uint.as_double_words() else { unreachable!() };
140 let $lo = lo.get();
141 let $hi = hi.get();
142 $e
143 }
144 };
145}
146
147#[cfg(test)]
148mod tests {
149 ruint_macro::uint_with_path! {
151 [crate]
152 const _A: [crate::aliases::U256; 2] = [
153 0x00006f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5_U256,
154 0x00004b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8_U256,
155 ];
156 }
157
158 crate::uint! {
159 const _B: [crate::aliases::U256; 2] = [
160 0x00006f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5_U256,
161 0x00004b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8_U256,
162 ];
163 }
164
165 #[test]
166 fn test_uint_macro_with_paths() {
167 extern crate self as aaa;
168 use crate as ruint;
169 use crate as __ruint;
170 let value = crate::aliases::U256::from(0x10);
171 assert_eq!(value, uint!(0x10U256));
172 assert_eq!(value, ruint_macro::uint_with_path!([crate] 0x10U256));
173 assert_eq!(value, ruint_macro::uint_with_path!([aaa] 0x10U256));
174 assert_eq!(value, ruint_macro::uint_with_path!([aaa] 0x10U256));
175 assert_eq!(value, ruint_macro::uint_with_path!([ruint] 0x10U256));
176 assert_eq!(value, ruint_macro::uint_with_path!([__ruint] 0x10U256));
177 }
178}