1define_bounded_integers! {
2 BoundedU8(u8, unaligned, unsigned),
3 BoundedU16(u16, unsigned),
4 BoundedU32(u32, unsigned),
5 BoundedU64(u64, unsigned),
6 BoundedU128(u128, unsigned),
7 BoundedUsize(usize, unsigned),
8 BoundedI8(i8, unaligned, unsigned),
9 BoundedI16(i16),
10 BoundedI32(i32),
11 BoundedI64(i64),
12 BoundedI128(i128),
13 BoundedIsize(isize),
14}
15
16macro_rules! define_bounded_integers {
17 ($($name:ident(
18 $inner:ident
19 $(, unaligned $([$unaligned:ident])?)?
20 $(, unsigned $([$unsigned:ident])?)?
21 ),)*) => { $(
22 #[doc = "An"]
23 #[doc = concat!("[`", stringify!($inner), "`]")]
24 #[doc = "constrained to be in the range `MIN..=MAX`."]
25 #[repr(transparent)]
26 #[cfg_attr(feature = "zerocopy", derive(zerocopy::IntoBytes, zerocopy::Immutable))]
27 #[cfg_attr(
28 all(feature = "zerocopy", any($($(if $unaligned)? true)?)),
29 derive(zerocopy::Unaligned),
30 )]
31 pub struct $name<const MIN: $inner, const MAX: $inner>($inner);
32
33 $crate::unsafe_api! {
34 [const MIN: $inner, const MAX: $inner] for $name<MIN, MAX>,
35 unsafe repr: $inner,
36 min: MIN,
37 max: MAX,
38 }
39
40 #[cfg(any($($(if $unsigned)? true)?))]
41 impl<const MAX: $inner> Default for $name<0, MAX> {
42 fn default() -> Self {
43 Self::const_new::<0>()
44 }
45 }
46
47 #[cfg(feature = "bytemuck1")]
48 #[cfg(any($($($unsigned)? true)?))]
49 unsafe impl<const MAX: $inner> bytemuck1::Zeroable for $name<0, MAX> {}
50 )* }
51}
52use define_bounded_integers;
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn range() {
60 type Bounded = BoundedI8<3, 10>;
61 assert_eq!(Bounded::MIN_VALUE, 3);
62 assert_eq!(Bounded::MAX_VALUE, 10);
63 assert_eq!(Bounded::MIN.get(), Bounded::MIN_VALUE);
64 assert_eq!(Bounded::MAX.get(), Bounded::MAX_VALUE);
65
66 assert!(Bounded::in_range(3));
67 assert!(!Bounded::in_range(2));
68 assert!(Bounded::in_range(10));
69 assert!(!Bounded::in_range(11));
70 }
71
72 #[test]
73 fn new_saturating() {
74 type Bounded = BoundedI8<3, 10>;
75 assert_eq!(Bounded::new_saturating(i8::MIN), Bounded::MIN);
76 assert_eq!(Bounded::new_saturating(i8::MAX), Bounded::MAX);
77 assert_eq!(Bounded::new_saturating(11).get(), 10);
78 assert_eq!(Bounded::new_saturating(10).get(), 10);
79 assert_eq!(Bounded::new_saturating(3).get(), 3);
80 assert_eq!(Bounded::new_saturating(2).get(), 3);
81 }
82
83 #[test]
84 fn wrapping_unwiden() {
85 type Bounded = BoundedU8<2, 20>;
86
87 assert_eq!(Bounded::new_wrapping(0_u8), 19);
88 assert_eq!(Bounded::new_wrapping(2_u8), 2);
89 assert_eq!(Bounded::new_wrapping(20_u8), 20);
90 assert_eq!(Bounded::new_wrapping(21_u8), 2);
91 assert_eq!(Bounded::new_wrapping(255_u8), 8);
92
93 assert_eq!(Bounded::new_wrapping(12_u16), 12);
94 assert_eq!(Bounded::new_wrapping(21_u16), 2);
95 assert_eq!(Bounded::new_wrapping(12_i16), 12);
96 assert_eq!(Bounded::new_wrapping(21_i16), 2);
97
98 assert_eq!(Bounded::new_wrapping(0_u16), 19);
99 assert_eq!(Bounded::new_wrapping(65535_u16), 4);
100 assert_eq!(Bounded::new_wrapping(65533_u16), 2);
101 assert_eq!(Bounded::new_wrapping(65532_u16), 20);
102
103 assert_eq!(Bounded::new_wrapping(-32768_i16), 7);
104 assert_eq!(Bounded::new_wrapping(-32755_i16), 20);
105 assert_eq!(Bounded::new_wrapping(-32754_i16), 2);
106 assert_eq!(Bounded::new_wrapping(32767_i16), 11);
107 }
108
109 #[test]
110 fn wrapping_full() {
111 type Bounded = BoundedI8<{ i8::MIN }, { i8::MAX }>;
112 assert_eq!(Bounded::new_wrapping(37_i8), 37);
113 assert_eq!(Bounded::new_wrapping(-128_i8), -128);
114 assert_eq!(Bounded::new_wrapping(127_i8), 127);
115 assert_eq!(Bounded::new_wrapping(128_i16), -128);
116 assert_eq!(Bounded::new_wrapping(-200_i16), 56);
117 assert_eq!(Bounded::new(25).unwrap().wrapping_pow(20), 97);
118 }
119
120 #[test]
121 fn wrapping_signed() {
122 type Bounded = BoundedI8<-5, 2>;
123 assert_eq!(Bounded::new_wrapping(0_i8).get(), 0);
124 assert_eq!(Bounded::new_wrapping(-5_i8).get(), -5);
125 assert_eq!(Bounded::new_wrapping(2_i8).get(), 2);
126 assert_eq!(Bounded::new_wrapping(-128_i8).get(), 0);
127 }
128
129 #[test]
130 fn arithmetic() {
131 #![expect(clippy::modulo_one)]
132 type Bounded = BoundedI8<-5, 20>;
133 assert_eq!(Bounded::new(2).unwrap() + 3, 5);
134 assert_eq!(Bounded::new(2).unwrap() - 5, -3);
135 assert_eq!(Bounded::new(3).unwrap() * 5, 15);
136 assert_eq!(Bounded::new(11).unwrap() / 3, 3);
137 assert_eq!(Bounded::new(11).unwrap() % 3, 2);
138 assert_eq!(Bounded::new(-3).unwrap() / 2, -1);
139 assert_eq!(Bounded::new(-3).unwrap() % 2, -1);
140 assert_eq!(-Bounded::new(-3).unwrap(), 3);
141 assert_eq!(!Bounded::new(-3).unwrap(), 2);
142 assert_eq!(-&Bounded::new(-3).unwrap(), 3);
143 assert_eq!(!&Bounded::new(-3).unwrap(), 2);
144 assert_eq!(Bounded::new(3).unwrap() << 1, 6);
145 assert_eq!(Bounded::new(3).unwrap() >> 1, 1);
146 variations!(Bounded, i8, + += - -= * *= / /= % %=);
147
148 assert_eq!(Bounded::new(2).unwrap().pow(3).get(), 8);
149 assert_eq!(Bounded::new(-3).unwrap().div_euclid(2).get(), -2);
150 assert_eq!(Bounded::new(-3).unwrap().rem_euclid(2).get(), 1);
151 assert_eq!(Bounded::new(-3).unwrap().abs().get(), 3);
152 assert_eq!(Bounded::new(4).unwrap().abs().get(), 4);
153
154 macro_rules! variations {
155 ($ty:ty, $inner:ty, $($op:tt $op_assign:tt)*) => {
156 $(
157 let _: $ty = <$ty>::new(0).unwrap() $op 1;
158 let _: $ty = &<$ty>::new(0).unwrap() $op 1;
159 let _: $ty = <$ty>::new(0).unwrap() $op &1;
160 let _: $ty = &<$ty>::new(0).unwrap() $op &1;
161 let _: $inner = 0 $op <$ty>::new(1).unwrap();
162 let _: $inner = 0 $op &<$ty>::new(1).unwrap();
163 let _: $inner = &0 $op <$ty>::new(1).unwrap();
164 let _: $inner = &0 $op &<$ty>::new(1).unwrap();
165 let _: $ty = <$ty>::new(0).unwrap() $op <$ty>::new(1).unwrap();
166 let _: $ty = &<$ty>::new(0).unwrap() $op <$ty>::new(1).unwrap();
167 let _: $ty = <$ty>::new(0).unwrap() $op &<$ty>::new(1).unwrap();
168 let _: $ty = &<$ty>::new(0).unwrap() $op &<$ty>::new(1).unwrap();
169 *&mut <$ty>::new(0).unwrap() $op_assign 1;
170 *&mut <$ty>::new(0).unwrap() $op_assign &1;
171 *&mut <$ty>::new(0).unwrap() $op_assign <$ty>::new(1).unwrap();
172 *&mut <$ty>::new(0).unwrap() $op_assign &<$ty>::new(1).unwrap();
173 *&mut 0 $op_assign <$ty>::new(1).unwrap();
174 *&mut 0 $op_assign &<$ty>::new(1).unwrap();
175 )*
176 };
177 }
178 use variations;
179 }
180
181 #[test]
182 fn saturating() {
183 type Bounded = BoundedI8<-5, 20>;
184 assert_eq!(Bounded::new(13).unwrap().saturating_add(1).get(), 14);
185 assert_eq!(Bounded::new(14).unwrap().saturating_add(7).get(), 20);
186 assert_eq!(Bounded::new(-2).unwrap().saturating_sub(-1).get(), -1);
187 assert_eq!(Bounded::new(-2).unwrap().saturating_sub(127).get(), -5);
188 assert_eq!(Bounded::new(2).unwrap().saturating_mul(3).get(), 6);
189 assert_eq!(Bounded::new(15).unwrap().saturating_mul(-1).get(), -5);
190 assert_eq!(Bounded::new(3).unwrap().saturating_pow(2).get(), 9);
191 assert_eq!(Bounded::new(3).unwrap().saturating_pow(3).get(), 20);
192 assert_eq!(Bounded::new(-4).unwrap().saturating_neg().get(), 4);
193 assert_eq!(Bounded::new(8).unwrap().saturating_neg().get(), -5);
194 assert_eq!(Bounded::new(8).unwrap().saturating_abs().get(), 8);
195 assert_eq!(<BoundedI8<-20, 5>>::new(-6).unwrap().saturating_abs(), 5);
196 }
197
198 #[test]
199 fn checked() {
200 type Bounded = BoundedI8<-5, 20>;
201 assert_eq!(Bounded::new(13).unwrap().checked_add(2).unwrap().get(), 15);
202 assert_eq!(Bounded::new(14).unwrap().checked_add(7), None);
203 assert_eq!(Bounded::new(-2).unwrap().checked_sub(-1).unwrap().get(), -1);
204 assert_eq!(Bounded::new(-2).unwrap().checked_sub(127), None);
205 assert_eq!(Bounded::new(2).unwrap().checked_mul(3).unwrap().get(), 6);
206 assert_eq!(Bounded::new(15).unwrap().checked_mul(-1), None);
207 assert_eq!(Bounded::new(3).unwrap().checked_pow(2).unwrap().get(), 9);
208 assert_eq!(Bounded::new(3).unwrap().checked_pow(3), None);
209 assert_eq!(Bounded::new(2).unwrap().checked_shl(3).unwrap().get(), 16);
210 assert_eq!(Bounded::new(3).unwrap().checked_shl(3), None);
211 assert_eq!(Bounded::new(9).unwrap().checked_shr(2).unwrap().get(), 2);
212 assert_eq!(<BoundedI8<4, 8>>::new(8).unwrap().checked_shr(2), None);
213 assert_eq!(Bounded::new(11).unwrap().checked_div(3).unwrap().get(), 3);
214 assert_eq!(Bounded::new(11).unwrap().checked_rem(3).unwrap().get(), 2);
215 assert_eq!(<BoundedI8<4, 11>>::new(11).unwrap().checked_div(3), None);
216 assert_eq!(<BoundedI8<4, 11>>::new(11).unwrap().checked_rem(3), None);
217 assert_eq!(Bounded::new(11).unwrap().checked_div_euclid(3).unwrap(), 3);
218 assert_eq!(Bounded::new(11).unwrap().checked_rem_euclid(3).unwrap(), 2);
219 assert_eq!(
220 <BoundedI8<4, 11>>::new(11).unwrap().checked_div_euclid(3),
221 None
222 );
223 assert_eq!(
224 <BoundedI8<4, 11>>::new(11).unwrap().checked_rem_euclid(3),
225 None
226 );
227 assert_eq!(Bounded::new(-3).unwrap().checked_neg().unwrap().get(), 3);
228 assert_eq!(Bounded::new(6).unwrap().checked_neg(), None);
229 assert_eq!(Bounded::new(-3).unwrap().checked_abs().unwrap().get(), 3);
230 assert_eq!(Bounded::new(6).unwrap().checked_abs().unwrap().get(), 6);
231 assert_eq!(<BoundedI8<-20, 5>>::new(-6).unwrap().checked_abs(), None);
232 }
233
234 #[test]
235 fn wrapping() {
236 type Bounded = BoundedI8<-5, 20>;
237 assert_eq!(Bounded::new(0).unwrap().wrapping_add(0).get(), 0);
238 assert_eq!(Bounded::new(-5).unwrap().wrapping_add(-128), -3);
239 assert_eq!(Bounded::new(-5).unwrap().wrapping_sub(127), -2);
240 assert_eq!(Bounded::new(20).unwrap().wrapping_add(127), 17);
241 assert_eq!(Bounded::new(15).unwrap().wrapping_mul(17), -5);
242 assert_eq!(Bounded::new(-5).unwrap().wrapping_div(2), -2);
243 assert_eq!(Bounded::new(-5).unwrap().wrapping_rem(2), -1);
244 assert_eq!(Bounded::new(-5).unwrap().wrapping_div_euclid(2), -3);
245 assert_eq!(Bounded::new(-5).unwrap().wrapping_rem_euclid(2), 1);
246 assert_eq!(Bounded::new(-5).unwrap().wrapping_neg(), 5);
247 assert_eq!(Bounded::new(6).unwrap().wrapping_neg(), 20);
248 assert_eq!(Bounded::new(-5).unwrap().wrapping_abs(), 5);
249 assert_eq!(Bounded::new(6).unwrap().wrapping_abs(), 6);
250 assert_eq!(<BoundedI8<-20, 5>>::new(-6).unwrap().wrapping_abs(), -20);
251 assert_eq!(Bounded::new(5).unwrap().wrapping_pow(607), -5);
252 }
253
254 #[test]
255 fn wrapping_div() {
256 type Bounded = BoundedI32<{ i32::MIN }, -1>;
257 assert_eq!(Bounded::new(i32::MIN).unwrap().wrapping_div(-1), i32::MIN);
258 }
259
260 #[test]
261 fn iter() {
262 type Bounded = BoundedI8<-8, 8>;
263 #[expect(clippy::trivially_copy_pass_by_ref)]
264 fn b(&n: &i8) -> Bounded {
265 Bounded::new(n).unwrap()
266 }
267 assert_eq!([3, 2, 1].iter().map(b).sum::<Bounded>().get(), 6);
268 assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<Bounded>().get(), 5);
269 assert_eq!([7, 6, 4].iter().map(b).sum::<i8>(), 17);
270 assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<i8>(), 5);
271
272 assert_eq!([1, 3, 2, 1].iter().map(b).product::<Bounded>().get(), 6);
273 assert_eq!([1, 3, 2, 1, 0].iter().map(b).product::<Bounded>().get(), 0);
274 assert_eq!([-2, -3, -1].iter().map(b).product::<Bounded>().get(), -6);
275 assert_eq!([3, 3].iter().map(b).product::<i8>(), 9);
276 }
277
278 #[test]
279 fn parse() {
280 use crate::ParseErrorKind::*;
281
282 type Bounded = BoundedI8<3, 11>;
283
284 assert_eq!("3".parse::<Bounded>().unwrap().get(), 3);
285 assert_eq!("10".parse::<Bounded>().unwrap().get(), 10);
286 assert_eq!("+11".parse::<Bounded>().unwrap().get(), 11);
287 assert_eq!(Bounded::from_str_radix("1010", 2).unwrap().get(), 10);
288 assert_eq!(Bounded::from_str_radix("B", 0xC).unwrap().get(), 11);
289 assert_eq!(Bounded::from_str_radix("11", 7).unwrap().get(), 8);
290 assert_eq!(Bounded::from_str_radix("7", 36).unwrap().get(), 7);
291
292 assert_eq!("".parse::<Bounded>().unwrap_err().kind(), NoDigits);
293 assert_eq!("+".parse::<Bounded>().unwrap_err().kind(), NoDigits);
294 assert_eq!("-".parse::<Bounded>().unwrap_err().kind(), NoDigits);
295 assert_eq!("2".parse::<Bounded>().unwrap_err().kind(), BelowMin);
296 assert_eq!("12".parse::<Bounded>().unwrap_err().kind(), AboveMax);
297 assert_eq!("-5".parse::<Bounded>().unwrap_err().kind(), BelowMin);
298 assert_eq!("128".parse::<Bounded>().unwrap_err().kind(), AboveMax);
299 assert_eq!("-129".parse::<Bounded>().unwrap_err().kind(), BelowMin);
300
301 assert_eq!("++0".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
302 assert_eq!("--0".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
303 assert_eq!("O".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
304 assert_eq!("C".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
305 assert_eq!(
306 Bounded::from_str_radix("3", 2).unwrap_err().kind(),
307 InvalidDigit
308 );
309 }
310
311 #[test]
312 #[cfg(feature = "alloc")]
313 fn fmt() {
314 use alloc::format;
315 use alloc::string::ToString;
316 type Bounded = BoundedU8<3, 210>;
317 assert_eq!(Bounded::new(3).unwrap().to_string(), "3");
318 assert_eq!(format!("{:b}", Bounded::new(5).unwrap()), "101");
319 assert_eq!(format!("{:x}", Bounded::new(200).unwrap()), "c8");
320 assert_eq!(format!("{:X}", Bounded::new(200).unwrap()), "C8");
321 assert_eq!(format!("{:o}", Bounded::new(200).unwrap()), "310");
322 }
323
324 #[test]
325 fn default() {
326 assert_eq!(<BoundedU8<0, 5>>::default().get(), 0);
327 }
328
329 #[test]
330 fn conversions() {
331 assert_eq!(i8::from(<BoundedI8<1, 5>>::new(3).unwrap()), 3);
332 assert_eq!(i16::from(<BoundedI8<1, 5>>::new(3).unwrap()), 3);
333 assert_eq!(i32::from(<BoundedI8<1, 5>>::new(3).unwrap()), 3);
334 assert_eq!(u32::from(<BoundedU32<1, 5>>::new(3).unwrap()), 3);
335 assert_eq!(i64::from(<BoundedU32<1, 5>>::new(3).unwrap()), 3);
336 assert_eq!(usize::from(<BoundedU16<1, 5>>::new(3).unwrap()), 3);
337 assert_eq!(
338 u8::try_from(<BoundedI8<-5, 5>>::new(3).unwrap()).unwrap(),
339 3
340 );
341 u8::try_from(<BoundedI8<-5, 5>>::new(-1).unwrap()).unwrap_err();
342 assert_eq!(<BoundedI8<2, 5>>::try_from(3_u16).unwrap(), 3);
343 <BoundedI8<2, 5>>::try_from(8_u16).unwrap_err();
344 }
345
346 #[test]
347 #[cfg(feature = "num-traits02")]
348 #[expect(clippy::too_many_lines)]
349 fn num() {
350 use num_traits02::{
351 AsPrimitive, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem,
352 CheckedShl, CheckedShr, CheckedSub, FromPrimitive, NumCast, ToPrimitive,
353 };
354
355 type B = BoundedI8<2, 8>;
356 type BNeg = BoundedI8<-4, 8>;
357
358 fn b(n: i8) -> B {
359 B::new(n).unwrap()
360 }
361
362 fn bneg(n: i8) -> BNeg {
363 BNeg::new(n).unwrap()
364 }
365
366 assert_eq!(B::min_value(), 2);
367 assert_eq!(B::max_value(), 8);
368
369 assert_eq!(BNeg::min_value(), -4);
370 assert_eq!(BNeg::max_value(), 8);
371
372 assert_eq!(<B as AsPrimitive<u8>>::as_(b(4)), 4u8);
373 assert_eq!(<B as AsPrimitive<u16>>::as_(b(4)), 4u16);
374 assert_eq!(<B as AsPrimitive<u32>>::as_(b(4)), 4u32);
375 assert_eq!(<B as AsPrimitive<u64>>::as_(b(4)), 4u64);
376 assert_eq!(<B as AsPrimitive<u128>>::as_(b(4)), 4u128);
377 assert_eq!(<B as AsPrimitive<usize>>::as_(b(4)), 4usize);
378 assert_eq!(<B as AsPrimitive<i8>>::as_(b(4)), 4i8);
379 assert_eq!(<B as AsPrimitive<i16>>::as_(b(4)), 4i16);
380 assert_eq!(<B as AsPrimitive<i32>>::as_(b(4)), 4i32);
381 assert_eq!(<B as AsPrimitive<i64>>::as_(b(4)), 4i64);
382 assert_eq!(<B as AsPrimitive<i128>>::as_(b(4)), 4i128);
383 assert_eq!(<B as AsPrimitive<isize>>::as_(b(4)), 4isize);
384 #[expect(clippy::float_cmp)]
385 let () = assert_eq!(<B as AsPrimitive<f32>>::as_(b(4)), 4f32);
386 #[expect(clippy::float_cmp)]
387 let () = assert_eq!(<B as AsPrimitive<f64>>::as_(b(4)), 4f64);
388
389 assert_eq!(B::from_u8(4u8), Some(b(4)));
390 assert_eq!(B::from_u16(4u16), Some(b(4)));
391 assert_eq!(B::from_u32(4u32), Some(b(4)));
392 assert_eq!(B::from_u64(4u64), Some(b(4)));
393 assert_eq!(B::from_u128(4u128), Some(b(4)));
394 assert_eq!(B::from_usize(4usize), Some(b(4)));
395 assert_eq!(B::from_i8(4i8), Some(b(4)));
396 assert_eq!(B::from_i16(4i16), Some(b(4)));
397 assert_eq!(B::from_i32(4i32), Some(b(4)));
398 assert_eq!(B::from_i64(4i64), Some(b(4)));
399 assert_eq!(B::from_i128(4i128), Some(b(4)));
400 assert_eq!(B::from_isize(4isize), Some(b(4)));
401 assert_eq!(B::from_f32(4f32), Some(b(4)));
402 assert_eq!(B::from_f64(4f64), Some(b(4)));
403
404 assert_eq!(B::from_u8(16u8), None);
405 assert_eq!(B::from_u16(16u16), None);
406 assert_eq!(B::from_u32(16u32), None);
407 assert_eq!(B::from_u64(16u64), None);
408 assert_eq!(B::from_u128(16u128), None);
409 assert_eq!(B::from_usize(16usize), None);
410 assert_eq!(B::from_i8(16i8), None);
411 assert_eq!(B::from_i16(16i16), None);
412 assert_eq!(B::from_i32(16i32), None);
413 assert_eq!(B::from_i64(16i64), None);
414 assert_eq!(B::from_i128(16i128), None);
415 assert_eq!(B::from_isize(16isize), None);
416 assert_eq!(B::from_f32(16f32), None);
417 assert_eq!(B::from_f64(16f64), None);
418
419 assert_eq!(<B as NumCast>::from(4u8), Some(b(4)));
420 assert_eq!(<B as NumCast>::from(4u16), Some(b(4)));
421 assert_eq!(<B as NumCast>::from(4u32), Some(b(4)));
422 assert_eq!(<B as NumCast>::from(4u64), Some(b(4)));
423 assert_eq!(<B as NumCast>::from(4u128), Some(b(4)));
424 assert_eq!(<B as NumCast>::from(4usize), Some(b(4)));
425 assert_eq!(<B as NumCast>::from(4i8), Some(b(4)));
426 assert_eq!(<B as NumCast>::from(4i16), Some(b(4)));
427 assert_eq!(<B as NumCast>::from(4i32), Some(b(4)));
428 assert_eq!(<B as NumCast>::from(4i64), Some(b(4)));
429 assert_eq!(<B as NumCast>::from(4i128), Some(b(4)));
430 assert_eq!(<B as NumCast>::from(4isize), Some(b(4)));
431 assert_eq!(<B as NumCast>::from(4f32), Some(b(4)));
432 assert_eq!(<B as NumCast>::from(4f64), Some(b(4)));
433
434 assert_eq!(<B as NumCast>::from(16u8), None);
435 assert_eq!(<B as NumCast>::from(16u16), None);
436 assert_eq!(<B as NumCast>::from(16u32), None);
437 assert_eq!(<B as NumCast>::from(16u64), None);
438 assert_eq!(<B as NumCast>::from(16u128), None);
439 assert_eq!(<B as NumCast>::from(16usize), None);
440 assert_eq!(<B as NumCast>::from(16i8), None);
441 assert_eq!(<B as NumCast>::from(16i16), None);
442 assert_eq!(<B as NumCast>::from(16i32), None);
443 assert_eq!(<B as NumCast>::from(16i64), None);
444 assert_eq!(<B as NumCast>::from(16i128), None);
445 assert_eq!(<B as NumCast>::from(16isize), None);
446 assert_eq!(<B as NumCast>::from(16f32), None);
447 assert_eq!(<B as NumCast>::from(16f64), None);
448
449 assert_eq!(b(4).to_u8(), Some(4u8));
450 assert_eq!(b(4).to_u16(), Some(4u16));
451 assert_eq!(b(4).to_u32(), Some(4u32));
452 assert_eq!(b(4).to_u64(), Some(4u64));
453 assert_eq!(b(4).to_u128(), Some(4u128));
454 assert_eq!(b(4).to_usize(), Some(4usize));
455 assert_eq!(b(4).to_i8(), Some(4i8));
456 assert_eq!(b(4).to_i16(), Some(4i16));
457 assert_eq!(b(4).to_i32(), Some(4i32));
458 assert_eq!(b(4).to_i64(), Some(4i64));
459 assert_eq!(b(4).to_i128(), Some(4i128));
460 assert_eq!(b(4).to_isize(), Some(4isize));
461 assert_eq!(b(4).to_f32(), Some(4f32));
462 assert_eq!(b(4).to_f64(), Some(4f64));
463
464 assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(4)), Some(b(8)));
465 assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(8)), None);
466
467 assert_eq!(<B as CheckedDiv>::checked_div(&b(8), &b(2)), Some(b(4)));
468 assert_eq!(<B as CheckedDiv>::checked_div(&b(4), &b(4)), None);
469
470 assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(2)), Some(b(4)));
471 assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(8)), None);
472
473 assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(2)), Some(bneg(-2)));
474
475 assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(8)), None);
476
477 assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(6)), Some(b(2)));
478 assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(7)), None);
479
480 assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(2)), Some(b(2)));
481 assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(4)), None);
482
483 assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 1u32), Some(b(8)));
484 assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 2u32), None);
485
486 assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 1u32), Some(b(2)));
487 assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 2u32), None);
488 }
489}