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);