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