1use super::{FixedUInt, MachineWord};
2use crate::machineword::ConstMachineWord;
3use const_num_traits::Nct;
4use const_num_traits::{CheckedEuclid, Euclid, Zero};
5
6c0nst::c0nst! {
7 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> Euclid for FixedUInt<T, N, Nct> {
8 fn div_euclid(self, v: Self) -> Self {
9 self / v
11 }
12
13 fn rem_euclid(self, v: Self) -> Self {
14 self % v
16 }
17
18 fn div_rem_euclid(self, v: Self) -> (Self, Self) {
19 (self / v, self % v)
20 }
21 }
22
23 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> CheckedEuclid for FixedUInt<T, N, Nct> {
24 fn checked_div_euclid(self, v: Self) -> Option<Self> {
25 if <Self as Zero>::is_zero(&v) {
26 None
27 } else {
28 Some(self / v)
29 }
30 }
31
32 fn checked_rem_euclid(self, v: Self) -> Option<Self> {
33 if <Self as Zero>::is_zero(&v) {
34 None
35 } else {
36 Some(self % v)
37 }
38 }
39
40 fn checked_div_rem_euclid(self, v: Self) -> Option<(Self, Self)> {
41 if <Self as Zero>::is_zero(&v) {
42 None
43 } else {
44 Some((self / v, self % v))
45 }
46 }
47 }
48
49 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> Euclid for &FixedUInt<T, N, Nct> {
50 fn div_euclid(self, v: Self) -> FixedUInt<T, N, Nct> {
51 <FixedUInt<T, N, Nct> as Euclid>::div_euclid(*self, *v)
52 }
53 fn rem_euclid(self, v: Self) -> FixedUInt<T, N, Nct> {
54 <FixedUInt<T, N, Nct> as Euclid>::rem_euclid(*self, *v)
55 }
56 fn div_rem_euclid(self, v: Self) -> (FixedUInt<T, N, Nct>, FixedUInt<T, N, Nct>) {
57 <FixedUInt<T, N, Nct> as Euclid>::div_rem_euclid(*self, *v)
58 }
59 }
60
61 c0nst impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> CheckedEuclid for &FixedUInt<T, N, Nct> {
62 fn checked_div_euclid(self, v: Self) -> Option<FixedUInt<T, N, Nct>> {
63 <FixedUInt<T, N, Nct> as CheckedEuclid>::checked_div_euclid(*self, *v)
64 }
65 fn checked_rem_euclid(self, v: Self) -> Option<FixedUInt<T, N, Nct>> {
66 <FixedUInt<T, N, Nct> as CheckedEuclid>::checked_rem_euclid(*self, *v)
67 }
68 fn checked_div_rem_euclid(self, v: Self) -> Option<(FixedUInt<T, N, Nct>, FixedUInt<T, N, Nct>)> {
69 <FixedUInt<T, N, Nct> as CheckedEuclid>::checked_div_rem_euclid(*self, *v)
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_div_euclid() {
80 let a = FixedUInt::<u8, 2>::from(100u8);
81 let b = FixedUInt::<u8, 2>::from(30u8);
82 assert_eq!(Euclid::div_euclid(a, b), 3u8.into());
83 assert_eq!(Euclid::rem_euclid(a, b), 10u8.into());
84 }
85
86 #[test]
87 fn test_checked_div_euclid() {
88 let a = FixedUInt::<u8, 2>::from(100u8);
89 let b = FixedUInt::<u8, 2>::from(30u8);
90 assert_eq!(CheckedEuclid::checked_div_euclid(a, b), Some(3u8.into()));
91 assert_eq!(CheckedEuclid::checked_rem_euclid(a, b), Some(10u8.into()));
92
93 let zero = FixedUInt::<u8, 2>::from(0u8);
95 assert_eq!(CheckedEuclid::checked_div_euclid(a, zero), None);
96 assert_eq!(CheckedEuclid::checked_rem_euclid(a, zero), None);
97 }
98
99 c0nst::c0nst! {
100 pub c0nst fn const_div_euclid<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
101 a: &FixedUInt<T, N, Nct>,
102 b: &FixedUInt<T, N, Nct>,
103 ) -> FixedUInt<T, N, Nct> {
104 Euclid::div_euclid(*a, *b)
105 }
106
107 pub c0nst fn const_rem_euclid<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
108 a: &FixedUInt<T, N, Nct>,
109 b: &FixedUInt<T, N, Nct>,
110 ) -> FixedUInt<T, N, Nct> {
111 Euclid::rem_euclid(*a, *b)
112 }
113
114 pub c0nst fn const_checked_div_euclid<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
115 a: &FixedUInt<T, N, Nct>,
116 b: &FixedUInt<T, N, Nct>,
117 ) -> Option<FixedUInt<T, N, Nct>> {
118 CheckedEuclid::checked_div_euclid(*a, *b)
119 }
120
121 pub c0nst fn const_checked_rem_euclid<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
122 a: &FixedUInt<T, N, Nct>,
123 b: &FixedUInt<T, N, Nct>,
124 ) -> Option<FixedUInt<T, N, Nct>> {
125 CheckedEuclid::checked_rem_euclid(*a, *b)
126 }
127 }
128
129 #[test]
130 fn test_const_euclid() {
131 let a = FixedUInt::<u8, 2>::from(100u8);
132 let b = FixedUInt::<u8, 2>::from(30u8);
133 assert_eq!(const_div_euclid(&a, &b), 3u8.into());
134 assert_eq!(const_rem_euclid(&a, &b), 10u8.into());
135 assert_eq!(const_checked_div_euclid(&a, &b), Some(3u8.into()));
136 assert_eq!(const_checked_rem_euclid(&a, &b), Some(10u8.into()));
137
138 #[cfg(feature = "nightly")]
139 {
140 const A: FixedUInt<u8, 2> = FixedUInt::from_array([100, 0]);
141 const B: FixedUInt<u8, 2> = FixedUInt::from_array([30, 0]);
142 const DIV_RESULT: FixedUInt<u8, 2> = const_div_euclid(&A, &B);
143 const REM_RESULT: FixedUInt<u8, 2> = const_rem_euclid(&A, &B);
144 const CHECKED_DIV: Option<FixedUInt<u8, 2>> = const_checked_div_euclid(&A, &B);
145 const CHECKED_REM: Option<FixedUInt<u8, 2>> = const_checked_rem_euclid(&A, &B);
146 assert_eq!(DIV_RESULT, FixedUInt::from_array([3, 0]));
147 assert_eq!(REM_RESULT, FixedUInt::from_array([10, 0]));
148 assert_eq!(CHECKED_DIV, Some(FixedUInt::from_array([3, 0])));
149 assert_eq!(CHECKED_REM, Some(FixedUInt::from_array([10, 0])));
150 }
151 }
152}