malachite_nz/integer/comparison/
partial_cmp_primitive_int.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::integer::Integer;
10use crate::natural::Natural;
11use core::cmp::Ordering::{self, *};
12use malachite_base::num::arithmetic::traits::UnsignedAbs;
13use malachite_base::num::basic::traits::Zero;
14
15fn partial_cmp_unsigned<T>(x: &Integer, other: &T) -> Option<Ordering>
16where
17    Natural: PartialOrd<T>,
18{
19    if x.sign {
20        x.abs.partial_cmp(other)
21    } else {
22        Some(Less)
23    }
24}
25
26macro_rules! impl_unsigned {
27    ($t: ident) => {
28        impl PartialOrd<$t> for Integer {
29            /// Compares an [`Integer`] to an unsigned primitive integer.
30            ///
31            /// # Worst-case complexity
32            /// Constant time and additional memory.
33            ///
34            /// # Examples
35            /// See [here](super::partial_cmp_primitive_int#partial_cmp).
36            #[inline]
37            fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
38                partial_cmp_unsigned(self, other)
39            }
40        }
41
42        impl PartialOrd<Integer> for $t {
43            /// Compares an unsigned primitive integer to an [`Integer`].
44            ///
45            /// # Worst-case complexity
46            /// Constant time and additional memory.
47            ///
48            /// # Examples
49            /// See [here](super::partial_cmp_primitive_int#partial_cmp).
50            #[inline]
51            fn partial_cmp(&self, other: &Integer) -> Option<Ordering> {
52                other.partial_cmp(self).map(Ordering::reverse)
53            }
54        }
55    };
56}
57apply_to_unsigneds!(impl_unsigned);
58
59fn partial_cmp_signed<U: PartialOrd<Natural>, S: Copy + Ord + UnsignedAbs<Output = U> + Zero>(
60    x: &Integer,
61    other: &S,
62) -> Option<Ordering>
63where
64    Natural: PartialOrd<U>,
65{
66    if x.sign {
67        if *other >= S::ZERO {
68            x.abs.partial_cmp(&other.unsigned_abs())
69        } else {
70            Some(Greater)
71        }
72    } else if *other >= S::ZERO {
73        Some(Less)
74    } else {
75        other.unsigned_abs().partial_cmp(&x.abs)
76    }
77}
78
79macro_rules! impl_signed {
80    ($t: ident) => {
81        impl PartialOrd<$t> for Integer {
82            /// Compares an [`Integer`] to a signed primitive integer.
83            ///
84            /// # Worst-case complexity
85            /// Constant time and additional memory.
86            ///
87            /// # Examples
88            /// See [here](super::partial_cmp_primitive_int#partial_cmp).
89            #[inline]
90            fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
91                partial_cmp_signed(self, other)
92            }
93        }
94
95        impl PartialOrd<Integer> for $t {
96            /// Compares a signed primitive integer to an [`Integer`].
97            ///
98            /// # Worst-case complexity
99            /// Constant time and additional memory.
100            ///
101            /// # Examples
102            /// See [here](super::partial_cmp_primitive_int#partial_cmp).
103            #[inline]
104            fn partial_cmp(&self, other: &Integer) -> Option<Ordering> {
105                other.partial_cmp(self).map(Ordering::reverse)
106            }
107        }
108    };
109}
110apply_to_signeds!(impl_signed);