bounded_integer/types/
mod.rs

1macro_rules! bin_op_variations {
2    ([$($generics:tt)*] $lhs:ty, $rhs:ty, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident) => {
3        impl<$($generics)*> $op<$rhs> for &$lhs {
4            type Output = $lhs;
5            #[inline]
6            fn $method(self, rhs: $rhs) -> Self::Output {
7                <$lhs as $op<$rhs>>::$method(*self, rhs)
8            }
9        }
10        impl<$($generics)*> $op<&$rhs> for $lhs {
11            type Output = $lhs;
12            #[inline]
13            fn $method(self, rhs: &$rhs) -> Self::Output {
14                <$lhs as $op<$rhs>>::$method(self, *rhs)
15            }
16        }
17        impl<$($generics)*> $op<&$rhs> for &$lhs {
18            type Output = $lhs;
19            #[inline]
20            fn $method(self, rhs: &$rhs) -> Self::Output {
21                <$lhs as $op<$rhs>>::$method(*self, *rhs)
22            }
23        }
24
25        impl<$($generics)*> $op_assign<$rhs> for $lhs {
26            #[inline]
27            fn $method_assign(&mut self, rhs: $rhs) {
28                *self = <Self as $op<$rhs>>::$method(*self, rhs);
29            }
30        }
31        impl<$($generics)*> $op_assign<&$rhs> for $lhs {
32            #[inline]
33            fn $method_assign(&mut self, rhs: &$rhs) {
34                *self = <Self as $op<$rhs>>::$method(*self, *rhs);
35            }
36        }
37    }
38}
39
40macro_rules! impl_bin_op {
41    ($op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal) => {
42        use core::ops::{$op, $op_assign};
43
44        impl<const MIN: Inner, const MAX: Inner> $op<Inner> for Bounded<MIN, MAX> {
45            type Output = Self;
46            #[inline]
47            fn $method(self, rhs: Inner) -> Self::Output {
48                Self::new(self.get().$method(rhs))
49                    .expect(concat!("Attempted to ", $desc, " out of range"))
50            }
51        }
52        bin_op_variations!(
53            [const MIN: Inner, const MAX: Inner]
54            Bounded<MIN, MAX>, Inner, $op::$method/$op_assign::$method_assign
55        );
56
57        impl<const MIN: Inner, const MAX: Inner> $op<Bounded<MIN, MAX>> for Inner {
58            type Output = Self;
59            #[inline]
60            fn $method(self, rhs: Bounded<MIN, MAX>) -> Self::Output {
61                self.$method(rhs.get())
62            }
63        }
64        bin_op_variations! {
65            [const MIN: Inner, const MAX: Inner]
66            Inner, Bounded<MIN, MAX>, $op::$method/$op_assign::$method_assign
67        }
68
69        impl<const L_MIN: Inner, const L_MAX: Inner, const R_MIN: Inner, const R_MAX: Inner>
70            $op<Bounded<R_MIN, R_MAX>> for Bounded<L_MIN, L_MAX>
71        {
72            type Output = Self;
73             #[inline]
74            fn $method(self, rhs: Bounded<R_MIN, R_MAX>) -> Self::Output {
75                Self::new(self.get().$method(rhs))
76                    .expect(concat!("Attempted to ", $desc, " out of range"))
77            }
78        }
79        bin_op_variations! {
80            [const L_MIN: Inner, const L_MAX: Inner, const R_MIN: Inner, const R_MAX: Inner]
81            Bounded<L_MIN, L_MAX>, Bounded<R_MIN, R_MAX>, $op::$method/$op_assign::$method_assign
82        }
83    };
84}
85
86macro_rules! impl_shift_bin_op {
87    (u32, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal) => {
88        impl_bin_op!($op::$method/$op_assign::$method_assign, $desc);
89    };
90    ($inner:ident, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal) => {
91        impl_bin_op!($op::$method/$op_assign::$method_assign, $desc);
92
93        // Implementation used by checked shift operations
94        impl<const MIN: Inner, const MAX: Inner> $op<u32> for Bounded<MIN, MAX> {
95            type Output = Self;
96            #[inline]
97            fn $method(self, rhs: u32) -> Self::Output {
98                Self::new(self.get().$method(rhs))
99                    .expect(concat!("Attempted to ", $desc, " out of range"))
100            }
101        }
102        bin_op_variations!(
103            [const MIN: Inner, const MAX: Inner]
104            Bounded<MIN, MAX>, u32, $op::$method/$op_assign::$method_assign
105        );
106    };
107}
108
109#[cfg(test)]
110macro_rules! test_arithmetic {
111    (ops($($op:tt $op_assign:tt)*) infallibles($($infallible:ident)*) fallibles($($fallible:ident)*)) => {
112        $( #[allow(const_item_mutation)] {
113            let _: Bounded = Bounded::MIN $op 0;
114            let _: Bounded = &Bounded::MIN $op 0;
115            let _: Bounded = Bounded::MIN $op &0;
116            let _: Bounded = &Bounded::MIN $op &0;
117            let _: Inner = 0 $op Bounded::MIN;
118            let _: Inner = 0 $op &Bounded::MIN;
119            let _: Inner = &0 $op Bounded::MIN;
120            let _: Inner = &0 $op &Bounded::MIN;
121            let _: Bounded = Bounded::MIN $op Bounded::MIN;
122            let _: Bounded = &Bounded::MIN $op Bounded::MIN;
123            let _: Bounded = Bounded::MIN $op &Bounded::MIN;
124            let _: Bounded = &Bounded::MIN $op &Bounded::MIN;
125            *&mut Bounded::MIN $op_assign 0;
126            *&mut Bounded::MIN $op_assign &0;
127            *&mut Bounded::MIN $op_assign Bounded::MIN;
128            *&mut Bounded::MIN $op_assign &Bounded::MIN;
129            *&mut 0 $op_assign Bounded::MIN;
130            *&mut 0 $op_assign &Bounded::MIN;
131        } )*
132        $(let _: Bounded = Bounded::MIN.$infallible(0);)*
133        $(let _: Option<Bounded> = Bounded::MIN.$fallible(0);)*
134        let _: Option<Bounded> = Bounded::MIN.checked_neg();
135    };
136    (signed $($tt:tt)*) => {
137        test_arithmetic!($($tt)*);
138
139        let _: Bounded = Bounded::MIN.abs();
140        let _: Option<Bounded> = Bounded::MIN.checked_abs();
141
142        let _: Bounded = -Bounded::MIN;
143        let _: Bounded = -&Bounded::MIN;
144        let _: Bounded = Bounded::MIN.saturating_neg();
145    };
146}
147
148macro_rules! impl_fmt_traits {
149    ($($trait:ident),*) => { $(
150        impl<const MIN: Inner, const MAX: Inner> fmt::$trait for Bounded<MIN, MAX> {
151            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152                fmt::$trait::fmt(&self.get(), f)
153            }
154        }
155    )* }
156}
157
158macro_rules! define_bounded_integers {
159    ($(
160        $name:ident $inner:ident $(signed $([$signed:ident])?)? -> $($into:ident)*,
161    )*) => { $( mod $inner {
162        use core::borrow::Borrow;
163        use core::cmp;
164        use core::fmt;
165        use core::iter;
166        use core::str::FromStr;
167
168        use crate::parse::{ParseError, FromStrRadix};
169
170        type Inner = core::primitive::$inner;
171
172        #[doc = "An"]
173        #[doc = concat!("[`", stringify!($inner), "`]")]
174        #[doc = "constrained to be in the range `MIN..=MAX`."]
175        #[cfg_attr(doc_cfg, doc(cfg(feature = "types")))]
176        #[repr(transparent)]
177        #[derive(Debug, Hash, Clone, Copy, Eq, Ord)]
178        #[cfg_attr(feature = "zerocopy", derive(zerocopy::IntoBytes))]
179        pub struct Bounded<const MIN: Inner, const MAX: Inner>(Inner);
180
181        impl<const MIN: Inner, const MAX: Inner> Bounded<MIN, MAX> {
182            /// The smallest value this bounded integer can contain.
183            pub const MIN_VALUE: Inner = MIN;
184            /// The largest value that this bounded integer can contain.
185            pub const MAX_VALUE: Inner = MAX;
186
187            /// The smallest value of the bounded integer.
188            pub const MIN: Self = Self(MIN);
189            /// The largest value of the bounded integer.
190            pub const MAX: Self = Self(MAX);
191
192            /// Creates a bounded integer without checking the value.
193            ///
194            /// # Safety
195            ///
196            /// The value must not be outside the valid range of values; it must not be less than
197            /// [`MIN_VALUE`](Self::MIN_VALUE) or greater than [`MAX_VALUE`](Self::MAX_VALUE).
198            #[must_use]
199            pub const unsafe fn new_unchecked(n: Inner) -> Self {
200                // Doesn't work in `const fn`:
201                // debug_assert!(Self::in_range(n));
202                Self(n)
203            }
204
205            /// Creates a shared reference to a bounded integer from a shared reference to a
206            /// primitive.
207            ///
208            /// # Safety
209            ///
210            /// The value must not be outside the valid range of values; it must not be less than
211            /// [`MIN_VALUE`](Self::MIN_VALUE) or greater than [`MAX_VALUE`](Self::MAX_VALUE).
212            #[must_use]
213            pub unsafe fn new_ref_unchecked(n: &Inner) -> &Self {
214                debug_assert!(Self::in_range(*n));
215                &*<*const _>::cast(n)
216            }
217
218            /// Creates a mutable reference to a bounded integer from a mutable reference to a
219            /// primitive.
220            ///
221            /// # Safety
222            ///
223            /// The value must not be outside the valid range of values; it must not be less than
224            /// [`MIN_VALUE`](Self::MIN_VALUE) or greater than [`MAX_VALUE`](Self::MAX_VALUE).
225            #[must_use]
226            pub unsafe fn new_mut_unchecked(n: &mut Inner) -> &mut Self {
227                debug_assert!(Self::in_range(*n));
228                &mut *<*mut _>::cast(n)
229            }
230
231            /// Checks whether the given value is in the range of the bounded integer.
232            #[must_use]
233            #[inline]
234            pub const fn in_range(n: Inner) -> bool {
235                n >= Self::MIN_VALUE && n <= Self::MAX_VALUE
236            }
237
238            /// Creates a bounded integer if the given value is within the range
239            /// [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
240            #[must_use]
241            #[inline]
242            pub const fn new(n: Inner) -> Option<Self> {
243                if Self::in_range(n) {
244                    Some(Self(n))
245                } else {
246                    None
247                }
248            }
249
250            /// Creates a reference to a bounded integer from a reference to a primitive if the
251            /// given value is within the range [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
252            #[must_use]
253            #[inline]
254            pub fn new_ref(n: &Inner) -> Option<&Self> {
255                Self::in_range(*n).then(|| {
256                    // SAFETY: We just asserted that the value is in range.
257                    unsafe { Self::new_ref_unchecked(n) }
258                })
259            }
260
261            /// Creates a mutable reference to a bounded integer from a mutable reference to a
262            /// primitive if the given value is within the range
263            /// [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
264            #[must_use]
265            #[inline]
266            pub fn new_mut(n: &mut Inner) -> Option<&mut Self> {
267                Self::in_range(*n).then(move || {
268                    // SAFETY: We just asserted that the value is in range.
269                    unsafe { Self::new_mut_unchecked(n) }
270                })
271            }
272
273            /// Creates a bounded integer by setting the value to [`MIN`](Self::MIN) or
274            /// [`MAX`](Self::MAX) if it is too low or too high respectively.
275            #[must_use]
276            #[inline]
277            pub const fn new_saturating(n: Inner) -> Self {
278                if n < Self::MIN_VALUE {
279                    Self::MIN
280                } else if n > Self::MAX_VALUE {
281                    Self::MAX
282                } else {
283                    Self(n)
284                }
285            }
286
287            /// Converts a string slice in a given base to the bounded integer.
288            ///
289            /// # Panics
290            ///
291            /// Panics if `radix` is below 2 or above 36.
292            pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseError> {
293                let value = <Inner as FromStrRadix>::from_str_radix(src, radix)?;
294                if value < Self::MIN_VALUE {
295                    Err(crate::parse::error_below_min())
296                } else if value > Self::MAX_VALUE {
297                    Err(crate::parse::error_above_max())
298                } else {
299                    Ok(unsafe { Self::new_unchecked(value) })
300                }
301            }
302
303            /// Returns the value of the bounded integer as a primitive type.
304            #[must_use]
305            #[inline]
306            pub const fn get(self) -> Inner {
307                self.0
308            }
309
310            /// Returns a shared reference to the value of the bounded integer.
311            #[must_use]
312            #[inline]
313            pub const fn get_ref(&self) -> &Inner {
314                &self.0
315            }
316
317            /// Returns a mutable reference to the value of the bounded integer.
318            ///
319            /// # Safety
320            ///
321            /// This value must never be set to a value beyond the range of the bounded integer.
322            #[must_use]
323            #[inline]
324            pub unsafe fn get_mut(&mut self) -> &mut Inner {
325                &mut *<*mut _>::cast(self)
326            }
327
328            $($(if $signed)?
329                /// Computes the absolute value of `self`, panicking if it is out of range.
330                #[must_use]
331                #[inline]
332                pub fn abs(self) -> Self {
333                    Self::new(self.get().abs()).expect("Absolute value out of range")
334                }
335            )*
336
337            /// Raises `self` to the power of `exp`, using exponentiation by squaring. Panics if it
338            /// is out of range.
339            #[must_use]
340            #[inline]
341            pub fn pow(self, exp: u32) -> Self {
342                Self::new(self.get().pow(exp)).expect("Value raised to power out of range")
343            }
344
345            /// Calculates the quotient of Euclidean division of `self` by `rhs`. Panics if `rhs`
346            /// is 0 or the result is out of range.
347            #[must_use]
348            #[inline]
349            pub fn div_euclid(self, rhs: Inner) -> Self {
350                Self::new(self.get().div_euclid(rhs)).expect("Attempted to divide out of range")
351            }
352
353            /// Calculates the least nonnegative remainder of `self (mod rhs)`. Panics if `rhs` is 0
354            /// or the result is out of range.
355            #[must_use]
356            #[inline]
357            pub fn rem_euclid(self, rhs: Inner) -> Self {
358                Self::new(self.get().rem_euclid(rhs))
359                    .expect("Attempted to divide with remainder out of range")
360            }
361
362            /// Checked integer addition.
363            #[must_use]
364            #[inline]
365            pub const fn checked_add(self, rhs: Inner) -> Option<Self> {
366                match self.get().checked_add(rhs) {
367                    Some(val) => Self::new(val),
368                    None => None,
369                }
370            }
371
372            /// Saturating integer addition.
373            #[must_use]
374            #[inline]
375            pub const fn saturating_add(self, rhs: Inner) -> Self {
376                Self::new_saturating(self.get().saturating_add(rhs))
377            }
378
379            /// Checked integer subtraction.
380            #[must_use]
381            #[inline]
382            pub const fn checked_sub(self, rhs: Inner) -> Option<Self> {
383                match self.get().checked_sub(rhs) {
384                    Some(val) => Self::new(val),
385                    None => None,
386                }
387            }
388
389            /// Saturating integer subtraction.
390            #[must_use]
391            #[inline]
392            pub const fn saturating_sub(self, rhs: Inner) -> Self {
393                Self::new_saturating(self.get().saturating_sub(rhs))
394            }
395
396            /// Checked integer multiplication.
397            #[must_use]
398            #[inline]
399            pub const fn checked_mul(self, rhs: Inner) -> Option<Self> {
400                match self.get().checked_mul(rhs) {
401                    Some(val) => Self::new(val),
402                    None => None,
403                }
404            }
405
406            /// Saturating integer multiplication.
407            #[must_use]
408            #[inline]
409            pub const fn saturating_mul(self, rhs: Inner) -> Self {
410                Self::new_saturating(self.get().saturating_mul(rhs))
411            }
412
413            /// Checked integer division.
414            #[must_use]
415            #[inline]
416            pub const fn checked_div(self, rhs: Inner) -> Option<Self> {
417                match self.get().checked_div(rhs) {
418                    Some(val) => Self::new(val),
419                    None => None,
420                }
421            }
422
423            /// Checked Euclidean division.
424            #[must_use]
425            #[inline]
426            pub const fn checked_div_euclid(self, rhs: Inner) -> Option<Self> {
427                match self.get().checked_div_euclid(rhs) {
428                    Some(val) => Self::new(val),
429                    None => None,
430                }
431            }
432
433            /// Checked integer remainder.
434            #[must_use]
435            #[inline]
436            pub const fn checked_rem(self, rhs: Inner) -> Option<Self> {
437                match self.get().checked_rem(rhs) {
438                    Some(val) => Self::new(val),
439                    None => None,
440                }
441            }
442
443            /// Checked Euclidean remainder.
444            #[must_use]
445            #[inline]
446            pub const fn checked_rem_euclid(self, rhs: Inner) -> Option<Self> {
447                match self.get().checked_rem_euclid(rhs) {
448                    Some(val) => Self::new(val),
449                    None => None,
450                }
451            }
452
453            /// Checked negation.
454            #[must_use]
455            #[inline]
456            pub const fn checked_neg(self) -> Option<Self> {
457                match self.get().checked_neg() {
458                    Some(val) => Self::new(val),
459                    None => None,
460                }
461            }
462
463            $($(if $signed)?
464                /// Saturating negation.
465                #[must_use]
466                #[inline]
467                pub const fn saturating_neg(self) -> Self {
468                    Self::new_saturating(self.get().saturating_neg())
469                }
470
471                /// Checked absolute value.
472                #[must_use]
473                #[inline]
474                pub const fn checked_abs(self) -> Option<Self> {
475                    match self.get().checked_abs() {
476                        Some(val) => Self::new(val),
477                        None => None,
478                    }
479                }
480
481                /// Saturating absolute value.
482                #[must_use]
483                #[inline]
484                pub const fn saturating_abs(self) -> Self {
485                    Self::new_saturating(self.get().saturating_abs())
486                }
487            )*
488
489            /// Checked exponentiation.
490            #[must_use]
491            #[inline]
492            pub const fn checked_pow(self, rhs: u32) -> Option<Self> {
493                match self.get().checked_pow(rhs) {
494                    Some(val) => Self::new(val),
495                    None => None,
496                }
497            }
498
499            /// Saturating exponentiation.
500            #[must_use]
501            #[inline]
502            pub const fn saturating_pow(self, rhs: u32) -> Self {
503                Self::new_saturating(self.get().saturating_pow(rhs))
504            }
505
506            /// Checked shift left.
507            #[must_use]
508            #[inline]
509            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
510                match self.get().checked_shl(rhs) {
511                    Some(val) => Self::new(val),
512                    None => None,
513                }
514            }
515
516            /// Checked shift right.
517            #[must_use]
518            #[inline]
519            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
520                match self.get().checked_shr(rhs) {
521                    Some(val) => Self::new(val),
522                    None => None,
523                }
524            }
525        }
526
527        // === Operators ===
528
529        impl_bin_op!(Add::add/AddAssign::add_assign, "add");
530        impl_bin_op!(Sub::sub/SubAssign::sub_assign, "subtract");
531        impl_bin_op!(Mul::mul/MulAssign::mul_assign, "multiply");
532        impl_bin_op!(Div::div/DivAssign::div_assign, "divide");
533        impl_bin_op!(Rem::rem/RemAssign::rem_assign, "take remainder");
534        impl_bin_op!(BitAnd::bitand/BitAndAssign::bitand_assign, "binary and");
535        impl_bin_op!(BitOr::bitor/BitOrAssign::bitor_assign, "binary or");
536        impl_bin_op!(BitXor::bitxor/BitXorAssign::bitxor_assign, "binary xor");
537        impl_shift_bin_op!($inner, Shl::shl/ShlAssign::shl_assign, "shift left");
538        impl_shift_bin_op!($inner, Shr::shr/ShrAssign::shr_assign, "shift right");
539
540        $($(if $signed)?
541            use core::ops::Neg;
542
543            impl<const MIN: Inner, const MAX: Inner> Neg for Bounded<MIN, MAX> {
544                type Output = Self;
545                #[inline]
546                fn neg(self) -> Self::Output {
547                    Self::new(-self.get())
548                        .expect("Attempted to negate out of range")
549                }
550            }
551            impl<const MIN: Inner, const MAX: Inner> Neg for &Bounded<MIN, MAX> {
552                type Output = Bounded<MIN, MAX>;
553                #[inline]
554                fn neg(self) -> Self::Output {
555                    -*self
556                }
557            }
558        )?
559
560        use core::ops::Not;
561
562        impl<const MIN: Inner, const MAX: Inner> Not for Bounded<MIN, MAX> {
563            type Output = Self;
564            #[inline]
565            fn not(self) -> Self::Output {
566                Self::new(!self.get())
567                    .expect("Attempted to negate out of range")
568            }
569        }
570        impl<const MIN: Inner, const MAX: Inner> Not for &Bounded<MIN, MAX> {
571            type Output = Bounded<MIN, MAX>;
572            #[inline]
573            fn not(self) -> Self::Output {
574                !*self
575            }
576        }
577
578        // === Comparisons ===
579
580        impl<const MIN: Inner, const MAX: Inner> PartialEq<Inner> for Bounded<MIN, MAX> {
581            #[inline]
582            fn eq(&self, other: &Inner) -> bool {
583                self.get() == *other
584            }
585        }
586        impl<const MIN: Inner, const MAX: Inner> PartialEq<Bounded<MIN, MAX>> for Inner {
587            #[inline]
588            fn eq(&self, other: &Bounded<MIN, MAX>) -> bool {
589                *self == other.get()
590            }
591        }
592        impl<const A_MIN: Inner, const A_MAX: Inner, const B_MIN: Inner, const B_MAX: Inner>
593            PartialEq<Bounded<B_MIN, B_MAX>> for Bounded<A_MIN, A_MAX>
594        {
595            #[inline]
596            fn eq(&self, other: &Bounded<B_MIN, B_MAX>) -> bool {
597                self.get() == other.get()
598            }
599        }
600
601        impl<const MIN: Inner, const MAX: Inner> PartialOrd<Inner> for Bounded<MIN, MAX> {
602            #[inline]
603            fn partial_cmp(&self, other: &Inner) -> Option<cmp::Ordering> {
604                self.get().partial_cmp(other)
605            }
606        }
607        impl<const MIN: Inner, const MAX: Inner> PartialOrd<Bounded<MIN, MAX>> for Inner {
608            #[inline]
609            fn partial_cmp(&self, other: &Bounded<MIN, MAX>) -> Option<cmp::Ordering> {
610                self.partial_cmp(&other.get())
611            }
612        }
613        impl<const A_MIN: Inner, const A_MAX: Inner, const B_MIN: Inner, const B_MAX: Inner>
614            PartialOrd<Bounded<B_MIN, B_MAX>> for Bounded<A_MIN, A_MAX>
615        {
616            #[inline]
617            fn partial_cmp(&self, other: &Bounded<B_MIN, B_MAX>) -> Option<cmp::Ordering> {
618                self.get().partial_cmp(&other.get())
619            }
620        }
621
622        // === AsRef, Borrow ===
623
624        impl<const MIN: Inner, const MAX: Inner> AsRef<Inner> for Bounded<MIN, MAX> {
625            #[inline]
626            fn as_ref(&self) -> &Inner {
627                self.get_ref()
628            }
629        }
630        impl<const MIN: Inner, const MAX: Inner> Borrow<Inner> for Bounded<MIN, MAX> {
631            #[inline]
632            fn borrow(&self) -> &Inner {
633                self.get_ref()
634            }
635        }
636
637        // === Iterator traits ===
638
639        // Sum bounded to bounded
640        impl<const MIN: Inner, const MAX: Inner> iter::Sum for Bounded<MIN, MAX> {
641            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
642                iter.reduce(Add::add)
643                    .unwrap_or_else(|| Self::new(0).expect("Attempted to sum to zero"))
644            }
645        }
646        impl<'a, const MIN: Inner, const MAX: Inner> iter::Sum<&'a Self> for Bounded<MIN, MAX> {
647            fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
648                iter.copied().sum()
649            }
650        }
651
652        // Sum bounded to primitive
653        impl<const MIN: Inner, const MAX: Inner> iter::Sum<Bounded<MIN, MAX>> for Inner {
654            fn sum<I: Iterator<Item = Bounded<MIN, MAX>>>(iter: I) -> Self {
655                iter.map(Bounded::get).sum()
656            }
657        }
658        impl<'a, const MIN: Inner, const MAX: Inner> iter::Sum<&'a Bounded<MIN, MAX>> for Inner {
659            fn sum<I: Iterator<Item = &'a Bounded<MIN, MAX>>>(iter: I) -> Self {
660                iter.copied().sum()
661            }
662        }
663
664        // Take product of bounded to bounded
665        impl<const MIN: Inner, const MAX: Inner> iter::Product for Bounded<MIN, MAX> {
666            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
667                iter.reduce(Mul::mul)
668                    .unwrap_or_else(|| Self::new(1).expect("Attempted to take product to one"))
669            }
670        }
671        impl<'a, const MIN: Inner, const MAX: Inner> iter::Product<&'a Self> for Bounded<MIN, MAX> {
672            fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
673                iter.copied().product()
674            }
675        }
676
677        // Take product of bounded to primitive
678        impl<const MIN: Inner, const MAX: Inner> iter::Product<Bounded<MIN, MAX>> for Inner {
679            fn product<I: Iterator<Item = Bounded<MIN, MAX>>>(iter: I) -> Self {
680                iter.map(Bounded::get).product()
681            }
682        }
683        impl<'a, const MIN: Inner, const MAX: Inner> iter::Product<&'a Bounded<MIN, MAX>> for Inner {
684            fn product<I: Iterator<Item = &'a Bounded<MIN, MAX>>>(iter: I) -> Self {
685                iter.copied().product()
686            }
687        }
688
689        #[cfg(feature = "step_trait")]
690        #[cfg_attr(doc_cfg, doc(cfg(feature = "step_trait")))]
691        impl<const MIN: Inner, const MAX: Inner> iter::Step for Bounded<MIN, MAX> {
692            #[inline]
693            fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
694                iter::Step::steps_between(&start.get(), &end.get())
695            }
696            #[inline]
697            fn forward_checked(start: Self, count: usize) -> Option<Self> {
698                iter::Step::forward_checked(start.get(), count).and_then(Self::new)
699            }
700            #[inline]
701            fn backward_checked(start: Self, count: usize) -> Option<Self> {
702                iter::Step::backward_checked(start.get(), count).and_then(Self::new)
703            }
704        }
705
706        // === Parsing ===
707
708        impl<const MIN: Inner, const MAX: Inner> FromStr for Bounded<MIN, MAX> {
709            type Err = ParseError;
710
711            fn from_str(s: &str) -> Result<Self, Self::Err> {
712                Self::from_str_radix(s, 10)
713            }
714        }
715
716        // === Formatting ===
717
718        impl_fmt_traits!(Binary, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex);
719
720        // === Arbitrary ===
721
722        #[cfg(feature = "arbitrary1")]
723        use arbitrary1::{Arbitrary, Unstructured};
724
725        #[cfg(feature = "arbitrary1")]
726        #[cfg_attr(doc_cfg, doc(cfg(feature = "arbitrary1")))]
727        impl<'a, const MIN: Inner, const MAX: Inner> Arbitrary<'a> for Bounded<MIN, MAX> {
728            fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary1::Result<Self> {
729                Self::new(u.arbitrary()?).ok_or(arbitrary1::Error::IncorrectFormat)
730            }
731
732            #[inline]
733            fn size_hint(depth: usize) -> (usize, Option<usize>) {
734                <Inner as Arbitrary<'a>>::size_hint(depth)
735            }
736        }
737
738        // === Bytemuck ===
739
740        #[cfg(feature = "bytemuck1")]
741        #[cfg_attr(doc_cfg, doc(cfg(feature = "bytemuck1")))]
742        unsafe impl<const MIN: Inner, const MAX: Inner> bytemuck1::Contiguous for Bounded<MIN, MAX> {
743            type Int = Inner;
744            const MAX_VALUE: Inner = MAX;
745            const MIN_VALUE: Inner = MIN;
746        }
747
748        // === Num ===
749
750        #[cfg(feature = "num-traits02")]
751        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
752        impl<const MIN: Inner, const MAX: Inner> num_traits02::Bounded for Bounded<MIN, MAX> {
753            fn min_value() -> Self {
754                Self::MIN
755            }
756
757            fn max_value() -> Self {
758                Self::MAX
759            }
760        }
761
762        #[cfg(feature = "num-traits02")]
763        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
764        impl<T, const MIN: Inner, const MAX: Inner> num_traits02::AsPrimitive<T>
765            for Bounded<MIN, MAX>
766        where
767            Inner: num_traits02::AsPrimitive<T>,
768            T: 'static + Copy,
769        {
770            fn as_(self) -> T {
771                self.get().as_()
772            }
773        }
774
775        #[cfg(feature = "num-traits02")]
776        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
777        impl<const MIN: Inner, const MAX: Inner> num_traits02::FromPrimitive for Bounded<MIN, MAX>
778        where
779            Inner: num_traits02::FromPrimitive,
780        {
781            fn from_i64(n: i64) -> Option<Self> {
782                Inner::from_i64(n)
783                    .map(Self::new)
784                    .flatten()
785            }
786
787            fn from_u64(n: u64) -> Option<Self> {
788                Inner::from_u64(n)
789                    .map(Self::new)
790                    .flatten()
791            }
792
793            fn from_isize(n: isize) -> Option<Self> {
794                Inner::from_isize(n)
795                    .map(Self::new)
796                    .flatten()
797            }
798
799            fn from_i8(n: i8) -> Option<Self> {
800                Inner::from_i8(n)
801                    .map(Self::new)
802                    .flatten()
803            }
804
805            fn from_i16(n: i16) -> Option<Self> {
806                Inner::from_i16(n)
807                    .map(Self::new)
808                    .flatten()
809            }
810
811            fn from_i32(n: i32) -> Option<Self> {
812                Inner::from_i32(n)
813                    .map(Self::new)
814                    .flatten()
815            }
816
817            fn from_i128(n: i128) -> Option<Self> {
818                Inner::from_i128(n)
819                    .map(Self::new)
820                    .flatten()
821            }
822
823            fn from_usize(n: usize) -> Option<Self> {
824                Inner::from_usize(n)
825                    .map(Self::new)
826                    .flatten()
827            }
828
829            fn from_u8(n: u8) -> Option<Self> {
830                Inner::from_u8(n)
831                    .map(Self::new)
832                    .flatten()
833            }
834
835            fn from_u16(n: u16) -> Option<Self> {
836                Inner::from_u16(n)
837                    .map(Self::new)
838                    .flatten()
839            }
840
841            fn from_u32(n: u32) -> Option<Self> {
842                Inner::from_u32(n)
843                    .map(Self::new)
844                    .flatten()
845            }
846
847            fn from_u128(n: u128) -> Option<Self> {
848                Inner::from_u128(n)
849                    .map(Self::new)
850                    .flatten()
851            }
852
853            fn from_f32(n: f32) -> Option<Self> {
854                Inner::from_f32(n)
855                    .map(Self::new)
856                    .flatten()
857            }
858
859            fn from_f64(n: f64) -> Option<Self> {
860                Inner::from_f64(n)
861                    .map(Self::new)
862                    .flatten()
863            }
864        }
865
866        #[cfg(feature = "num-traits02")]
867        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
868        impl<const MIN: Inner, const MAX: Inner> num_traits02::NumCast for Bounded<MIN, MAX>
869        where
870            Inner: num_traits02::NumCast,
871        {
872            fn from<T: num_traits02::ToPrimitive>(n: T) -> Option<Self> {
873                <Inner as num_traits02::NumCast>::from(n).map(Self::new).flatten()
874            }
875        }
876
877        #[cfg(feature = "num-traits02")]
878        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
879        impl<const MIN: Inner, const MAX: Inner> num_traits02::ToPrimitive for Bounded<MIN, MAX>
880        where
881            Inner: num_traits02::ToPrimitive,
882        {
883            fn to_i64(&self) -> Option<i64> {
884                self.get().to_i64()
885            }
886
887            fn to_u64(&self) -> Option<u64> {
888                self.get().to_u64()
889            }
890
891            fn to_isize(&self) -> Option<isize> {
892                self.get().to_isize()
893            }
894
895            fn to_i8(&self) -> Option<i8> {
896                self.get().to_i8()
897            }
898
899            fn to_i16(&self) -> Option<i16> {
900                self.get().to_i16()
901            }
902
903            fn to_i32(&self) -> Option<i32> {
904                self.get().to_i32()
905            }
906
907            fn to_i128(&self) -> Option<i128> {
908                self.get().to_i128()
909            }
910
911            fn to_usize(&self) -> Option<usize> {
912                self.get().to_usize()
913            }
914
915            fn to_u8(&self) -> Option<u8> {
916                self.get().to_u8()
917            }
918
919            fn to_u16(&self) -> Option<u16> {
920                self.get().to_u16()
921            }
922
923            fn to_u32(&self) -> Option<u32> {
924                self.get().to_u32()
925            }
926
927            fn to_u128(&self) -> Option<u128> {
928                self.get().to_u128()
929            }
930
931            fn to_f32(&self) -> Option<f32> {
932                self.get().to_f32()
933            }
934
935            fn to_f64(&self) -> Option<f64> {
936                self.get().to_f64()
937            }
938        }
939
940        #[cfg(feature = "num-traits02")]
941        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
942        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedAdd for Bounded<MIN, MAX> {
943            fn checked_add(&self, v: &Self) -> Option<Self> {
944                Self::checked_add(*self, v.get())
945            }
946        }
947
948        #[cfg(feature = "num-traits02")]
949        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
950        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedDiv for Bounded<MIN, MAX> {
951            fn checked_div(&self, v: &Self) -> Option<Self> {
952                Self::checked_div(*self, v.get())
953            }
954        }
955
956        #[cfg(feature = "num-traits02")]
957        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
958        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedMul for Bounded<MIN, MAX> {
959            fn checked_mul(&self, v: &Self) -> Option<Self> {
960                Self::checked_mul(*self, v.get())
961            }
962        }
963
964        #[cfg(feature = "num-traits02")]
965        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
966        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedNeg for Bounded<MIN, MAX> {
967            fn checked_neg(&self) -> Option<Self> {
968                Self::checked_neg(*self)
969            }
970        }
971
972        #[cfg(feature = "num-traits02")]
973        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
974        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedRem for Bounded<MIN, MAX> {
975            fn checked_rem(&self, v: &Self) -> Option<Self> {
976                Self::checked_rem(*self, v.get())
977            }
978        }
979
980        #[cfg(feature = "num-traits02")]
981        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
982        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedShl for Bounded<MIN, MAX> {
983            fn checked_shl(&self, v: u32) -> Option<Self> {
984                Self::checked_shl(*self, v)
985            }
986        }
987
988        #[cfg(feature = "num-traits02")]
989        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
990        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedShr for Bounded<MIN, MAX> {
991            fn checked_shr(&self, v: u32) -> Option<Self> {
992                Self::checked_shr(*self, v)
993            }
994        }
995
996        #[cfg(feature = "num-traits02")]
997        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
998        impl<const MIN: Inner, const MAX: Inner> num_traits02::CheckedSub for Bounded<MIN, MAX> {
999            fn checked_sub(&self, v: &Self) -> Option<Self> {
1000                Self::checked_sub(*self, v.get())
1001            }
1002        }
1003
1004        #[cfg(feature = "num-traits02")]
1005        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
1006        impl<A, B, const MIN: Inner, const MAX: Inner> num_traits02::MulAdd<A, B>
1007            for Bounded<MIN, MAX>
1008        where
1009            Inner: num_traits02::MulAdd<A, B, Output = Inner>,
1010        {
1011            type Output = Inner;
1012
1013            fn mul_add(self, a: A, b: B) -> Self::Output {
1014                self.get().mul_add(a, b)
1015            }
1016        }
1017
1018        #[cfg(feature = "num-traits02")]
1019        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
1020        impl<const MIN: Inner, const MAX: Inner> num_traits02::SaturatingAdd for Bounded<MIN, MAX> {
1021            fn saturating_add(&self, v: &Self) -> Self {
1022                Self::saturating_add(*self, v.get())
1023            }
1024        }
1025
1026        #[cfg(feature = "num-traits02")]
1027        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
1028        impl<const MIN: Inner, const MAX: Inner> num_traits02::SaturatingMul for Bounded<MIN, MAX> {
1029            fn saturating_mul(&self, v: &Self) -> Self {
1030                Self::saturating_mul(*self, v.get())
1031            }
1032        }
1033
1034        #[cfg(feature = "num-traits02")]
1035        #[cfg_attr(doc_cfg, doc(cfg(feature = "num-traits02")))]
1036        impl<const MIN: Inner, const MAX: Inner> num_traits02::SaturatingSub for Bounded<MIN, MAX> {
1037            fn saturating_sub(&self, v: &Self) -> Self {
1038                Self::saturating_sub(*self, v.get())
1039            }
1040        }
1041
1042        // === Serde ===
1043
1044        #[cfg(feature = "serde1")]
1045        use serde1::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
1046
1047        #[cfg(feature = "serde1")]
1048        #[cfg_attr(doc_cfg, doc(cfg(feature = "serde1")))]
1049        impl<const MIN: Inner, const MAX: Inner> Serialize for Bounded<MIN, MAX> {
1050            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1051                self.get().serialize(serializer)
1052            }
1053        }
1054
1055        #[cfg(feature = "serde1")]
1056        #[cfg_attr(doc_cfg, doc(cfg(feature = "serde1")))]
1057        impl<'de, const MIN: Inner, const MAX: Inner> Deserialize<'de> for Bounded<MIN, MAX> {
1058            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1059                Self::new(Inner::deserialize(deserializer)?)
1060                    .ok_or_else(|| {
1061                        D::Error::custom(format_args!(
1062                            "integer out of range, expected it to be between {} and {}",
1063                            Self::MIN_VALUE,
1064                            Self::MAX_VALUE,
1065                        ))
1066                    })
1067            }
1068        }
1069
1070        // === Conversions ===
1071
1072        $(impl<const MIN: Inner, const MAX: Inner> From<Bounded<MIN, MAX>> for $into {
1073            fn from(bounded: Bounded<MIN, MAX>) -> Self {
1074                Self::from(bounded.get())
1075            }
1076        })*
1077
1078        // === Tests ===
1079
1080        #[cfg(test)]
1081        mod tests {
1082            use super::Inner;
1083
1084            #[cfg(feature = "std")]
1085            use std::format;
1086
1087            #[test]
1088            fn range() {
1089                type Bounded = super::Bounded<3, 10>;
1090                assert_eq!(Bounded::MIN_VALUE, 3);
1091                assert_eq!(Bounded::MAX_VALUE, 10);
1092                assert_eq!(Bounded::MIN.get(), Bounded::MIN_VALUE);
1093                assert_eq!(Bounded::MAX.get(), Bounded::MAX_VALUE);
1094
1095                assert!(Bounded::in_range(3));
1096                assert!(!Bounded::in_range(2));
1097                assert!(Bounded::in_range(10));
1098                assert!(!Bounded::in_range(11));
1099            }
1100
1101            #[test]
1102            fn saturating() {
1103                type Bounded = super::Bounded<3, 10>;
1104                assert_eq!(Bounded::new_saturating(Inner::MIN), Bounded::MIN);
1105                assert_eq!(Bounded::new_saturating(Inner::MAX), Bounded::MAX);
1106                assert_eq!(Bounded::new_saturating(11).get(), 10);
1107                assert_eq!(Bounded::new_saturating(10).get(), 10);
1108                assert_eq!(Bounded::new_saturating(3).get(), 3);
1109                assert_eq!(Bounded::new_saturating(2).get(), 3);
1110            }
1111
1112            #[test]
1113            fn arithmetic() {
1114                if false {
1115                    type Bounded = super::Bounded<0, 15>;
1116                    test_arithmetic! {
1117                        $($(if $signed)? signed)?
1118                        ops(+ += - -= * *= / /= % %=)
1119                        infallibles(
1120                            pow
1121                            div_euclid
1122                            rem_euclid
1123                            saturating_add
1124                            saturating_sub
1125                            saturating_mul
1126                            saturating_pow
1127                        )
1128                        fallibles(
1129                            checked_add
1130                            checked_sub
1131                            checked_mul
1132                            checked_div
1133                            checked_div_euclid
1134                            checked_rem
1135                            checked_rem_euclid
1136                            checked_pow
1137                            checked_shl
1138                            checked_shr
1139                        )
1140                    }
1141                }
1142            }
1143
1144            #[test]
1145            fn iter() {
1146                type Bounded = super::Bounded<{ 0 $($(if $signed)? - 8)? }, 8>;
1147
1148                fn b(&n: &Inner) -> Bounded {
1149                    Bounded::new(n).unwrap()
1150                }
1151
1152                assert_eq!([3, 2, 1].iter().map(b).sum::<Bounded>().get(), 6);
1153                $($(if $signed)? assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<Bounded>().get(), 5);)?
1154                assert_eq!([7, 6, 4].iter().map(b).sum::<Inner>(), 17);
1155                $($(if $signed)? assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<Inner>(), 5);)?
1156
1157                assert_eq!([1, 3, 2, 1].iter().map(b).product::<Bounded>().get(), 6);
1158                assert_eq!([1, 3, 2, 1, 0].iter().map(b).product::<Bounded>().get(), 0);
1159                $($(if $signed)? assert_eq!([-2, -3, -1].iter().map(b).product::<Bounded>().get(), -6);)?
1160                assert_eq!([3, 3].iter().map(b).product::<Inner>(), 9);
1161            }
1162
1163            #[test]
1164            fn parse() {
1165                use crate::ParseErrorKind::*;
1166
1167                type Bounded = super::Bounded<3, 11>;
1168
1169                assert_eq!("3".parse::<Bounded>().unwrap().get(), 3);
1170                assert_eq!("10".parse::<Bounded>().unwrap().get(), 10);
1171                assert_eq!("+11".parse::<Bounded>().unwrap().get(), 11);
1172                assert_eq!(Bounded::from_str_radix("1010", 2).unwrap().get(), 10);
1173                assert_eq!(Bounded::from_str_radix("B", 0xC).unwrap().get(), 11);
1174                assert_eq!(Bounded::from_str_radix("11", 7).unwrap().get(), 8);
1175                assert_eq!(Bounded::from_str_radix("7", 36).unwrap().get(), 7);
1176
1177                assert_eq!("".parse::<Bounded>().unwrap_err().kind(), NoDigits);
1178                assert_eq!("+".parse::<Bounded>().unwrap_err().kind(), NoDigits);
1179                assert_eq!("-".parse::<Bounded>().unwrap_err().kind(), NoDigits);
1180                assert_eq!("2".parse::<Bounded>().unwrap_err().kind(), BelowMin);
1181                assert_eq!("12".parse::<Bounded>().unwrap_err().kind(), AboveMax);
1182                assert_eq!("-5".parse::<Bounded>().unwrap_err().kind(), BelowMin);
1183                #[cfg(feature = "std")]
1184                assert_eq!(
1185                    format!("{}00", Inner::MAX).parse::<Bounded>().unwrap_err().kind(),
1186                    AboveMax
1187                );
1188                #[cfg(feature = "std")]
1189                assert_eq!(
1190                    format!("{}00", Inner::MIN).parse::<Bounded>().unwrap_err().kind(),
1191                    BelowMin
1192                );
1193
1194                assert_eq!("++0".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
1195                assert_eq!("--0".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
1196                assert_eq!("O".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
1197                assert_eq!("C".parse::<Bounded>().unwrap_err().kind(), InvalidDigit);
1198                assert_eq!(Bounded::from_str_radix("3", 2).unwrap_err().kind(), InvalidDigit);
1199            }
1200
1201            #[test]
1202            #[cfg(feature = "num-traits02")]
1203            fn num() {
1204                use num_traits02::{
1205                    Bounded, AsPrimitive, FromPrimitive, NumCast, ToPrimitive, CheckedAdd,
1206                    CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub, CheckedShl, CheckedShr
1207                };
1208
1209                type B = super::Bounded<2, 8>;
1210                type BNeg = super::Bounded<{0 $($(if $signed)? - 4)?}, 8>;
1211
1212                fn b(n: Inner) -> B {
1213                    B::new(n).unwrap()
1214                }
1215
1216                fn bneg(n: Inner) -> BNeg {
1217                    BNeg::new(n).unwrap()
1218                }
1219
1220                assert_eq!(B::min_value(), 2);
1221                assert_eq!(B::max_value(), 8);
1222
1223                assert_eq!(BNeg::min_value(), 0 $($(if $signed)? - 4)?);
1224                assert_eq!(BNeg::max_value(), 8);
1225
1226                assert_eq!(<B as AsPrimitive<u8>>::as_(b(4)), 4u8);
1227                assert_eq!(<B as AsPrimitive<u16>>::as_(b(4)), 4u16);
1228                assert_eq!(<B as AsPrimitive<u32>>::as_(b(4)), 4u32);
1229                assert_eq!(<B as AsPrimitive<u64>>::as_(b(4)), 4u64);
1230                assert_eq!(<B as AsPrimitive<u128>>::as_(b(4)), 4u128);
1231                assert_eq!(<B as AsPrimitive<usize>>::as_(b(4)), 4usize);
1232                assert_eq!(<B as AsPrimitive<i8>>::as_(b(4)), 4i8);
1233                assert_eq!(<B as AsPrimitive<i16>>::as_(b(4)), 4i16);
1234                assert_eq!(<B as AsPrimitive<i32>>::as_(b(4)), 4i32);
1235                assert_eq!(<B as AsPrimitive<i64>>::as_(b(4)), 4i64);
1236                assert_eq!(<B as AsPrimitive<i128>>::as_(b(4)), 4i128);
1237                assert_eq!(<B as AsPrimitive<isize>>::as_(b(4)), 4isize);
1238                assert_eq!(<B as AsPrimitive<f32>>::as_(b(4)), 4f32);
1239                assert_eq!(<B as AsPrimitive<f64>>::as_(b(4)), 4f64);
1240
1241                assert_eq!(B::from_u8(4u8), Some(b(4)));
1242                assert_eq!(B::from_u16(4u16), Some(b(4)));
1243                assert_eq!(B::from_u32(4u32), Some(b(4)));
1244                assert_eq!(B::from_u64(4u64), Some(b(4)));
1245                assert_eq!(B::from_u128(4u128), Some(b(4)));
1246                assert_eq!(B::from_usize(4usize), Some(b(4)));
1247                assert_eq!(B::from_i8(4i8), Some(b(4)));
1248                assert_eq!(B::from_i16(4i16), Some(b(4)));
1249                assert_eq!(B::from_i32(4i32), Some(b(4)));
1250                assert_eq!(B::from_i64(4i64), Some(b(4)));
1251                assert_eq!(B::from_i128(4i128), Some(b(4)));
1252                assert_eq!(B::from_isize(4isize), Some(b(4)));
1253                assert_eq!(B::from_f32(4f32), Some(b(4)));
1254                assert_eq!(B::from_f64(4f64), Some(b(4)));
1255
1256                assert_eq!(B::from_u8(16u8), None);
1257                assert_eq!(B::from_u16(16u16), None);
1258                assert_eq!(B::from_u32(16u32), None);
1259                assert_eq!(B::from_u64(16u64), None);
1260                assert_eq!(B::from_u128(16u128), None);
1261                assert_eq!(B::from_usize(16usize), None);
1262                assert_eq!(B::from_i8(16i8), None);
1263                assert_eq!(B::from_i16(16i16), None);
1264                assert_eq!(B::from_i32(16i32), None);
1265                assert_eq!(B::from_i64(16i64), None);
1266                assert_eq!(B::from_i128(16i128), None);
1267                assert_eq!(B::from_isize(16isize), None);
1268                assert_eq!(B::from_f32(16f32), None);
1269                assert_eq!(B::from_f64(16f64), None);
1270
1271                assert_eq!(<B as NumCast>::from(4u8), Some(b(4)));
1272                assert_eq!(<B as NumCast>::from(4u16), Some(b(4)));
1273                assert_eq!(<B as NumCast>::from(4u32), Some(b(4)));
1274                assert_eq!(<B as NumCast>::from(4u64), Some(b(4)));
1275                assert_eq!(<B as NumCast>::from(4u128), Some(b(4)));
1276                assert_eq!(<B as NumCast>::from(4usize), Some(b(4)));
1277                assert_eq!(<B as NumCast>::from(4i8), Some(b(4)));
1278                assert_eq!(<B as NumCast>::from(4i16), Some(b(4)));
1279                assert_eq!(<B as NumCast>::from(4i32), Some(b(4)));
1280                assert_eq!(<B as NumCast>::from(4i64), Some(b(4)));
1281                assert_eq!(<B as NumCast>::from(4i128), Some(b(4)));
1282                assert_eq!(<B as NumCast>::from(4isize), Some(b(4)));
1283                assert_eq!(<B as NumCast>::from(4f32), Some(b(4)));
1284                assert_eq!(<B as NumCast>::from(4f64), Some(b(4)));
1285
1286                assert_eq!(<B as NumCast>::from(16u8), None);
1287                assert_eq!(<B as NumCast>::from(16u16), None);
1288                assert_eq!(<B as NumCast>::from(16u32), None);
1289                assert_eq!(<B as NumCast>::from(16u64), None);
1290                assert_eq!(<B as NumCast>::from(16u128), None);
1291                assert_eq!(<B as NumCast>::from(16usize), None);
1292                assert_eq!(<B as NumCast>::from(16i8), None);
1293                assert_eq!(<B as NumCast>::from(16i16), None);
1294                assert_eq!(<B as NumCast>::from(16i32), None);
1295                assert_eq!(<B as NumCast>::from(16i64), None);
1296                assert_eq!(<B as NumCast>::from(16i128), None);
1297                assert_eq!(<B as NumCast>::from(16isize), None);
1298                assert_eq!(<B as NumCast>::from(16f32), None);
1299                assert_eq!(<B as NumCast>::from(16f64), None);
1300
1301                assert_eq!(b(4).to_u8(), Some(4u8));
1302                assert_eq!(b(4).to_u16(), Some(4u16));
1303                assert_eq!(b(4).to_u32(), Some(4u32));
1304                assert_eq!(b(4).to_u64(), Some(4u64));
1305                assert_eq!(b(4).to_u128(), Some(4u128));
1306                assert_eq!(b(4).to_usize(), Some(4usize));
1307                assert_eq!(b(4).to_i8(), Some(4i8));
1308                assert_eq!(b(4).to_i16(), Some(4i16));
1309                assert_eq!(b(4).to_i32(), Some(4i32));
1310                assert_eq!(b(4).to_i64(), Some(4i64));
1311                assert_eq!(b(4).to_i128(), Some(4i128));
1312                assert_eq!(b(4).to_isize(), Some(4isize));
1313                assert_eq!(b(4).to_f32(), Some(4f32));
1314                assert_eq!(b(4).to_f64(), Some(4f64));
1315
1316                assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(4)), Some(b(8)));
1317                assert_eq!(<B as CheckedAdd>::checked_add(&b(4), &b(8)), None);
1318
1319                assert_eq!(<B as CheckedDiv>::checked_div(&b(8), &b(2)), Some(b(4)));
1320                assert_eq!(<B as CheckedDiv>::checked_div(&b(4), &b(4)), None);
1321
1322                assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(2)), Some(b(4)));
1323                assert_eq!(<B as CheckedMul>::checked_mul(&b(2), &b(8)), None);
1324
1325                $($(if $signed)? {
1326                    assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(2)), Some(bneg(-2)));
1327                })?
1328
1329                assert_eq!(<BNeg as CheckedNeg>::checked_neg(&bneg(8)), None);
1330
1331                assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(6)), Some(b(2)));
1332                assert_eq!(<B as CheckedRem>::checked_rem(&b(8), &b(7)), None);
1333
1334                assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(2)), Some(b(2)));
1335                assert_eq!(<B as CheckedSub>::checked_sub(&b(4), &b(4)), None);
1336
1337                assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 1u32), Some(b(8)));
1338                assert_eq!(<B as CheckedShl>::checked_shl(&b(4), 2u32), None);
1339
1340                assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 1u32), Some(b(2)));
1341                assert_eq!(<B as CheckedShr>::checked_shr(&b(4), 2u32), None);
1342            }
1343        }
1344    } pub use self::$inner::Bounded as $name; )* }
1345}
1346
1347define_bounded_integers! {
1348    BoundedU8 u8 -> u8 u16 u32 u64 u128 usize i16 i32 i64 i128 isize,
1349    BoundedU16 u16 -> u16 u32 u64 u128 usize i32 i64 i128,
1350    BoundedU32 u32 -> u32 u64 u128 i64 i128,
1351    BoundedU64 u64 -> u64 u128 i128,
1352    BoundedU128 u128 -> u128,
1353    BoundedUsize usize -> usize,
1354    BoundedI8 i8 signed -> i8 i16 i32 i64 i128 isize,
1355    BoundedI16 i16 signed -> i16 i32 i64 i128 isize,
1356    BoundedI32 i32 signed -> i32 i64 i128,
1357    BoundedI64 i64 signed -> i64 i128,
1358    BoundedI128 i128 signed -> i128,
1359    BoundedIsize isize signed -> isize,
1360}
1361
1362mod indexing;