Skip to main content

relp_num/integer/big/
properties.rs

1use std::cmp::Ordering;
2use std::ops::Deref;
3
4use crate::{NonZero, Sign, Ubig};
5use crate::integer::big::NonZeroUbig;
6use crate::integer::big::ops::building_blocks::is_well_formed;
7use crate::Signed;
8
9impl<const S: usize> NonZero for Ubig<S> {
10    #[inline]
11    fn is_not_zero(&self) -> bool {
12        !self.0.is_empty()
13    }
14}
15
16impl<const S: usize> NonZero for NonZeroUbig<S> {
17    #[inline]
18    fn is_not_zero(&self) -> bool {
19        true
20    }
21}
22
23impl<const S: usize> Deref for Ubig<S> {
24    type Target = [usize];
25
26    fn deref(&self) -> &Self::Target {
27        &self.0
28    }
29}
30
31impl<const S: usize> Deref for NonZeroUbig<S> {
32    type Target = [usize];
33
34    fn deref(&self) -> &Self::Target {
35        &self.0
36    }
37}
38
39impl<const S: usize> Signed for Ubig<S> {
40    fn signum(&self) -> Sign {
41        Sign::Positive
42    }
43
44    fn is_positive(&self) -> bool {
45        true
46    }
47
48    fn is_negative(&self) -> bool {
49        false
50    }
51}
52
53impl<const S: usize> Signed for NonZeroUbig<S> {
54    fn signum(&self) -> Sign {
55        Sign::Positive
56    }
57
58    fn is_positive(&self) -> bool {
59        true
60    }
61
62    fn is_negative(&self) -> bool {
63        false
64    }
65}
66
67impl<const S: usize> Ord for NonZeroUbig<S> {
68    fn cmp(&self, other: &Self) -> Ordering {
69        cmp(&self.0, &other.0)
70    }
71}
72
73impl<const S: usize> Ord for Ubig<S> {
74    fn cmp(&self, other: &Self) -> Ordering {
75        cmp(&self.0, &other.0)
76    }
77}
78
79impl<const S: usize> PartialOrd for NonZeroUbig<S> {
80    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
81        Some(self.cmp(other))
82    }
83}
84
85impl<const S: usize> PartialOrd for Ubig<S> {
86    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
87        Some(self.cmp(other))
88    }
89}
90
91#[must_use]
92#[inline]
93pub fn cmp(left: &[usize], right: &[usize]) -> Ordering {
94    debug_assert!(is_well_formed(left));
95    debug_assert!(is_well_formed(right));
96
97    match left.len().cmp(&right.len()) {
98        Ordering::Less => Ordering::Less,
99        Ordering::Equal => {
100            // TODO(PERFORMANCE): Check that bounds checks are not done twice.
101            for (left_word, right_word) in left.iter().zip(right.iter()).rev() {
102                match left_word.cmp(right_word) {
103                    Ordering::Less => return Ordering::Less,
104                    Ordering::Equal => {}
105                    Ordering::Greater => return Ordering::Greater,
106                }
107            }
108
109            Ordering::Equal
110        }
111        Ordering::Greater => Ordering::Greater,
112    }
113}