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