1use crate::{Choice, CtLt};
2use core::{
3 cmp,
4 num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize},
5};
6
7pub trait CtGt {
9 #[must_use]
11 fn ct_gt(&self, other: &Self) -> Choice;
12}
13
14macro_rules! impl_unsigned_ct_gt {
16 ( $($uint:ty),+ ) => {
17 $(
18 impl CtGt for $uint {
19 #[inline]
20 fn ct_gt(&self, other: &Self) -> Choice {
21 other.ct_lt(self)
22 }
23 }
24 )+
25 };
26}
27
28impl_unsigned_ct_gt!(u8, u16, u32, u64, u128, usize);
29
30macro_rules! impl_ct_gt_for_nonzero_integer {
32 ( $($ty:ty),+ ) => {
33 $(
34 impl CtGt for $ty {
35 #[inline]
36 fn ct_gt(&self, other: &Self) -> Choice {
37 self.get().ct_gt(&other.get())
38 }
39 }
40 )+
41 };
42}
43
44impl_ct_gt_for_nonzero_integer!(
45 NonZeroU8,
46 NonZeroU16,
47 NonZeroU32,
48 NonZeroU64,
49 NonZeroU128,
50 NonZeroUsize
51);
52
53impl CtGt for cmp::Ordering {
54 #[inline]
55 #[allow(clippy::arithmetic_side_effects, clippy::cast_sign_loss)]
56 fn ct_gt(&self, other: &Self) -> Choice {
57 let a = (*self as i8) + 1;
58 let b = (*other as i8) + 1;
59
60 a.cast_unsigned().ct_gt(&b.cast_unsigned())
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::CtGt;
68 use core::cmp::Ordering;
69
70 macro_rules! ct_gt_tests {
72 ( $($int:ident),+ ) => {
73 $(
74 mod $int {
75 use super::CtGt;
76
77 #[test]
78 fn ct_gt() {
79 let a = <$int>::MIN;
80 let b = <$int>::MAX;
81 assert!(!a.ct_gt(&a).to_bool());
82 assert!(!a.ct_gt(&b).to_bool());
83 assert!(b.ct_gt(&a).to_bool());
84 }
85
86 }
87 )+
88 };
89 }
90
91 ct_gt_tests!(u8, u16, u32, u64, u128, usize);
92
93 #[test]
94 fn ordering() {
95 assert!(!Ordering::Equal.ct_gt(&Ordering::Equal).to_bool());
96 assert!(!Ordering::Less.ct_gt(&Ordering::Greater).to_bool());
97 assert!(Ordering::Greater.ct_gt(&Ordering::Less).to_bool());
98 }
99}