malachite_base/num/comparison/
cmp_abs.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::UnsignedAbs;
10use crate::num::basic::floats::PrimitiveFloat;
11use crate::num::comparison::traits::{OrdAbs, PartialOrdAbs};
12use core::cmp::Ordering;
13
14macro_rules! impl_partial_ord_abs {
15    ($t:ident) => {
16        impl PartialOrdAbs<$t> for $t {
17            /// Compares the absolute values of two numbers, taking both by reference.
18            ///
19            /// The [`PartialOrdAbs`] interface allows for pairs of incomparable elements, but for
20            /// primitive integers these never occur.
21            ///
22            /// # Worst-case complexity
23            /// Constant time and additional memory.
24            ///
25            /// # Examples
26            /// See [here](super::cmp_abs#partial_cmp_abs).
27            #[inline]
28            fn partial_cmp_abs(&self, other: &$t) -> Option<Ordering> {
29                Some(self.cmp_abs(other))
30            }
31        }
32    };
33}
34apply_to_primitive_ints!(impl_partial_ord_abs);
35
36macro_rules! impl_ord_abs_unsigned {
37    ($t:ident) => {
38        impl OrdAbs for $t {
39            /// Compares the absolute values of two numbers, taking both by reference.
40            ///
41            /// For unsigned values, this is the same as ordinary comparison.
42            ///
43            /// # Worst-case complexity
44            /// Constant time and additional memory.
45            ///
46            /// # Examples
47            /// See [here](super::cmp_abs#cmp_abs).
48            #[inline]
49            fn cmp_abs(&self, other: &Self) -> Ordering {
50                self.cmp(other)
51            }
52        }
53    };
54}
55apply_to_unsigneds!(impl_ord_abs_unsigned);
56
57fn cmp_abs_signed<U: Ord, S: Copy + UnsignedAbs<Output = U>>(x: &S, y: &S) -> Ordering {
58    x.unsigned_abs().cmp(&y.unsigned_abs())
59}
60
61macro_rules! impl_ord_abs_signed {
62    ($t:ident) => {
63        impl OrdAbs for $t {
64            /// Compares the absolute values of two numbers, taking both by reference.
65            ///
66            /// # Worst-case complexity
67            /// Constant time and additional memory.
68            ///
69            /// # Examples
70            /// See [here](super::cmp_abs#cmp_abs).
71            #[inline]
72            fn cmp_abs(&self, other: &Self) -> Ordering {
73                cmp_abs_signed(self, other)
74            }
75        }
76    };
77}
78apply_to_signeds!(impl_ord_abs_signed);
79
80fn partial_cmp_abs_primitive_float<T: PrimitiveFloat>(x: &T, y: &T) -> Option<Ordering> {
81    x.abs().partial_cmp(&y.abs())
82}
83
84macro_rules! impl_ord_abs_primitive_float {
85    ($t:ident) => {
86        impl PartialOrdAbs for $t {
87            /// Compares the absolute values of two numbers, taking both by reference.
88            ///
89            /// For unsigned values, this is the same as ordinary comparison.
90            ///
91            /// # Worst-case complexity
92            /// Constant time and additional memory.
93            ///
94            /// # Examples
95            /// See [here](super::cmp_abs#cmp_abs).
96            #[inline]
97            fn partial_cmp_abs(&self, other: &Self) -> Option<Ordering> {
98                partial_cmp_abs_primitive_float(self, other)
99            }
100        }
101    };
102}
103apply_to_primitive_floats!(impl_ord_abs_primitive_float);