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 = "schemars1")]
348 fn schemars() {
349 use schemars1::{generate::SchemaSettings, schema_for};
350 use serde_json1::json;
351
352 let meta = SchemaSettings::default().meta_schema.unwrap();
353
354 assert_eq!(
355 schema_for!(BoundedU16<10, 20>),
356 json!({
357 "$schema": meta,
358 "type": "integer",
359 "title": "uint16",
360 "format": "uint16",
361 "minimum": 10,
362 "maximum": 20,
363 })
364 );
365
366 assert_eq!(
367 schema_for!(BoundedI32<-8, 8>),
368 json!({
369 "$schema": meta,
370 "type": "integer",
371 "title": "int32",
372 "format": "int32",
373 "minimum": -8,
374 "maximum": 8,
375 })
376 );
377
378 assert_eq!(
379 schema_for!(BoundedI128<-0x1_0000_0000_0000_0000, 0x1_0000_0000_0000_0000>),
380 json!({
381 "$schema": meta,
382 "type": "integer",
383 "title": "int128",
384 "format": "int128",
385 })
386 );
387 }
388
389 #[test]
390 #[cfg(feature = "num-traits02")]
391 #[expect(clippy::too_many_lines)]
392 fn num() {
393 use num_traits02::{
394 AsPrimitive, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem,
395 CheckedShl, CheckedShr, CheckedSub, FromPrimitive, NumCast, ToPrimitive,
396 };
397
398 type B = BoundedI8<2, 8>;
399 type BNeg = BoundedI8<-4, 8>;
400
401 fn b(n: i8) -> B {
402 B::new(n).unwrap()
403 }
404
405 fn bneg(n: i8) -> BNeg {
406 BNeg::new(n).unwrap()
407 }
408
409 assert_eq!(B::min_value(), 2);
410 assert_eq!(B::max_value(), 8);
411
412 assert_eq!(BNeg::min_value(), -4);
413 assert_eq!(BNeg::max_value(), 8);
414
415 assert_eq!(<B as AsPrimitive<u8>>::as_(b(4)), 4u8);
416 assert_eq!(<B as AsPrimitive<u16>>::as_(b(4)), 4u16);
417 assert_eq!(<B as AsPrimitive<u32>>::as_(b(4)), 4u32);
418 assert_eq!(<B as AsPrimitive<u64>>::as_(b(4)), 4u64);
419 assert_eq!(<B as AsPrimitive<u128>>::as_(b(4)), 4u128);
420 assert_eq!(<B as AsPrimitive<usize>>::as_(b(4)), 4usize);
421 assert_eq!(<B as AsPrimitive<i8>>::as_(b(4)), 4i8);
422 assert_eq!(<B as AsPrimitive<i16>>::as_(b(4)), 4i16);
423 assert_eq!(<B as AsPrimitive<i32>>::as_(b(4)), 4i32);
424 assert_eq!(<B as AsPrimitive<i64>>::as_(b(4)), 4i64);
425 assert_eq!(<B as AsPrimitive<i128>>::as_(b(4)), 4i128);
426 assert_eq!(<B as AsPrimitive<isize>>::as_(b(4)), 4isize);
427 #[expect(clippy::float_cmp)]
428 let () = assert_eq!(<B as AsPrimitive<f32>>::as_(b(4)), 4f32);
429 #[expect(clippy::float_cmp)]
430 let () = assert_eq!(<B as AsPrimitive<f64>>::as_(b(4)), 4f64);
431
432 assert_eq!(B::from_u8(4u8), Some(b(4)));
433 assert_eq!(B::from_u16(4u16), Some(b(4)));
434 assert_eq!(B::from_u32(4u32), Some(b(4)));
435 assert_eq!(B::from_u64(4u64), Some(b(4)));
436 assert_eq!(B::from_u128(4u128), Some(b(4)));
437 assert_eq!(B::from_usize(4usize), Some(b(4)));
438 assert_eq!(B::from_i8(4i8), Some(b(4)));
439 assert_eq!(B::from_i16(4i16), Some(b(4)));
440 assert_eq!(B::from_i32(4i32), Some(b(4)));
441 assert_eq!(B::from_i64(4i64), Some(b(4)));
442 assert_eq!(B::from_i128(4i128), Some(b(4)));
443 assert_eq!(B::from_isize(4isize), Some(b(4)));
444 assert_eq!(B::from_f32(4f32), Some(b(4)));
445 assert_eq!(B::from_f64(4f64), Some(b(4)));
446
447 assert_eq!(B::from_u8(16u8), None);
448 assert_eq!(B::from_u16(16u16), None);
449 assert_eq!(B::from_u32(16u32), None);
450 assert_eq!(B::from_u64(16u64), None);
451 assert_eq!(B::from_u128(16u128), None);
452 assert_eq!(B::from_usize(16usize), None);
453 assert_eq!(B::from_i8(16i8), None);
454 assert_eq!(B::from_i16(16i16), None);
455 assert_eq!(B::from_i32(16i32), None);
456 assert_eq!(B::from_i64(16i64), None);
457 assert_eq!(B::from_i128(16i128), None);
458 assert_eq!(B::from_isize(16isize), None);
459 assert_eq!(B::from_f32(16f32), None);
460 assert_eq!(B::from_f64(16f64), None);
461
462 assert_eq!(<B as NumCast>::from(4u8), Some(b(4)));
463 assert_eq!(<B as NumCast>::from(4u16), Some(b(4)));
464 assert_eq!(<B as NumCast>::from(4u32), Some(b(4)));
465 assert_eq!(<B as NumCast>::from(4u64), Some(b(4)));
466 assert_eq!(<B as NumCast>::from(4u128), Some(b(4)));
467 assert_eq!(<B as NumCast>::from(4usize), Some(b(4)));
468 assert_eq!(<B as NumCast>::from(4i8), Some(b(4)));
469 assert_eq!(<B as NumCast>::from(4i16), Some(b(4)));
470 assert_eq!(<B as NumCast>::from(4i32), Some(b(4)));
471 assert_eq!(<B as NumCast>::from(4i64), Some(b(4)));
472 assert_eq!(<B as NumCast>::from(4i128), Some(b(4)));
473 assert_eq!(<B as NumCast>::from(4isize), Some(b(4)));
474 assert_eq!(<B as NumCast>::from(4f32), Some(b(4)));
475 assert_eq!(<B as NumCast>::from(4f64), Some(b(4)));
476
477 assert_eq!(<B as NumCast>::from(16u8), None);
478 assert_eq!(<B as NumCast>::from(16u16), None);
479 assert_eq!(<B as NumCast>::from(16u32), None);
480 assert_eq!(<B as NumCast>::from(16u64), None);
481 assert_eq!(<B as NumCast>::from(16u128), None);
482 assert_eq!(<B as NumCast>::from(16usize), None);
483 assert_eq!(<B as NumCast>::from(16i8), None);
484 assert_eq!(<B as NumCast>::from(16i16), None);
485 assert_eq!(<B as NumCast>::from(16i32), None);
486 assert_eq!(<B as NumCast>::from(16i64), None);
487 assert_eq!(<B as NumCast>::from(16i128), None);
488 assert_eq!(<B as NumCast>::from(16isize), None);
489 assert_eq!(<B as NumCast>::from(16f32), None);
490 assert_eq!(<B as NumCast>::from(16f64), None);
491
492 assert_eq!(b(4).to_u8(), Some(4u8));
493 assert_eq!(b(4).to_u16(), Some(4u16));
494 assert_eq!(b(4).to_u32(), Some(4u32));
495 assert_eq!(b(4).to_u64(), Some(4u64));
496 assert_eq!(b(4).to_u128(), Some(4u128));
497 assert_eq!(b(4).to_usize(), Some(4usize));
498 assert_eq!(b(4).to_i8(), Some(4i8));
499 assert_eq!(b(4).to_i16(), Some(4i16));
500 assert_eq!(b(4).to_i32(), Some(4i32));
501 assert_eq!(b(4).to_i64(), Some(4i64));
502 assert_eq!(b(4).to_i128(), Some(4i128));
503 assert_eq!(b(4).to_isize(), Some(4isize));
504 assert_eq!(b(4).to_f32(), Some(4f32));
505 assert_eq!(b(4).to_f64(), Some(4f64));
506
507 assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(4)), Some(b(8)));
508 assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(8)), None);
509
510 assert_eq!(<B as CheckedDiv>::checked_div(&b(8), &b(2)), Some(b(4)));
511 assert_eq!(<B as CheckedDiv>::checked_div(&b(4), &b(4)), None);
512
513 assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(2)), Some(b(4)));
514 assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(8)), None);
515
516 assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(2)), Some(bneg(-2)));
517
518 assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(8)), None);
519
520 assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(6)), Some(b(2)));
521 assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(7)), None);
522
523 assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(2)), Some(b(2)));
524 assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(4)), None);
525
526 assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 1u32), Some(b(8)));
527 assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 2u32), None);
528
529 assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 1u32), Some(b(2)));
530 assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 2u32), None);
531 }
532}