nstd_sys/core/
ops.rs

1//! Operator overloading for types and operators that may cause overflow.
2//!
3//! The types of overflows that this module attempts to catch can be found
4//! [here](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow).
5use crate::{
6    core::optional::{
7        NSTDOptional, NSTDOptionalInt, NSTDOptionalInt16, NSTDOptionalInt32, NSTDOptionalInt64,
8        NSTDOptionalInt8, NSTDOptionalUInt, NSTDOptionalUInt16, NSTDOptionalUInt32,
9        NSTDOptionalUInt64, NSTDOptionalUInt8,
10    },
11    NSTDInt, NSTDInt16, NSTDInt32, NSTDInt64, NSTDInt8, NSTDUInt, NSTDUInt16, NSTDUInt32,
12    NSTDUInt64, NSTDUInt8,
13};
14use nstdapi::nstdapi;
15
16/// Generates the negate (-) operator implementation, this is not to be confused with the
17/// subtraction operator.
18macro_rules! gen_neg {
19    ($name: ident, $T: ty, $Opt: ty) => {
20        /// Returns the negative value of `x`.
21        ///
22        /// # Parameters:
23        ///
24        #[doc = concat!(" - `", stringify!($T), " x` - The value to negate.")]
25        ///
26        /// # Returns
27        ///
28        #[doc = concat!(" `", stringify!($Opt), " v` - The negative value of `x` on success, or an uninitialized \"none\" variant on overflow.")]
29        ///
30        /// # Example
31        ///
32        /// ```
33        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
34        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
35        ///
36        /// # unsafe {
37        #[doc = concat!("assert!(", stringify!($name), "(69) == NSTDOptional::Some(-69));")]
38        #[doc = concat!("assert!(", stringify!($name), "(", stringify!($T), "::MIN) == NSTDOptional::None);")]
39        /// # }
40        /// ```
41        #[inline]
42        #[nstdapi]
43        pub const fn $name(x: $T) -> $Opt {
44            match x.checked_neg() {
45                Some(v) => NSTDOptional::Some(v),
46                _ => NSTDOptional::None,
47            }
48        }
49    };
50}
51gen_neg!(nstd_core_ops_neg_int, NSTDInt, NSTDOptionalInt);
52gen_neg!(nstd_core_ops_neg_i8, NSTDInt8, NSTDOptionalInt8);
53gen_neg!(nstd_core_ops_neg_i16, NSTDInt16, NSTDOptionalInt16);
54gen_neg!(nstd_core_ops_neg_i32, NSTDInt32, NSTDOptionalInt32);
55gen_neg!(nstd_core_ops_neg_i64, NSTDInt64, NSTDOptionalInt64);
56
57/// Generates the addition (+) operator implementations.
58macro_rules! gen_add {
59    ($name: ident, $T: ty, $Opt: ty) => {
60        /// Computes the addition operation of `x` + `y`.
61        ///
62        /// # Parameters:
63        ///
64        #[doc = concat!(" - `", stringify!($T), " x` - The left operand.")]
65        ///
66        #[doc = concat!(" - `", stringify!($T), " y` - The right operand.")]
67        ///
68        /// # Returns
69        ///
70        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant on overflow.")]
71        ///
72        /// # Example
73        ///
74        /// ```
75        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
76        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
77        ///
78        /// # unsafe {
79        #[doc = concat!("assert!(", stringify!($name), "(4, 5) == NSTDOptional::Some(9));")]
80        #[doc = concat!("assert!(", stringify!($name), "(", stringify!($T), "::MAX, 1) == NSTDOptional::None);")]
81        /// # }
82        /// ```
83        #[inline]
84        #[nstdapi]
85        pub const fn $name(x: $T, y: $T) -> $Opt {
86            match x.checked_add(y) {
87                Some(v) => NSTDOptional::Some(v),
88                _ => NSTDOptional::None,
89            }
90        }
91    };
92}
93gen_add!(nstd_core_ops_add_int, NSTDInt, NSTDOptionalInt);
94gen_add!(nstd_core_ops_add_uint, NSTDUInt, NSTDOptionalUInt);
95gen_add!(nstd_core_ops_add_i8, NSTDInt8, NSTDOptionalInt8);
96gen_add!(nstd_core_ops_add_u8, NSTDUInt8, NSTDOptionalUInt8);
97gen_add!(nstd_core_ops_add_i16, NSTDInt16, NSTDOptionalInt16);
98gen_add!(nstd_core_ops_add_u16, NSTDUInt16, NSTDOptionalUInt16);
99gen_add!(nstd_core_ops_add_i32, NSTDInt32, NSTDOptionalInt32);
100gen_add!(nstd_core_ops_add_u32, NSTDUInt32, NSTDOptionalUInt32);
101gen_add!(nstd_core_ops_add_i64, NSTDInt64, NSTDOptionalInt64);
102gen_add!(nstd_core_ops_add_u64, NSTDUInt64, NSTDOptionalUInt64);
103
104/// Generates the subtraction (-) operator implementations.
105macro_rules! gen_sub {
106    ($name: ident, $T: ty, $Opt: ty) => {
107        /// Computes the subtraction operation of `x` - `y`.
108        ///
109        /// # Parameters:
110        ///
111        #[doc = concat!(" - `", stringify!($T), " x` - The left operand.")]
112        ///
113        #[doc = concat!(" - `", stringify!($T), " y` - The right operand.")]
114        ///
115        /// # Returns
116        ///
117        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant on overflow.")]
118        ///
119        /// # Example
120        ///
121        /// ```
122        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
123        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
124        ///
125        /// # unsafe {
126        #[doc = concat!("assert!(", stringify!($name), "(9, 5) == NSTDOptional::Some(4));")]
127        #[doc = concat!("assert!(", stringify!($name), "(", stringify!($T), "::MIN, 1) == NSTDOptional::None);")]
128        /// # }
129        /// ```
130        #[inline]
131        #[nstdapi]
132        pub const fn $name(x: $T, y: $T) -> $Opt {
133            match x.checked_sub(y) {
134                Some(v) => NSTDOptional::Some(v),
135                _ => NSTDOptional::None,
136            }
137        }
138    };
139}
140gen_sub!(nstd_core_ops_sub_int, NSTDInt, NSTDOptionalInt);
141gen_sub!(nstd_core_ops_sub_uint, NSTDUInt, NSTDOptionalUInt);
142gen_sub!(nstd_core_ops_sub_i8, NSTDInt8, NSTDOptionalInt8);
143gen_sub!(nstd_core_ops_sub_u8, NSTDUInt8, NSTDOptionalUInt8);
144gen_sub!(nstd_core_ops_sub_i16, NSTDInt16, NSTDOptionalInt16);
145gen_sub!(nstd_core_ops_sub_u16, NSTDUInt16, NSTDOptionalUInt16);
146gen_sub!(nstd_core_ops_sub_i32, NSTDInt32, NSTDOptionalInt32);
147gen_sub!(nstd_core_ops_sub_u32, NSTDUInt32, NSTDOptionalUInt32);
148gen_sub!(nstd_core_ops_sub_i64, NSTDInt64, NSTDOptionalInt64);
149gen_sub!(nstd_core_ops_sub_u64, NSTDUInt64, NSTDOptionalUInt64);
150
151/// Generates the multiplication (*) operator implementations.
152macro_rules! gen_mul {
153    ($name: ident, $T: ty, $Opt: ty) => {
154        /// Computes the multiplication operation of `x` * `y`.
155        ///
156        /// # Parameters:
157        ///
158        #[doc = concat!(" - `", stringify!($T), " x` - The left operand.")]
159        ///
160        #[doc = concat!(" - `", stringify!($T), " y` - The right operand.")]
161        ///
162        /// # Returns
163        ///
164        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant on overflow.")]
165        ///
166        /// # Example
167        ///
168        /// ```
169        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
170        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
171        ///
172        /// # unsafe {
173        #[doc = concat!("assert!(", stringify!($name), "(3, 4) == NSTDOptional::Some(12));")]
174        #[doc = concat!("assert!(", stringify!($name), "(", stringify!($T), "::MAX, 2) == NSTDOptional::None);")]
175        /// # }
176        /// ```
177        #[inline]
178        #[nstdapi]
179        pub const fn $name(x: $T, y: $T) -> $Opt {
180            match x.checked_mul(y) {
181                Some(v) => NSTDOptional::Some(v),
182                _ => NSTDOptional::None,
183            }
184        }
185    };
186}
187gen_mul!(nstd_core_ops_mul_int, NSTDInt, NSTDOptionalInt);
188gen_mul!(nstd_core_ops_mul_uint, NSTDUInt, NSTDOptionalUInt);
189gen_mul!(nstd_core_ops_mul_i8, NSTDInt8, NSTDOptionalInt8);
190gen_mul!(nstd_core_ops_mul_u8, NSTDUInt8, NSTDOptionalUInt8);
191gen_mul!(nstd_core_ops_mul_i16, NSTDInt16, NSTDOptionalInt16);
192gen_mul!(nstd_core_ops_mul_u16, NSTDUInt16, NSTDOptionalUInt16);
193gen_mul!(nstd_core_ops_mul_i32, NSTDInt32, NSTDOptionalInt32);
194gen_mul!(nstd_core_ops_mul_u32, NSTDUInt32, NSTDOptionalUInt32);
195gen_mul!(nstd_core_ops_mul_i64, NSTDInt64, NSTDOptionalInt64);
196gen_mul!(nstd_core_ops_mul_u64, NSTDUInt64, NSTDOptionalUInt64);
197
198/// Generates the division (/) operator implementations.
199macro_rules! gen_div {
200    ($name: ident, $T: ty, $Opt: ty) => {
201        /// Computes the division operation of `x` / `y`.
202        ///
203        /// # Parameters:
204        ///
205        #[doc = concat!(" - `", stringify!($T), " x` - The left operand.")]
206        ///
207        #[doc = concat!(" - `", stringify!($T), " y` - The right operand.")]
208        ///
209        /// # Returns
210        ///
211        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant if `y` is 0 or overflow occurs.")]
212        ///
213        /// # Example
214        ///
215        /// ```
216        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
217        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
218        ///
219        /// # unsafe {
220        #[doc = concat!("assert!(", stringify!($name), "(15, 3) == NSTDOptional::Some(5));")]
221        #[doc = concat!("assert!(", stringify!($name), "(15, 0) == NSTDOptional::None);")]
222        /// # }
223        /// ```
224        #[inline]
225        #[nstdapi]
226        pub const fn $name(x: $T, y: $T) -> $Opt {
227            match x.checked_div(y) {
228                Some(v) => NSTDOptional::Some(v),
229                _ => NSTDOptional::None,
230            }
231        }
232    };
233}
234gen_div!(nstd_core_ops_div_int, NSTDInt, NSTDOptionalInt);
235gen_div!(nstd_core_ops_div_uint, NSTDUInt, NSTDOptionalUInt);
236gen_div!(nstd_core_ops_div_i8, NSTDInt8, NSTDOptionalInt8);
237gen_div!(nstd_core_ops_div_u8, NSTDUInt8, NSTDOptionalUInt8);
238gen_div!(nstd_core_ops_div_i16, NSTDInt16, NSTDOptionalInt16);
239gen_div!(nstd_core_ops_div_u16, NSTDUInt16, NSTDOptionalUInt16);
240gen_div!(nstd_core_ops_div_i32, NSTDInt32, NSTDOptionalInt32);
241gen_div!(nstd_core_ops_div_u32, NSTDUInt32, NSTDOptionalUInt32);
242gen_div!(nstd_core_ops_div_i64, NSTDInt64, NSTDOptionalInt64);
243gen_div!(nstd_core_ops_div_u64, NSTDUInt64, NSTDOptionalUInt64);
244
245/// Generates the remainder (%) operator implementations.
246macro_rules! gen_rem {
247    ($name: ident, $T: ty, $Opt: ty) => {
248        /// Computes the remainder of `x` / `y`.
249        ///
250        /// # Parameters:
251        ///
252        #[doc = concat!(" - `", stringify!($T), " x` - The left operand.")]
253        ///
254        #[doc = concat!(" - `", stringify!($T), " y` - The right operand.")]
255        ///
256        /// # Returns
257        ///
258        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant if `y` is 0 or overflow occurs.")]
259        ///
260        /// # Example
261        ///
262        /// ```
263        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
264        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
265        ///
266        /// # unsafe {
267        #[doc = concat!("assert!(", stringify!($name), "(23, 5) == NSTDOptional::Some(3));")]
268        #[doc = concat!("assert!(", stringify!($name), "(23, 0) == NSTDOptional::None);")]
269        /// # }
270        /// ```
271        #[inline]
272        #[nstdapi]
273        pub const fn $name(x: $T, y: $T) -> $Opt {
274            match x.checked_rem(y) {
275                Some(v) => NSTDOptional::Some(v),
276                _ => NSTDOptional::None,
277            }
278        }
279    };
280}
281gen_rem!(nstd_core_ops_rem_int, NSTDInt, NSTDOptionalInt);
282gen_rem!(nstd_core_ops_rem_uint, NSTDUInt, NSTDOptionalUInt);
283gen_rem!(nstd_core_ops_rem_i8, NSTDInt8, NSTDOptionalInt8);
284gen_rem!(nstd_core_ops_rem_u8, NSTDUInt8, NSTDOptionalUInt8);
285gen_rem!(nstd_core_ops_rem_i16, NSTDInt16, NSTDOptionalInt16);
286gen_rem!(nstd_core_ops_rem_u16, NSTDUInt16, NSTDOptionalUInt16);
287gen_rem!(nstd_core_ops_rem_i32, NSTDInt32, NSTDOptionalInt32);
288gen_rem!(nstd_core_ops_rem_u32, NSTDUInt32, NSTDOptionalUInt32);
289gen_rem!(nstd_core_ops_rem_i64, NSTDInt64, NSTDOptionalInt64);
290gen_rem!(nstd_core_ops_rem_u64, NSTDUInt64, NSTDOptionalUInt64);
291
292/// Generates the shift left (<<) operator implementations.
293macro_rules! gen_shl {
294    ($name: ident, $T: ty, $Opt: ty) => {
295        /// Shifts value `x` `y` bits to the left.
296        ///
297        /// # Parameters:
298        ///
299        #[doc = concat!(" - `", stringify!($T), " x` - The value to shift.")]
300        ///
301        /// - `NSTDUInt32 y` - The number of bits to shift.
302        ///
303        /// # Returns
304        ///
305        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant on overflow.")]
306        ///
307        /// # Example
308        ///
309        /// ```
310        #[doc = concat!("use nstd_sys::", stringify!($T), ";")]
311        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
312        ///
313        /// # unsafe {
314        #[doc = concat!("assert!(", stringify!($name), "(1, 4) == NSTDOptional::Some(16));")]
315        #[doc = concat!("assert!(", stringify!($name), "(1, 128) == NSTDOptional::None);")]
316        /// # }
317        /// ```
318        #[inline]
319        #[nstdapi]
320        pub const fn $name(x: $T, y: NSTDUInt32) -> $Opt {
321            match x.checked_shl(y) {
322                Some(v) => NSTDOptional::Some(v),
323                _ => NSTDOptional::None,
324            }
325        }
326    };
327}
328gen_shl!(nstd_core_ops_shl_int, NSTDInt, NSTDOptionalInt);
329gen_shl!(nstd_core_ops_shl_uint, NSTDUInt, NSTDOptionalUInt);
330gen_shl!(nstd_core_ops_shl_i8, NSTDInt8, NSTDOptionalInt8);
331gen_shl!(nstd_core_ops_shl_u8, NSTDUInt8, NSTDOptionalUInt8);
332gen_shl!(nstd_core_ops_shl_i16, NSTDInt16, NSTDOptionalInt16);
333gen_shl!(nstd_core_ops_shl_u16, NSTDUInt16, NSTDOptionalUInt16);
334gen_shl!(nstd_core_ops_shl_i32, NSTDInt32, NSTDOptionalInt32);
335gen_shl!(nstd_core_ops_shl_u32, NSTDUInt32, NSTDOptionalUInt32);
336gen_shl!(nstd_core_ops_shl_i64, NSTDInt64, NSTDOptionalInt64);
337gen_shl!(nstd_core_ops_shl_u64, NSTDUInt64, NSTDOptionalUInt64);
338
339/// Generates the shift right (>>) operator implementations.
340macro_rules! gen_shr {
341    ($name: ident, $T: ty, $Opt: ty) => {
342        /// Shifts value `x` `y` bits to the right.
343        ///
344        /// # Parameters:
345        ///
346        #[doc = concat!(" - `", stringify!($T), " x` - The value to shift.")]
347        ///
348        /// - `NSTDUInt32 y` - The number of bits to shift.
349        ///
350        /// # Returns
351        ///
352        #[doc = concat!(" `", stringify!($Opt), " z` - The result of the operation on success, or an uninitialized \"none\" variant on overflow.")]
353        ///
354        /// # Example
355        ///
356        /// ```
357        #[doc = concat!("use nstd_sys::core::{ops::", stringify!($name), ", optional::NSTDOptional};")]
358        ///
359        /// # unsafe {
360        #[doc = concat!("assert!(", stringify!($name), "(16, 4) == NSTDOptional::Some(1));")]
361        #[doc = concat!("assert!(", stringify!($name), "(16, 128) == NSTDOptional::None);")]
362        /// # }
363        /// ```
364        #[inline]
365        #[nstdapi]
366        pub const fn $name(x: $T, y: NSTDUInt32) -> $Opt {
367            match x.checked_shr(y) {
368                Some(v) => NSTDOptional::Some(v),
369                _ => NSTDOptional::None,
370            }
371        }
372    };
373}
374gen_shr!(nstd_core_ops_shr_int, NSTDInt, NSTDOptionalInt);
375gen_shr!(nstd_core_ops_shr_uint, NSTDUInt, NSTDOptionalUInt);
376gen_shr!(nstd_core_ops_shr_i8, NSTDInt8, NSTDOptionalInt8);
377gen_shr!(nstd_core_ops_shr_u8, NSTDUInt8, NSTDOptionalUInt8);
378gen_shr!(nstd_core_ops_shr_i16, NSTDInt16, NSTDOptionalInt16);
379gen_shr!(nstd_core_ops_shr_u16, NSTDUInt16, NSTDOptionalUInt16);
380gen_shr!(nstd_core_ops_shr_i32, NSTDInt32, NSTDOptionalInt32);
381gen_shr!(nstd_core_ops_shr_u32, NSTDUInt32, NSTDOptionalUInt32);
382gen_shr!(nstd_core_ops_shr_i64, NSTDInt64, NSTDOptionalInt64);
383gen_shr!(nstd_core_ops_shr_u64, NSTDUInt64, NSTDOptionalUInt64);