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