1use std::cmp::Ordering;
3use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
4use std::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
5
6use crate::Negateable;
7use crate::Sign;
8use crate::Signed;
9
10macro_rules! unsigned {
11 ($ty:ty) => {
12 impl Signed for $ty {
13 #[must_use]
14 #[inline]
15 fn signum(&self) -> Sign {
16 if *self == 0 {
17 Sign::Zero
18 } else {
19 Sign::Positive
20 }
21 }
22 }
23 }
24}
25
26unsigned!(u8);
27unsigned!(u16);
28unsigned!(u32);
29unsigned!(u64);
30unsigned!(u128);
31unsigned!(usize);
32
33macro_rules! signed {
34 ($ty:ty) => {
35 impl Signed for $ty {
36 #[must_use]
37 #[inline]
38 fn signum(&self) -> Sign {
39 match self.cmp(&0) {
40 Ordering::Less => Sign::Negative,
41 Ordering::Equal => Sign::Zero,
42 Ordering::Greater => Sign::Positive,
43 }
44 }
45 }
46
47 impl Negateable for $ty {
48 #[inline]
49 fn negate(&mut self) {
50 *self = -*self;
51 }
52 }
53 }
54}
55
56signed!(i8);
57signed!(i16);
58signed!(i32);
59signed!(i64);
60signed!(i128);
61signed!(isize);
62
63macro_rules! non_zero_unsigned {
64 ($ty:ty) => {
65 impl Signed for $ty {
66 #[must_use]
67 #[inline]
68 fn signum(&self) -> Sign {
69 Sign::Positive
70 }
71 }
72 }
73}
74
75non_zero_unsigned!(NonZeroU8);
76non_zero_unsigned!(NonZeroU16);
77non_zero_unsigned!(NonZeroU32);
78non_zero_unsigned!(NonZeroU64);
79non_zero_unsigned!(NonZeroU128);
80non_zero_unsigned!(NonZeroUsize);
81
82macro_rules! non_zero_signed {
83 ($ty:ty) => {
84 impl Signed for $ty {
85 #[must_use]
86 #[inline]
87 fn signum(&self) -> Sign {
88 if self.get() > 0 {
89 Sign::Positive
90 } else {
91 Sign::Negative
92 }
93 }
94 }
95
96 impl Negateable for $ty {
97 #[inline]
98 fn negate(&mut self) {
99 *self = unsafe {
100 <$ty>::new_unchecked(-self.get())
102 };
103 }
104 }
105 }
106}
107
108non_zero_signed!(NonZeroI8);
109non_zero_signed!(NonZeroI16);
110non_zero_signed!(NonZeroI32);
111non_zero_signed!(NonZeroI64);
112non_zero_signed!(NonZeroI128);
113non_zero_signed!(NonZeroIsize);
114
115#[cfg(test)]
116mod test {
117 use std::num::{NonZeroI8, NonZeroU8};
118
119 use crate::{NonZeroSign, NonZeroSigned};
120
121 #[test]
122 fn test_zero_sign() {
123 assert_eq!(1_u32.non_zero_signum(), NonZeroSign::Positive);
124 assert_eq!(-1_u32.non_zero_signum(), NonZeroSign::Negative);
125
126 assert_eq!(NonZeroU8::new(1).unwrap().non_zero_signum(), NonZeroSign::Positive);
127 assert_eq!(NonZeroI8::new(1).unwrap().non_zero_signum(), NonZeroSign::Positive);
128 assert_eq!(NonZeroI8::new(-1).unwrap().non_zero_signum(), NonZeroSign::Negative);
129 }
130
131 #[test]
132 #[should_panic]
133 fn test_non_zero_on_zero() {
134 0_u32.non_zero_signum();
135 }
136
137 #[test]
138 #[should_panic]
139 fn test_non_zero_on_zero_signed() {
140 0_i8.non_zero_signum();
141 }
142}