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