fixed_bigint/fixeduint/
multiple_impl.rs1use super::{FixedUInt, MachineWord};
18use crate::const_numtraits::{ConstCheckedAdd, ConstMultiple, ConstZero};
19use crate::machineword::ConstMachineWord;
20
21c0nst::c0nst! {
22 impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstMultiple for FixedUInt<T, N> {
23 fn is_multiple_of(&self, rhs: &Self) -> bool {
24 if rhs.is_zero() {
25 false
26 } else {
27 (*self % *rhs).is_zero()
28 }
29 }
30
31 fn next_multiple_of(self, rhs: Self) -> Self {
32 match self.checked_next_multiple_of(rhs) {
33 Some(v) => v,
34 None => panic!("next_multiple_of: rhs is zero or result overflows"),
35 }
36 }
37
38 fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
39 if rhs.is_zero() {
40 return None;
41 }
42 let rem = self % rhs;
43 if rem.is_zero() {
44 Some(self)
45 } else {
46 let add = rhs - rem;
48 ConstCheckedAdd::checked_add(&self, &add)
49 }
50 }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_is_multiple_of() {
60 type U16 = FixedUInt<u8, 2>;
61
62 assert!(ConstMultiple::is_multiple_of(
63 &U16::from(0u8),
64 &U16::from(5u8)
65 ));
66 assert!(ConstMultiple::is_multiple_of(
67 &U16::from(10u8),
68 &U16::from(5u8)
69 ));
70 assert!(ConstMultiple::is_multiple_of(
71 &U16::from(15u8),
72 &U16::from(5u8)
73 ));
74 assert!(!ConstMultiple::is_multiple_of(
75 &U16::from(11u8),
76 &U16::from(5u8)
77 ));
78 assert!(ConstMultiple::is_multiple_of(
79 &U16::from(100u8),
80 &U16::from(10u8)
81 ));
82 assert!(!ConstMultiple::is_multiple_of(
83 &U16::from(101u8),
84 &U16::from(10u8)
85 ));
86
87 assert!(!ConstMultiple::is_multiple_of(
89 &U16::from(10u8),
90 &U16::from(0u8)
91 ));
92 }
93
94 #[test]
95 fn test_next_multiple_of() {
96 type U16 = FixedUInt<u8, 2>;
97
98 assert_eq!(
100 ConstMultiple::next_multiple_of(U16::from(10u8), U16::from(5u8)),
101 U16::from(10u8)
102 );
103 assert_eq!(
104 ConstMultiple::next_multiple_of(U16::from(0u8), U16::from(5u8)),
105 U16::from(0u8)
106 );
107
108 assert_eq!(
110 ConstMultiple::next_multiple_of(U16::from(11u8), U16::from(5u8)),
111 U16::from(15u8)
112 );
113 assert_eq!(
114 ConstMultiple::next_multiple_of(U16::from(12u8), U16::from(5u8)),
115 U16::from(15u8)
116 );
117 assert_eq!(
118 ConstMultiple::next_multiple_of(U16::from(14u8), U16::from(5u8)),
119 U16::from(15u8)
120 );
121
122 assert_eq!(
124 ConstMultiple::next_multiple_of(U16::from(101u8), U16::from(10u8)),
125 U16::from(110u8)
126 );
127 }
128
129 #[test]
130 fn test_checked_next_multiple_of() {
131 type U16 = FixedUInt<u8, 2>;
132
133 assert_eq!(
135 ConstMultiple::checked_next_multiple_of(U16::from(11u8), U16::from(5u8)),
136 Some(U16::from(15u8))
137 );
138
139 assert_eq!(
141 ConstMultiple::checked_next_multiple_of(U16::from(10u8), U16::from(0u8)),
142 None
143 );
144
145 let large = U16::from(65530u16);
147 assert_eq!(
148 ConstMultiple::checked_next_multiple_of(large, U16::from(10u8)),
149 Some(large)
150 ); let large2 = U16::from(65531u16);
154 assert_eq!(
155 ConstMultiple::checked_next_multiple_of(large2, U16::from(10u8)),
156 None
157 ); }
159
160 c0nst::c0nst! {
161 pub c0nst fn const_is_multiple_of<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
162 a: &FixedUInt<T, N>,
163 b: &FixedUInt<T, N>,
164 ) -> bool {
165 ConstMultiple::is_multiple_of(a, b)
166 }
167
168 pub c0nst fn const_next_multiple_of<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(
169 a: FixedUInt<T, N>,
170 b: FixedUInt<T, N>,
171 ) -> FixedUInt<T, N> {
172 ConstMultiple::next_multiple_of(a, b)
173 }
174 }
175
176 #[test]
177 fn test_const_multiple() {
178 type U16 = FixedUInt<u8, 2>;
179
180 assert!(const_is_multiple_of(&U16::from(10u8), &U16::from(5u8)));
181 assert_eq!(
182 const_next_multiple_of(U16::from(11u8), U16::from(5u8)),
183 U16::from(15u8)
184 );
185
186 #[cfg(feature = "nightly")]
187 {
188 const TEN: U16 = FixedUInt { array: [10, 0] };
189 const FIVE: U16 = FixedUInt { array: [5, 0] };
190 const IS_MULT: bool = const_is_multiple_of(&TEN, &FIVE);
191 assert!(IS_MULT);
192
193 const ELEVEN: U16 = FixedUInt { array: [11, 0] };
194 const NEXT: U16 = const_next_multiple_of(ELEVEN, FIVE);
195 assert_eq!(NEXT, FixedUInt { array: [15, 0] });
196 }
197 }
198}