bounded_integer/
unsafe_api.rs

1/// Unsafely provide the bounded integer API for a custom type.
2///
3/// This is used by the higher-level const generic types and by
4/// [the `bounded_integer!` macro](crate::bounded_integer). It is preferable to use those APIs when
5/// possible.
6///
7/// Takes in a `ty` and a `repr`. `ty` must be a type whose layout is identical to `repr`.
8///
9/// `min` and `max` are const expressions giving the bounds of the type (inclusive).
10/// If `zero` is provided, various traits like [`Default`] will be implemented;
11/// if `one` is provided, `num_traits::One` will be implemented.
12///
13/// # Safety
14///
15/// The given type must be `repr(transparent)` over its claimed `repr`.
16///
17/// # Examples
18///
19/// ```
20#[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
21/// #[repr(transparent)]
22/// struct MyInteger(u8);
23///
24/// bounded_integer::unsafe_api! {
25///     for MyInteger,
26///     unsafe repr: u8,
27///     min: 0,
28///     max: 37,
29///     zero,
30///     one,
31/// }
32///
33/// assert_eq!(MyInteger::new(0).unwrap(), 0);
34/// assert_eq!(MyInteger::new(38), None);
35/// ```
36///
37/// # Reprs
38///
39/// `repr` may either be a primitive integer type, or a descriptor:
40///
41/// ```text
42/// unsafe repr: {
43///     type: u32, // a primitive integer type, or something that resolves to one (e.g. c_int)
44///     signed: false,
45///     supersets: [u32, u64, u128, i64, i128], // Types implementing `From<u32>`
46///     non_supersets: [u8, u16, usize, i8, i16, i32, isize], // All the other integer types
47///     has_wide, // Include for all except `u128` and `i128`.
48/// }
49/// ```
50#[macro_export]
51macro_rules! unsafe_api {
52    (
53        $(#![$($attr:tt)*])*
54        $([$($generics:tt)*])? for $ty:ty $(where { $($where:tt)* })?,
55        unsafe repr: $repr:tt,
56        min: $min:expr,
57        max: $max:expr,
58        $(zero $([$($_:tt)* $zero:tt])?,)?
59        $(one $([$($__:tt)* $one:tt])?,)?
60    ) => {
61        $crate::__unsafe_api_internal! {
62            @repr $repr,
63            $(#![$($attr)*])*
64            [$($($generics)*)?] for $ty where { $($($where)*)? },
65            ([$($($generics)*)?] where $($($where)*)?),
66            min: $min,
67            max: $max,
68            $(zero, $($zero)?)?
69            $(one, $($one)?)?
70        }
71    };
72}
73
74#[macro_export]
75#[doc(hidden)]
76macro_rules! __unsafe_api_internal {
77    (
78        @repr {
79            type: $inner:ty,
80            signed: $(true $([$($_:tt)* $signed:tt])?)? $(false)?,
81            supersets: [$($super:ty),* $(,)?],
82            non_supersets: [$($non_super:ty),* $(,)?],
83            $(has_wide $([$($__:tt)* $has_wide:tt])?,)?
84        },
85        $(#![$($attr:tt)*])*
86        [$($generics:tt)*] for $ty:ty where { $($where:tt)* },
87        $generics_single_token:tt,
88        min: $min:expr,
89        max: $max:expr,
90        $(zero $([$zero:tt])?,)?
91        $(one $([$one:tt])?,)?
92    ) => { $(#[$($attr)*])* const _: () = {
93        // The presence of these imports is somewhat unhygienic: it means users cannot name their
94        // type any of these things. This can always be changed if the need arises.
95        use ::core::assert;
96        use ::core::hash::Hash;
97        use ::core::hash::Hasher;
98        use ::core::fmt;
99        use ::core::borrow::Borrow;
100        use ::core::cmp;
101        use ::core::debug_assert;
102        use ::core::iter;
103        use ::core::num::NonZero;
104        use ::core::prelude::rust_2024::*;
105        use ::core::primitive::*;
106        use ::core::str::FromStr;
107
108        use $crate::ParseError;
109        #[cfg(any($($(if $has_wide)? true)?))]
110        use $crate::__private::Wide;
111        #[cfg(any($($(if $has_wide)? true)?))]
112        use $crate::__private::Signed;
113        use $crate::__private::Unsigned;
114        use $crate::__private::Dispatch;
115
116        #[allow(dead_code)]
117        #[allow(clippy::double_must_use)]
118        impl<$($generics)*> $ty where $($where)* {
119            /// The smallest value this bounded integer can contain.
120            pub const MIN_VALUE: $inner = $min;
121            /// The largest value that this bounded integer can contain.
122            pub const MAX_VALUE: $inner = $max;
123
124            /// The smallest value of the bounded integer.
125            pub const MIN: Self = Self::new(Self::MIN_VALUE)
126                .expect("range minimum should be less than maximum");
127            /// The largest value of the bounded integer.
128            pub const MAX: Self = Self::new(Self::MAX_VALUE)
129                .expect("range minimum should be less than maximum");
130
131            /// Creates a bounded integer if the given value is within the range
132            /// [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
133            #[must_use]
134            #[inline]
135            pub const fn new(n: $inner) -> Option<Self> {
136                if Self::in_range(n) {
137                    Some(unsafe { Self::new_unchecked(n) })
138                } else {
139                    None
140                }
141            }
142
143            /// Creates a bounded integer whose value is known at compile time.
144            ///
145            /// Causes a compile-time error if `N` is not in the valid range.
146            #[must_use]
147            #[inline]
148            pub const fn const_new<const N: $inner>() -> Self {
149                const { Self::new(N).expect("value passed to `const_new` is out of range") }
150            }
151
152            /// Creates a reference to a bounded integer from a reference to a primitive if the
153            /// given value is within the range [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
154            #[must_use]
155            #[inline]
156            pub const fn new_ref(n: &$inner) -> Option<&Self> {
157                if Self::in_range(*n) {
158                    // SAFETY: We just asserted that the value is in range.
159                    Some(unsafe { Self::new_ref_unchecked(n) })
160                } else {
161                    None
162                }
163            }
164
165            /// Creates a mutable reference to a bounded integer from a mutable reference to a
166            /// primitive if the given value is within the range
167            /// [[`MIN`](Self::MIN), [`MAX`](Self::MAX)].
168            #[must_use]
169            #[inline]
170            pub const fn new_mut(n: &mut $inner) -> Option<&mut Self> {
171                if Self::in_range(*n) {
172                    // SAFETY: We just asserted that the value is in range.
173                    Some(unsafe { Self::new_mut_unchecked(n) })
174                } else {
175                    None
176                }
177            }
178
179            /// Creates a bounded integer without checking the value.
180            ///
181            /// # Safety
182            ///
183            /// The value must not be outside the valid range of values; it must not be less than
184            /// [`MIN_VALUE`](Self::MIN_VALUE) or greater than [`MAX_VALUE`](Self::MAX_VALUE).
185            #[must_use]
186            pub const unsafe fn new_unchecked(n: $inner) -> Self {
187                debug_assert!(Self::in_range(n));
188                unsafe { ::core::mem::transmute(n) }
189            }
190
191            /// Creates a shared reference to a bounded integer from a shared reference to a
192            /// primitive.
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_ref_unchecked(n: &$inner) -> &Self {
200                debug_assert!(Self::in_range(*n));
201                unsafe { &*<*const _>::cast(n) }
202            }
203
204            /// Creates a mutable reference to a bounded integer from a mutable reference to a
205            /// primitive.
206            ///
207            /// # Safety
208            ///
209            /// The value must not be outside the valid range of values; it must not be less than
210            /// [`MIN_VALUE`](Self::MIN_VALUE) or greater than [`MAX_VALUE`](Self::MAX_VALUE).
211            #[must_use]
212            pub const unsafe fn new_mut_unchecked(n: &mut $inner) -> &mut Self {
213                debug_assert!(Self::in_range(*n));
214                unsafe { &mut *<*mut _>::cast(n) }
215            }
216
217            /// Checks whether the given value is in the range of the bounded integer.
218            #[must_use]
219            #[inline]
220            pub const fn in_range(n: $inner) -> bool {
221                n >= Self::MIN_VALUE && n <= Self::MAX_VALUE
222            }
223
224            /// Creates a bounded integer by setting the value to [`MIN`](Self::MIN) or
225            /// [`MAX`](Self::MAX) if it is too low or too high respectively.
226            #[must_use]
227            #[inline]
228            pub const fn new_saturating(n: $inner) -> Self {
229                if n < Self::MIN_VALUE {
230                    Self::MIN
231                } else if n > Self::MAX_VALUE {
232                    Self::MAX
233                } else {
234                    unsafe { Self::new_unchecked(n) }
235                }
236            }
237
238            /// Creates a bounded integer by wrapping using modular arithmetic.
239            ///
240            /// For `n` in range, this is an identity function, and it wraps for `n` out of range.
241            ///
242            /// The type parameter `Z` must be any integer type that is a superset of this one.
243            #[must_use]
244            #[inline]
245            pub const fn new_wrapping<__Z: LargerInt>(n: __Z) -> Self {
246                const { assert!(Self::MIN_VALUE < Self::MAX_VALUE) };
247                let range_sub_one: Unsigned<$inner> = Self::MAX_VALUE.abs_diff(Self::MIN_VALUE);
248                let offsets = match range_sub_one.checked_add(1) {
249                    Some(range) => {
250                        let range = NonZero::new(range).unwrap();
251
252                        // The smallest nonnegative value satisfying `left ≡ MIN [MOD range]`.
253                        let left = <Dispatch<$inner>>::rem_euclid_unsigned(Self::MIN_VALUE, range);
254
255                        // The smallest nonnegative value satisfying `−right ≡ MIN [MOD range]`.
256                        let right = match left.checked_sub(1) {
257                            None => 0,
258                            Some(left_sub_one) => range_sub_one - left_sub_one,
259                        };
260
261                        Some((range, left, right))
262                    },
263                    None => None,
264                };
265
266                const {
267                    let mut n: u32 = 0;
268                    $(n += str_eq(__Z::KIND, stringify!($super)) as u32;)*
269                    assert!(n == 1);
270                }
271
272                $(if str_eq(__Z::KIND, stringify!($super)) {
273                    let n = unsafe { ::core::mem::transmute_copy::<__Z, $super>(&n) };
274
275                    let Some((range, left, right)) = offsets else {
276                        // In the case where the range spans this entire type, truncating is
277                        // equivalent to taking modulo.
278                        #[allow(clippy::cast_possible_truncation)]
279                        #[allow(clippy::cast_sign_loss)]
280                        return unsafe { Self::new_unchecked(n as _) };
281                    };
282
283                    // At least one of `n − left` and `n + right` fits in a `__Z`. We calculate
284                    // this value.
285                    let shifted = match <Dispatch<$super>>::checked_add_unsigned(n, right as _) {
286                        Some(n) => n,
287                        None => <Dispatch<$super>>::checked_sub_unsigned(n, left as _).unwrap(),
288                    };
289
290                    let range_t = NonZero::new(range.get() as _).unwrap();
291
292                    // Calculate `shifted mod range`. Since `range` fits in an `Unsigned`, we
293                    // know the result will too.
294                    #[allow(clippy::cast_possible_truncation)]
295                    let rem = <Dispatch<$super>>::rem_euclid_unsigned(shifted, range_t) as _;
296
297                    let inner = <Dispatch<$inner>>::checked_add_unsigned(Self::MIN_VALUE, rem).unwrap();
298
299                    return unsafe { Self::new_unchecked(inner) };
300                })*
301
302                const fn str_eq(a: &str, b: &str) -> bool {
303                    if a.len() != b.len() {
304                        return false;
305                    }
306                    let mut i = 0;
307                    while i < a.len() {
308                        if a.as_bytes()[i] != b.as_bytes()[i] {
309                            return false;
310                        }
311                        i += 1;
312                    }
313                    true
314                }
315
316                ::core::unreachable!()
317            }
318
319            /// Converts a string slice in a given base to the bounded integer.
320            ///
321            /// # Panics
322            ///
323            /// Panics if `radix` is below 2 or above 36.
324            pub const fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseError> {
325                let value = match <Dispatch<$inner>>::from_ascii_radix(src.as_bytes(), radix) {
326                    Ok(value) => value,
327                    Err(e) => return Err(e),
328                };
329                if value < Self::MIN_VALUE {
330                    Err($crate::__private::error_below_min())
331                } else if value > Self::MAX_VALUE {
332                    Err($crate::__private::error_above_max())
333                } else {
334                    Ok(unsafe { Self::new_unchecked(value) })
335                }
336            }
337
338            #[inline]
339            const fn assert_range(&self) {
340                // Safety: As this type cannot be constructed unless the inner value is within
341                // the given range, we can use `assert_unchecked` to ensure that LLVM always
342                // maintains the range information no matter what.
343                unsafe {
344                    ::core::hint::assert_unchecked(
345                        Self::in_range(::core::mem::transmute::<Self, $inner>(*self)),
346                    );
347                }
348            }
349
350            /// Returns the value of the bounded integer as a primitive type.
351            #[must_use]
352            #[inline]
353            pub const fn get(self) -> $inner {
354                self.assert_range();
355                unsafe { ::core::mem::transmute(self) }
356            }
357
358            /// Returns a shared reference to the value of the bounded integer.
359            #[must_use]
360            #[inline]
361            pub const fn get_ref(&self) -> &$inner {
362                self.assert_range();
363                unsafe { &*<*const _>::cast(self) }
364            }
365
366            /// Returns a mutable reference to the value of the bounded integer.
367            ///
368            /// # Safety
369            ///
370            /// This value must never be set to a value beyond the range of the bounded integer.
371            #[must_use]
372            #[inline]
373            pub const unsafe fn get_mut(&mut self) -> &mut $inner {
374                self.assert_range();
375                unsafe { &mut *<*mut _>::cast(self) }
376            }
377
378            $($(if $signed)?
379                /// Computes the absolute value of `self`, panicking if it is out of range.
380                #[must_use]
381                #[inline]
382                pub const fn abs(self) -> Self {
383                    Self::new(self.get().abs()).expect("Absolute value out of range")
384                }
385            )*
386
387            /// Raises `self` to the power of `exp`, using exponentiation by squaring. Panics if it
388            /// is out of range.
389            #[must_use]
390            #[inline]
391            pub const fn pow(self, exp: u32) -> Self {
392                Self::new(self.get().pow(exp)).expect("Value raised to power out of range")
393            }
394
395            /// Calculates the quotient of Euclidean division of `self` by `rhs`. Panics if `rhs`
396            /// is 0 or the result is out of range.
397            #[must_use]
398            #[inline]
399            pub const fn div_euclid(self, rhs: $inner) -> Self {
400                Self::new(self.get().div_euclid(rhs)).expect("Attempted to divide out of range")
401            }
402
403            /// Calculates the least nonnegative remainder of `self (mod rhs)`. Panics if `rhs` is 0
404            /// or the result is out of range.
405            #[must_use]
406            #[inline]
407            pub const fn rem_euclid(self, rhs: $inner) -> Self {
408                Self::new(self.get().rem_euclid(rhs))
409                    .expect("Attempted to divide with remainder out of range")
410            }
411
412            /// Checked integer addition.
413            ///
414            /// Returns `None` if the result would be out of range.
415            #[must_use]
416            #[inline]
417            pub const fn checked_add(self, rhs: $inner) -> Option<Self> {
418                match self.get().checked_add(rhs) {
419                    Some(val) => Self::new(val),
420                    None => None,
421                }
422            }
423
424            /// Saturating integer addition.
425            #[must_use]
426            #[inline]
427            pub const fn saturating_add(self, rhs: $inner) -> Self {
428                Self::new_saturating(self.get().saturating_add(rhs))
429            }
430
431            /// Wrapping (modular) integer addition.
432            #[must_use]
433            #[inline]
434            #[cfg(not(all($($(if $has_wide)? false)?)))]
435            pub const fn wrapping_add(self, rhs: $inner) -> Self {
436                Self::new_wrapping((self.get() as Wide<$inner>) + (rhs as Wide<$inner>))
437            }
438
439            /// Checked integer subtraction.
440            ///
441            /// Returns `None` if the result would be out of range.
442            #[must_use]
443            #[inline]
444            pub const fn checked_sub(self, rhs: $inner) -> Option<Self> {
445                match self.get().checked_sub(rhs) {
446                    Some(val) => Self::new(val),
447                    None => None,
448                }
449            }
450
451            /// Saturating integer subtraction.
452            #[must_use]
453            #[inline]
454            pub const fn saturating_sub(self, rhs: $inner) -> Self {
455                Self::new_saturating(self.get().saturating_sub(rhs))
456            }
457
458            /// Wrapping (modular) integer subtraction.
459            #[must_use]
460            #[inline]
461            #[cfg(not(all($($(if $has_wide)? false)?)))]
462            pub const fn wrapping_sub(self, rhs: $inner) -> Self {
463                Self::new_wrapping(
464                    (self.get() as Signed<Wide<$inner>>) - (rhs as Signed<Wide<$inner>>)
465                )
466            }
467
468            /// Checked integer multiplication.
469            ///
470            /// Returns `None` if the result would be out of range.
471            #[must_use]
472            #[inline]
473            pub const fn checked_mul(self, rhs: $inner) -> Option<Self> {
474                match self.get().checked_mul(rhs) {
475                    Some(val) => Self::new(val),
476                    None => None,
477                }
478            }
479
480            /// Saturating integer multiplication.
481            #[must_use]
482            #[inline]
483            pub const fn saturating_mul(self, rhs: $inner) -> Self {
484                Self::new_saturating(self.get().saturating_mul(rhs))
485            }
486
487            /// Wrapping (modular) integer multiplication.
488            #[must_use]
489            #[inline]
490            #[cfg(not(all($($(if $has_wide)? false)?)))]
491            pub const fn wrapping_mul(self, rhs: $inner) -> Self {
492                Self::new_wrapping((self.get() as Wide<$inner>) * (rhs as Wide<$inner>))
493            }
494
495            /// Checked integer division.
496            ///
497            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
498            #[must_use]
499            #[inline]
500            pub const fn checked_div(self, rhs: $inner) -> Option<Self> {
501                match self.get().checked_div(rhs) {
502                    Some(val) => Self::new(val),
503                    None => None,
504                }
505            }
506
507            /// Wrapping (modular) integer division.
508            #[must_use]
509            #[inline]
510            #[cfg(not(all($($(if $has_wide)? false)?)))]
511            pub const fn wrapping_div(self, rhs: $inner) -> Self {
512                // We need to widen for the case of `$inner::MIN / −1`.
513                Self::new_wrapping((self.get() as Wide<$inner>) / (rhs as Wide<$inner>))
514            }
515
516            /// Checked Euclidean division.
517            ///
518            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
519            #[must_use]
520            #[inline]
521            pub const fn checked_div_euclid(self, rhs: $inner) -> Option<Self> {
522                match self.get().checked_div_euclid(rhs) {
523                    Some(val) => Self::new(val),
524                    None => None,
525                }
526            }
527
528            /// Wrapping (modular) Euclidean division.
529            #[must_use]
530            #[inline]
531            #[cfg(not(all($($(if $has_wide)? false)?)))]
532            pub const fn wrapping_div_euclid(self, rhs: $inner) -> Self {
533                // We need to widen for the case of `$inner::MIN / −1`.
534                Self::new_wrapping((self.get() as Wide<$inner>).div_euclid(rhs as Wide<$inner>))
535            }
536
537            /// Checked integer remainder.
538            ///
539            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
540            #[must_use]
541            #[inline]
542            pub const fn checked_rem(self, rhs: $inner) -> Option<Self> {
543                match self.get().checked_rem(rhs) {
544                    Some(val) => Self::new(val),
545                    None => None,
546                }
547            }
548
549            /// Wrapping (modular) integer remainder.
550            #[must_use]
551            #[inline]
552            #[cfg(not(all($($(if $has_wide)? false)?)))]
553            pub const fn wrapping_rem(self, rhs: $inner) -> Self {
554                // We need to widen for the case of `$inner::MIN % −1`.
555                Self::new_wrapping((self.get() as Wide<$inner>) % (rhs as Wide<$inner>))
556            }
557
558            /// Checked Euclidean remainder.
559            ///
560            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
561            #[must_use]
562            #[inline]
563            pub const fn checked_rem_euclid(self, rhs: $inner) -> Option<Self> {
564                match self.get().checked_rem_euclid(rhs) {
565                    Some(val) => Self::new(val),
566                    None => None,
567                }
568            }
569
570            /// Wrapping (modular) Euclidean remainder.
571            #[must_use]
572            #[inline]
573            #[cfg(not(all($($(if $has_wide)? false)?)))]
574            pub const fn wrapping_rem_euclid(self, rhs: $inner) -> Self {
575                // We need to widen for the case of `$inner::MIN % −1`.
576                Self::new_wrapping((self.get() as Wide<$inner>).rem_euclid(rhs as Wide<$inner>))
577            }
578
579            /// Checked negation.
580            ///
581            /// Returns `None` if the result would be out of range.
582            #[must_use]
583            #[inline]
584            pub const fn checked_neg(self) -> Option<Self> {
585                match self.get().checked_neg() {
586                    Some(val) => Self::new(val),
587                    None => None,
588                }
589            }
590
591            /// Saturating negation.
592            #[must_use]
593            #[inline]
594            #[cfg(not(all($($(if $signed)? false)?)))]
595            pub const fn saturating_neg(self) -> Self {
596                Self::new_saturating(self.get().saturating_neg())
597            }
598
599            /// Wrapping (modular) negation.
600            #[must_use]
601            #[inline]
602            #[cfg(not(all($($(if $signed)? false)?)))]
603            #[cfg(not(all($($(if $has_wide)? false)?)))]
604            pub const fn wrapping_neg(self) -> Self {
605                Self::new_wrapping(-(self.get() as Wide<$inner>))
606            }
607
608            /// Checked absolute value.
609            #[must_use]
610            #[inline]
611            #[cfg(not(all($($(if $signed)? false)?)))]
612            pub const fn checked_abs(self) -> Option<Self> {
613                match self.get().checked_abs() {
614                    Some(val) => Self::new(val),
615                    None => None,
616                }
617            }
618
619            /// Saturating absolute value.
620            #[must_use]
621            #[inline]
622            #[cfg(not(all($($(if $signed)? false)?)))]
623            pub const fn saturating_abs(self) -> Self {
624                Self::new_saturating(self.get().saturating_abs())
625            }
626
627            /// Wrapping (modular) absolute value.
628            #[must_use]
629            #[inline]
630            #[cfg(not(all($($(if $signed)? false)?)))]
631            #[cfg(not(all($($(if $has_wide)? false)?)))]
632            pub const fn wrapping_abs(self) -> Self {
633                Self::new_wrapping((self.get() as Wide<$inner>).abs())
634            }
635
636            /// Checked exponentiation.
637            #[must_use]
638            #[inline]
639            pub const fn checked_pow(self, rhs: u32) -> Option<Self> {
640                match self.get().checked_pow(rhs) {
641                    Some(val) => Self::new(val),
642                    None => None,
643                }
644            }
645
646            /// Saturating exponentiation.
647            #[must_use]
648            #[inline]
649            pub const fn saturating_pow(self, rhs: u32) -> Self {
650                Self::new_saturating(self.get().saturating_pow(rhs))
651            }
652
653            /// Wrapping (modular) exponentiation.
654            #[must_use]
655            #[inline]
656            #[cfg(not(all($($(if $has_wide)? false)?)))]
657            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
658                let range_sub_one = Self::MAX_VALUE.abs_diff(Self::MIN_VALUE);
659                let Some(range) = range_sub_one.checked_add(1) else {
660                    return unsafe { Self::new_unchecked(self.get().wrapping_pow(exp)) };
661                };
662
663                // Exponentiation by squaring (same algorithm as used in std), but taking modulo
664                // each time. We keep our values in the range [0, MAX − MIN].
665                if exp == 0 {
666                    return Self::new_wrapping::<$inner>(1);
667                }
668                let mut base = self.get() as Wide<$inner>;
669                let mut acc: Wide<$inner> = 1;
670                let range = range as Wide<$inner>;
671                loop {
672                    if (exp & 1) == 1 {
673                        acc = (acc * base).rem_euclid(range);
674                        if exp == 1 {
675                            return Self::new_wrapping(acc);
676                        }
677                    }
678                    exp /= 2;
679                    base = (base * base).rem_euclid(range);
680                }
681            }
682
683            /// Checked shift left.
684            #[must_use]
685            #[inline]
686            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
687                match self.get().checked_shl(rhs) {
688                    Some(val) => Self::new(val),
689                    None => None,
690                }
691            }
692
693            /// Checked shift right.
694            #[must_use]
695            #[inline]
696            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
697                match self.get().checked_shr(rhs) {
698                    Some(val) => Self::new(val),
699                    None => None,
700                }
701            }
702        }
703
704        pub trait LargerInt: Copy {
705            const KIND: &'static str;
706        }
707
708        $(#[automatically_derived]
709        impl LargerInt for $super { const KIND: &'static str = stringify!($super); })*
710
711        $crate::__unsafe_api_internal!(@with_super($ty, $inner)
712            $({ super: $super, generics: $generics_single_token })*
713        );
714        $crate::__unsafe_api_internal!(@with_non_super($ty, $inner)
715            $({ non_super: $non_super, generics: $generics_single_token })*
716        );
717        $crate::__unsafe_api_internal!(@with_all_int($ty, $inner)
718            { int: u8, generics: $generics_single_token }
719            { int: u16, generics: $generics_single_token }
720            { int: u32, generics: $generics_single_token }
721            { int: u64, generics: $generics_single_token }
722            { int: u128, generics: $generics_single_token }
723            { int: usize, generics: $generics_single_token }
724            { int: i8, generics: $generics_single_token }
725            { int: i16, generics: $generics_single_token }
726            { int: i32, generics: $generics_single_token }
727            { int: i64, generics: $generics_single_token }
728            { int: i128, generics: $generics_single_token }
729            { int: isize, generics: $generics_single_token }
730        );
731
732        // === Clone / Copy ===
733
734        #[automatically_derived]
735        impl<$($generics)*> Clone for $ty where $($where)* {
736            fn clone(&self) -> Self { *self }
737        }
738        #[automatically_derived]
739        impl<$($generics)*> Copy for $ty where $($where)* {}
740
741        // === Default ===
742
743        #[cfg(not(all($($($zero)? false)?)))]
744        #[automatically_derived]
745        impl<$($generics)*> Default for $ty where $($where)* {
746            fn default() -> Self {
747                const {
748                    Self::new(0).expect("used `zero` on a type whose range does not include zero")
749                }
750            }
751        }
752
753        // Use a function to force post-mono errors even if `num-traits02` is disabled.
754        #[cfg(not(all($($($one)? false)?)))]
755        impl<$($generics)*> $ty where $($where)* {
756            #[allow(unused)]
757            fn one() -> Self {
758                const {
759                    Self::new(1).expect("used `one` on a type whose range does not include one")
760                }
761            }
762        }
763
764        // === Operators ===
765
766        $crate::__unsafe_api_internal!(@bin_ops($ty, $inner)
767            ($generics_single_token, Add::add/AddAssign::add_assign, "add"),
768            ($generics_single_token, Sub::sub/SubAssign::sub_assign, "subtract"),
769            ($generics_single_token, Mul::mul/MulAssign::mul_assign, "multiply"),
770            ($generics_single_token, Div::div/DivAssign::div_assign, "divide"),
771            ($generics_single_token, Rem::rem/RemAssign::rem_assign, "take remainder"),
772            ($generics_single_token, BitAnd::bitand/BitAndAssign::bitand_assign, "binary and"),
773            ($generics_single_token, BitOr::bitor/BitOrAssign::bitor_assign, "binary or"),
774            ($generics_single_token, BitXor::bitxor/BitXorAssign::bitxor_assign, "binary xor"),
775        );
776        use ::core::ops::{Shl, Shr, ShlAssign, ShrAssign};
777        #[automatically_derived]
778        impl<$($generics)*> Shl<u32> for $ty where $($where)* {
779            type Output = Self;
780            #[inline]
781            fn shl(self, rhs: u32) -> Self::Output {
782                Self::new(self.get().shl(rhs))
783                    .expect("Attempted to shift left out of range")
784            }
785        }
786        $crate::__unsafe_api_internal!(@bin_op_variations
787            $generics_single_token,
788            $ty, u32, Shl::shl/ShlAssign::shl_assign
789        );
790        #[automatically_derived]
791        impl<$($generics)*> Shr<u32> for $ty where $($where)* {
792            type Output = Self;
793            #[inline]
794            fn shr(self, rhs: u32) -> Self::Output {
795                Self::new(self.get().shr(rhs))
796                    .expect("Attempted to shift right out of range")
797            }
798        }
799        $crate::__unsafe_api_internal!(@bin_op_variations
800            $generics_single_token,
801            $ty, u32, Shr::shr/ShrAssign::shr_assign
802        );
803
804        #[cfg(not(all($($(if $signed)? false)?)))]
805        use ::core::ops::Neg;
806
807        #[cfg(not(all($($(if $signed)? false)?)))]
808        #[automatically_derived]
809        impl<$($generics)*> Neg for $ty where $($where)* {
810            type Output = Self;
811            #[inline]
812            fn neg(self) -> Self::Output {
813                Self::new(-self.get())
814                    .expect("Attempted to negate out of range")
815            }
816        }
817        #[cfg(not(all($($(if $signed)? false)?)))]
818        #[automatically_derived]
819        impl<$($generics)*> Neg for &$ty where $($where)* {
820            type Output = $ty;
821            #[inline]
822            fn neg(self) -> Self::Output {
823                -*self
824            }
825        }
826
827        use ::core::ops::Not;
828
829        #[automatically_derived]
830        impl<$($generics)*> Not for $ty where $($where)* {
831            type Output = Self;
832            #[inline]
833            fn not(self) -> Self::Output {
834                Self::new(!self.get())
835                    .expect("Attempted to invert bits out of range")
836            }
837        }
838        #[automatically_derived]
839        impl<$($generics)*> Not for &$ty where $($where)* {
840            type Output = $ty;
841            #[inline]
842            fn not(self) -> Self::Output {
843                !*self
844            }
845        }
846
847        // === Comparisons and Hash ===
848
849        #[automatically_derived]
850        impl<$($generics)*> PartialEq<$inner> for $ty where $($where)* {
851            #[inline]
852            fn eq(&self, other: &$inner) -> bool {
853                self.get() == *other
854            }
855        }
856        #[automatically_derived]
857        impl<$($generics)*> PartialEq<$ty> for $inner where $($where)* {
858            #[inline]
859            fn eq(&self, other: &$ty) -> bool {
860                *self == other.get()
861            }
862        }
863        #[automatically_derived]
864        impl<$($generics)*> PartialEq for $ty where $($where)* {
865            #[inline]
866            fn eq(&self, other: &$ty) -> bool {
867                self.get() == other.get()
868            }
869        }
870        #[automatically_derived]
871        impl<$($generics)*> Eq for $ty where $($where)* {}
872
873        #[automatically_derived]
874        impl<$($generics)*> PartialOrd<$inner> for $ty where $($where)* {
875            #[inline]
876            fn partial_cmp(&self, other: &$inner) -> Option<cmp::Ordering> {
877                self.get().partial_cmp(other)
878            }
879        }
880        #[automatically_derived]
881        impl<$($generics)*> PartialOrd<$ty> for $inner where $($where)* {
882            #[inline]
883            fn partial_cmp(&self, other: &$ty) -> Option<cmp::Ordering> {
884                self.partial_cmp(&other.get())
885            }
886        }
887        #[automatically_derived]
888        impl<$($generics)*> PartialOrd for $ty where $($where)* {
889            #[inline]
890            fn partial_cmp(&self, other: &$ty) -> Option<cmp::Ordering> {
891                Some(self.cmp(other))
892            }
893        }
894        #[automatically_derived]
895        impl<$($generics)*> Ord for $ty where $($where)* {
896            #[inline]
897            fn cmp(&self, other: &$ty) -> cmp::Ordering {
898                self.get().cmp(&other.get())
899            }
900        }
901
902        #[automatically_derived]
903        impl<$($generics)*> Hash for $ty where $($where)* {
904            #[inline]
905            fn hash<H: Hasher>(&self, state: &mut H) {
906                self.get().hash(state);
907            }
908        }
909
910        // === AsRef, Borrow ===
911
912        #[automatically_derived]
913        impl<$($generics)*> AsRef<$inner> for $ty where $($where)* {
914            #[inline]
915            fn as_ref(&self) -> &$inner {
916                self.get_ref()
917            }
918        }
919        #[automatically_derived]
920        impl<$($generics)*> Borrow<$inner> for $ty where $($where)* {
921            #[inline]
922            fn borrow(&self) -> &$inner {
923                self.get_ref()
924            }
925        }
926
927        // === Iterator traits ===
928
929        // Sum bounded to bounded
930        #[automatically_derived]
931        impl<$($generics)*> iter::Sum for $ty where $($where)* {
932            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
933                iter.reduce(Add::add)
934                    .unwrap_or_else(|| Self::new(0).expect("Attempted to sum to zero"))
935            }
936        }
937        #[automatically_derived]
938        impl<'__a, $($generics)*> iter::Sum<&'__a Self> for $ty where $($where)* {
939            fn sum<I: Iterator<Item = &'__a Self>>(iter: I) -> Self {
940                iter.copied().sum()
941            }
942        }
943
944        // Sum bounded to primitive
945        #[automatically_derived]
946        impl<$($generics)*> iter::Sum<$ty> for $inner where $($where)* {
947            fn sum<I: Iterator<Item = $ty>>(iter: I) -> Self {
948                iter.map(<$ty>::get).sum()
949            }
950        }
951        #[automatically_derived]
952        impl<'__a, $($generics)*> iter::Sum<&'__a $ty> for $inner where $($where)* {
953            fn sum<I: Iterator<Item = &'__a $ty>>(iter: I) -> Self {
954                iter.copied().sum()
955            }
956        }
957
958        // Take product of bounded to bounded
959        #[automatically_derived]
960        impl<$($generics)*> iter::Product for $ty where $($where)* {
961            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
962                iter.reduce(Mul::mul)
963                    .unwrap_or_else(|| Self::new(1).expect("Attempted to take product to one"))
964            }
965        }
966        #[automatically_derived]
967        impl<'__a, $($generics)*> iter::Product<&'__a Self> for $ty where $($where)* {
968            fn product<I: Iterator<Item = &'__a Self>>(iter: I) -> Self {
969                iter.copied().product()
970            }
971        }
972
973        // Take product of bounded to primitive
974        #[automatically_derived]
975        impl<$($generics)*> iter::Product<$ty> for $inner where $($where)* {
976            fn product<I: Iterator<Item = $ty>>(iter: I) -> Self {
977                iter.map(<$ty>::get).product()
978            }
979        }
980        #[automatically_derived]
981        impl<'__a, $($generics)*> iter::Product<&'__a $ty> for $inner where $($where)* {
982            fn product<I: Iterator<Item = &'__a $ty>>(iter: I) -> Self {
983                iter.copied().product()
984            }
985        }
986
987        $crate::__private::__cfg_step_trait! {
988            #[automatically_derived]
989            impl<$($generics)*> iter::Step for $ty where $($where)* {
990                #[inline]
991                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
992                    iter::Step::steps_between(&start.get(), &end.get())
993                }
994                #[inline]
995                fn forward_checked(start: Self, count: usize) -> Option<Self> {
996                    iter::Step::forward_checked(start.get(), count).and_then(Self::new)
997                }
998                #[inline]
999                fn backward_checked(start: Self, count: usize) -> Option<Self> {
1000                    iter::Step::backward_checked(start.get(), count).and_then(Self::new)
1001                }
1002            }
1003        }
1004
1005        // === Parsing ===
1006
1007        #[automatically_derived]
1008        impl<$($generics)*> FromStr for $ty where $($where)* {
1009            type Err = ParseError;
1010            fn from_str(s: &str) -> Result<Self, Self::Err> {
1011                Self::from_str_radix(s, 10)
1012            }
1013        }
1014
1015        // === Formatting ===
1016
1017        #[automatically_derived]
1018        impl<$($generics)*> fmt::Debug for $ty where $($where)* {
1019            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1020                f.debug_tuple("Bounded").field(&self.get()).finish()
1021            }
1022        }
1023
1024        $crate::__unsafe_api_internal!(@fmt_traits($ty, $inner)
1025            $generics_single_token Binary,
1026            $generics_single_token Display,
1027            $generics_single_token LowerExp,
1028            $generics_single_token LowerHex,
1029            $generics_single_token Octal,
1030            $generics_single_token UpperExp,
1031            $generics_single_token UpperHex,
1032        );
1033
1034        // === Arbitrary ===
1035
1036        $crate::__private::__cfg_arbitrary1! {
1037            use $crate::__private::arbitrary1::{self, Arbitrary, Unstructured};
1038
1039            #[automatically_derived]
1040            impl<'__a, $($generics)*> Arbitrary<'__a> for $ty where $($where)* {
1041                fn arbitrary(u: &mut Unstructured<'__a>) -> arbitrary1::Result<Self> {
1042                    Self::new(u.arbitrary()?).ok_or(arbitrary1::Error::IncorrectFormat)
1043                }
1044
1045                #[inline]
1046                fn size_hint(depth: usize) -> (usize, Option<usize>) {
1047                    <$inner as Arbitrary<'__a>>::size_hint(depth)
1048                }
1049            }
1050        }
1051
1052        // === Bytemuck ===
1053
1054        $crate::__private::__cfg_bytemuck1! {
1055            use $crate::__private::bytemuck1;
1056
1057            #[automatically_derived]
1058            unsafe impl<$($generics)*> bytemuck1::Contiguous for $ty
1059            where
1060                Self: 'static,
1061                $($where)*
1062            {
1063                type Int = $inner;
1064                const MAX_VALUE: $inner = Self::MAX_VALUE;
1065                const MIN_VALUE: $inner = Self::MIN_VALUE;
1066            }
1067
1068            #[automatically_derived]
1069            unsafe impl<$($generics)*> bytemuck1::NoUninit for $ty
1070            where
1071                Self: 'static,
1072                $($where)*
1073            {}
1074
1075            #[cfg(not(all($($(if $zero)? false)?)))]
1076            #[automatically_derived]
1077            unsafe impl<$($generics)*> bytemuck1::Zeroable for $ty where $($where)* {}
1078        }
1079
1080        // === Num ===
1081
1082        $crate::__private::__cfg_num_traits02! {
1083            use $crate::__private::num_traits02;
1084
1085            #[automatically_derived]
1086            impl<$($generics)*> num_traits02::Bounded for $ty where $($where)* {
1087                fn min_value() -> Self {
1088                    Self::MIN
1089                }
1090                fn max_value() -> Self {
1091                    Self::MAX
1092                }
1093            }
1094
1095            #[automatically_derived]
1096            impl<__T, $($generics)*> num_traits02::AsPrimitive<__T> for $ty
1097            where
1098                $inner: num_traits02::AsPrimitive<__T>,
1099                __T: 'static + Copy,
1100                Self: 'static,
1101                $($where)*
1102            {
1103                fn as_(self) -> __T {
1104                    self.get().as_()
1105                }
1106            }
1107
1108            #[automatically_derived]
1109            impl<$($generics)*> num_traits02::FromPrimitive for $ty
1110            where
1111                $inner: num_traits02::FromPrimitive,
1112                $($where)*
1113            {
1114                fn from_i64(n: i64) -> Option<Self> {
1115                    <$inner>::from_i64(n).and_then(Self::new)
1116                }
1117                fn from_u64(n: u64) -> Option<Self> {
1118                    <$inner>::from_u64(n).and_then(Self::new)
1119                }
1120                fn from_isize(n: isize) -> Option<Self> {
1121                    <$inner>::from_isize(n).and_then(Self::new)
1122                }
1123                fn from_i8(n: i8) -> Option<Self> {
1124                    <$inner>::from_i8(n).and_then(Self::new)
1125                }
1126                fn from_i16(n: i16) -> Option<Self> {
1127                    <$inner>::from_i16(n).and_then(Self::new)
1128                }
1129                fn from_i32(n: i32) -> Option<Self> {
1130                    <$inner>::from_i32(n).and_then(Self::new)
1131                }
1132                fn from_i128(n: i128) -> Option<Self> {
1133                    <$inner>::from_i128(n).and_then(Self::new)
1134                }
1135                fn from_usize(n: usize) -> Option<Self> {
1136                    <$inner>::from_usize(n).and_then(Self::new)
1137                }
1138                fn from_u8(n: u8) -> Option<Self> {
1139                    <$inner>::from_u8(n).and_then(Self::new)
1140                }
1141                fn from_u16(n: u16) -> Option<Self> {
1142                    <$inner>::from_u16(n).and_then(Self::new)
1143                }
1144                fn from_u32(n: u32) -> Option<Self> {
1145                    <$inner>::from_u32(n).and_then(Self::new)
1146                }
1147                fn from_u128(n: u128) -> Option<Self> {
1148                    <$inner>::from_u128(n).and_then(Self::new)
1149                }
1150                fn from_f32(n: f32) -> Option<Self> {
1151                    <$inner>::from_f32(n).and_then(Self::new)
1152                }
1153                fn from_f64(n: f64) -> Option<Self> {
1154                    <$inner>::from_f64(n).and_then(Self::new)
1155                }
1156            }
1157
1158            #[automatically_derived]
1159            impl<$($generics)*> num_traits02::NumCast for $ty
1160            where
1161                $inner: num_traits02::NumCast,
1162                $($where)*
1163            {
1164                fn from<__T: num_traits02::ToPrimitive>(n: __T) -> Option<Self> {
1165                    <$inner as num_traits02::NumCast>::from(n).map(Self::new).flatten()
1166                }
1167            }
1168
1169            #[automatically_derived]
1170            impl<$($generics)*> num_traits02::ToPrimitive for $ty
1171            where
1172                $inner: num_traits02::ToPrimitive,
1173                $($where)*
1174            {
1175                fn to_i64(&self) -> Option<i64> {
1176                    self.get().to_i64()
1177                }
1178                fn to_u64(&self) -> Option<u64> {
1179                    self.get().to_u64()
1180                }
1181                fn to_isize(&self) -> Option<isize> {
1182                    self.get().to_isize()
1183                }
1184                fn to_i8(&self) -> Option<i8> {
1185                    self.get().to_i8()
1186                }
1187                fn to_i16(&self) -> Option<i16> {
1188                    self.get().to_i16()
1189                }
1190                fn to_i32(&self) -> Option<i32> {
1191                    self.get().to_i32()
1192                }
1193                fn to_i128(&self) -> Option<i128> {
1194                    self.get().to_i128()
1195                }
1196                fn to_usize(&self) -> Option<usize> {
1197                    self.get().to_usize()
1198                }
1199                fn to_u8(&self) -> Option<u8> {
1200                    self.get().to_u8()
1201                }
1202                fn to_u16(&self) -> Option<u16> {
1203                    self.get().to_u16()
1204                }
1205                fn to_u32(&self) -> Option<u32> {
1206                    self.get().to_u32()
1207                }
1208                fn to_u128(&self) -> Option<u128> {
1209                    self.get().to_u128()
1210                }
1211                fn to_f32(&self) -> Option<f32> {
1212                    self.get().to_f32()
1213                }
1214                fn to_f64(&self) -> Option<f64> {
1215                    self.get().to_f64()
1216                }
1217            }
1218
1219            #[automatically_derived]
1220            impl<$($generics)*> num_traits02::CheckedAdd for $ty where $($where)* {
1221                fn checked_add(&self, v: &Self) -> Option<Self> {
1222                    Self::checked_add(*self, v.get())
1223                }
1224            }
1225
1226            #[automatically_derived]
1227            impl<$($generics)*> num_traits02::CheckedDiv for $ty where $($where)* {
1228                fn checked_div(&self, v: &Self) -> Option<Self> {
1229                    Self::checked_div(*self, v.get())
1230                }
1231            }
1232
1233            #[automatically_derived]
1234            impl<$($generics)*> num_traits02::CheckedMul for $ty where $($where)* {
1235                fn checked_mul(&self, v: &Self) -> Option<Self> {
1236                    Self::checked_mul(*self, v.get())
1237                }
1238            }
1239
1240            #[automatically_derived]
1241            impl<$($generics)*> num_traits02::CheckedNeg for $ty where $($where)* {
1242                fn checked_neg(&self) -> Option<Self> {
1243                    Self::checked_neg(*self)
1244                }
1245            }
1246
1247            #[automatically_derived]
1248            impl<$($generics)*> num_traits02::CheckedRem for $ty where $($where)* {
1249                fn checked_rem(&self, v: &Self) -> Option<Self> {
1250                    Self::checked_rem(*self, v.get())
1251                }
1252            }
1253
1254            #[automatically_derived]
1255            impl<$($generics)*> num_traits02::CheckedShl for $ty where $($where)* {
1256                fn checked_shl(&self, v: u32) -> Option<Self> {
1257                    Self::checked_shl(*self, v)
1258                }
1259            }
1260
1261            #[automatically_derived]
1262            impl<$($generics)*> num_traits02::CheckedShr for $ty where $($where)* {
1263                fn checked_shr(&self, v: u32) -> Option<Self> {
1264                    Self::checked_shr(*self, v)
1265                }
1266            }
1267
1268            #[automatically_derived]
1269            impl<$($generics)*> num_traits02::CheckedSub for $ty where $($where)* {
1270                fn checked_sub(&self, v: &Self) -> Option<Self> {
1271                    Self::checked_sub(*self, v.get())
1272                }
1273            }
1274
1275            #[automatically_derived]
1276            impl<__A, __B, $($generics)*> num_traits02::MulAdd<__A, __B> for $ty
1277            where
1278                $inner: num_traits02::MulAdd<__A, __B, Output = $inner>,
1279                $($where)*
1280            {
1281                type Output = $inner;
1282
1283                fn mul_add(self, a: __A, b: __B) -> Self::Output {
1284                    self.get().mul_add(a, b)
1285                }
1286            }
1287
1288            #[automatically_derived]
1289            impl<$($generics)*> num_traits02::SaturatingAdd for $ty where $($where)* {
1290                fn saturating_add(&self, v: &Self) -> Self {
1291                    Self::saturating_add(*self, v.get())
1292                }
1293            }
1294
1295            #[automatically_derived]
1296            impl<$($generics)*> num_traits02::SaturatingMul for $ty where $($where)* {
1297                fn saturating_mul(&self, v: &Self) -> Self {
1298                    Self::saturating_mul(*self, v.get())
1299                }
1300            }
1301
1302            #[automatically_derived]
1303            impl<$($generics)*> num_traits02::SaturatingSub for $ty where $($where)* {
1304                fn saturating_sub(&self, v: &Self) -> Self {
1305                    Self::saturating_sub(*self, v.get())
1306                }
1307            }
1308
1309            #[cfg(not(all($($($zero)? false)?)))]
1310            #[automatically_derived]
1311            impl<$($generics)*> num_traits02::Zero for $ty where $($where)* {
1312                fn zero() -> Self {
1313                    Self::default()
1314                }
1315                fn is_zero(&self) -> bool {
1316                    self.get() == 0
1317                }
1318            }
1319
1320            #[cfg(not(all($($($one)? false)?)))]
1321            #[automatically_derived]
1322            impl<$($generics)*> num_traits02::One for $ty where $($where)* {
1323                fn one() -> Self {
1324                    Self::one()
1325                }
1326            }
1327        }
1328
1329        // === Serde ===
1330
1331        $crate::__private::__cfg_serde1! {
1332            use $crate::__private::serde1::{self, Deserialize, Deserializer, Serialize, Serializer};
1333
1334            #[automatically_derived]
1335            impl<$($generics)*> Serialize for $ty where $($where)* {
1336                fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1337                    self.get().serialize(serializer)
1338                }
1339            }
1340
1341            // Disable this to prevent triggering `clippy::unsafe_derive_deserialize`. I couldn’t
1342            // figure out how to `#[allow]` it.
1343            // #[automatically_derived]
1344            impl<'__de, $($generics)*> Deserialize<'__de> for $ty where $($where)* {
1345                fn deserialize<D: Deserializer<'__de>>(deserializer: D) -> Result<Self, D::Error> {
1346                    Self::new(<$inner>::deserialize(deserializer)?)
1347                        .ok_or_else(|| {
1348                            <D::Error as serde1::de::Error>::custom(format_args!(
1349                                "integer out of range, expected it to be between {} and {}",
1350                                Self::MIN_VALUE,
1351                                Self::MAX_VALUE,
1352                            ))
1353                        })
1354                }
1355            }
1356        }
1357    }; };
1358
1359    (@repr u8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1360        @repr {
1361            type: u8,
1362            signed: false,
1363            supersets: [u8, u16, u32, u64, u128, usize, i16, i32, i64, i128, isize],
1364            non_supersets: [i8],
1365            has_wide,
1366        },
1367        $($rest)*
1368    } };
1369    (@repr u16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1370        @repr {
1371            type: u16,
1372            signed: false,
1373            supersets: [u16, u32, u64, u128, usize, i32, i64, i128],
1374            non_supersets: [u8, i8, i16, isize],
1375            has_wide,
1376        },
1377        $($rest)*
1378    } };
1379    (@repr u32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1380        @repr {
1381            type: u32,
1382            signed: false,
1383            supersets: [u32, u64, u128, i64, i128],
1384            non_supersets: [u8, u16, usize, i8, i16, i32, isize],
1385            has_wide,
1386        },
1387        $($rest)*
1388    } };
1389    (@repr u64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1390        @repr {
1391            type: u64,
1392            signed: false,
1393            supersets: [u64, u128, i128],
1394            non_supersets: [u8, u16, u32, usize, i8, i16, i32, i64, isize],
1395            has_wide,
1396        },
1397        $($rest)*
1398    } };
1399    (@repr u128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1400        @repr {
1401            type: u128,
1402            signed: false,
1403            supersets: [u128],
1404            non_supersets: [u8, u16, u32, u64, usize, i8, i16, i32, i64, i128, isize],
1405        },
1406        $($rest)*
1407    } };
1408    (@repr usize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1409        @repr {
1410            type: usize,
1411            signed: false,
1412            supersets: [usize],
1413            non_supersets: [u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize],
1414        },
1415        $($rest)*
1416    } };
1417    (@repr i8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1418        @repr {
1419            type: i8,
1420            signed: true,
1421            supersets: [i8, i16, i32, i64, i128, isize],
1422            non_supersets: [u8, u16, u32, u64, u128, usize],
1423            has_wide,
1424        },
1425        $($rest)*
1426    } };
1427    (@repr i16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1428        @repr {
1429            type: i16,
1430            signed: true,
1431            supersets: [i16, i32, i64, i128, isize],
1432            non_supersets: [u8, u16, u32, u64, u128, usize, i8],
1433            has_wide,
1434        },
1435        $($rest)*
1436    } };
1437    (@repr i32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1438        @repr {
1439            type: i32,
1440            signed: true,
1441            supersets: [i32, i64, i128],
1442            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, isize],
1443            has_wide,
1444        },
1445        $($rest)*
1446    } };
1447    (@repr i64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1448        @repr {
1449            type: i64,
1450            signed: true,
1451            supersets: [i64, i128],
1452            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, isize],
1453            has_wide,
1454        },
1455        $($rest)*
1456    } };
1457    (@repr i128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1458        @repr {
1459            type: i128,
1460            signed: true,
1461            supersets: [i128],
1462            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, isize],
1463        },
1464        $($rest)*
1465    } };
1466    (@repr isize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1467        @repr {
1468            type: isize,
1469            signed: true,
1470            supersets: [isize],
1471            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128],
1472        },
1473        $($rest)*
1474    } };
1475
1476    (@with_super($ty:ty, $inner:ty)
1477        $({ super: $super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1478    ) => { $(
1479        #[automatically_derived]
1480        impl<$($generics)*> From<$ty> for $super where $($where)* {
1481            fn from(bounded: $ty) -> Self {
1482                Self::from(bounded.get())
1483            }
1484        }
1485    )* };
1486
1487    (@with_non_super($ty:ty, $inner:ty)
1488        $({ non_super: $non_super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1489    ) => { $(
1490        #[automatically_derived]
1491        impl<$($generics)*> TryFrom<$ty> for $non_super where $($where)* {
1492            type Error = ::core::num::TryFromIntError;
1493            fn try_from(n: $ty) -> Result<Self, Self::Error> {
1494                <$non_super as TryFrom<$inner>>::try_from(n.get())
1495            }
1496        }
1497    )* };
1498
1499    (@with_all_int($ty:ty, $inner:ty)
1500        $({ int: $int:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1501    ) => { $(
1502        #[automatically_derived]
1503        impl<$($generics)*> TryFrom<$int> for $ty where $($where)* {
1504            type Error = $crate::TryFromError;
1505            fn try_from(n: $int) -> Result<Self, Self::Error> {
1506                <$inner as TryFrom<$int>>::try_from(n)
1507                    .ok()
1508                    .and_then(Self::new)
1509                    .ok_or_else($crate::__private::try_from_error)
1510            }
1511        }
1512    )* };
1513
1514    (@bin_ops($ty:ty, $inner:ty)
1515        $((
1516            ([$($generics:tt)*] where $($where:tt)*),
1517            $op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal
1518        ),)*
1519    ) => { $(
1520        use ::core::ops::{$op, $op_assign};
1521
1522        #[automatically_derived]
1523        impl<$($generics)*> $op<$inner> for $ty where $($where)* {
1524            type Output = Self;
1525            #[inline]
1526            fn $method(self, rhs: $inner) -> Self::Output {
1527                Self::new(self.get().$method(rhs))
1528                    .expect(concat!("Attempted to ", $desc, " out of range"))
1529            }
1530        }
1531        $crate::__unsafe_api_internal!(@bin_op_variations
1532            ([$($generics)*] where $($where)*),
1533            $ty, $inner, $op::$method/$op_assign::$method_assign
1534        );
1535
1536        #[automatically_derived]
1537        impl<$($generics)*> $op<$ty> for $inner where $($where)* {
1538            type Output = Self;
1539            #[inline]
1540            fn $method(self, rhs: $ty) -> Self::Output {
1541                self.$method(rhs.get())
1542            }
1543        }
1544        $crate::__unsafe_api_internal!(@bin_op_variations
1545            ([$($generics)*] where $($where)*),
1546            $inner, $ty, $op::$method/$op_assign::$method_assign
1547        );
1548
1549        #[automatically_derived]
1550        impl<$($generics)*> $op<$ty> for $ty where $($where)* {
1551            type Output = Self;
1552            #[inline]
1553            fn $method(self, rhs: $ty) -> Self::Output {
1554                self.$method(rhs.get())
1555            }
1556        }
1557        $crate::__unsafe_api_internal!(@bin_op_variations
1558            ([$($generics)*] where $($where)*),
1559            $ty, $ty, $op::$method/$op_assign::$method_assign
1560        );
1561    )* };
1562
1563    (@bin_op_variations
1564        ([$($generics:tt)*] where $($where:tt)*),
1565        $lhs:ty, $rhs:ty, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident
1566    ) => {
1567        #[automatically_derived]
1568        impl<$($generics)*> $op<$rhs> for &$lhs where $($where)* {
1569            type Output = $lhs;
1570            #[inline]
1571            fn $method(self, rhs: $rhs) -> Self::Output {
1572                <$lhs as $op<$rhs>>::$method(*self, rhs)
1573            }
1574        }
1575        #[automatically_derived]
1576        impl<$($generics)*> $op<&$rhs> for $lhs where $($where)* {
1577            type Output = $lhs;
1578            #[inline]
1579            fn $method(self, rhs: &$rhs) -> Self::Output {
1580                <$lhs as $op<$rhs>>::$method(self, *rhs)
1581            }
1582        }
1583        #[automatically_derived]
1584        impl<$($generics)*> $op<&$rhs> for &$lhs where $($where)* {
1585            type Output = $lhs;
1586            #[inline]
1587            fn $method(self, rhs: &$rhs) -> Self::Output {
1588                <$lhs as $op<$rhs>>::$method(*self, *rhs)
1589            }
1590        }
1591
1592        #[automatically_derived]
1593        impl<$($generics)*> $op_assign<$rhs> for $lhs where $($where)* {
1594            #[inline]
1595            fn $method_assign(&mut self, rhs: $rhs) {
1596                *self = <Self as $op<$rhs>>::$method(*self, rhs);
1597            }
1598        }
1599        #[automatically_derived]
1600        impl<$($generics)*> $op_assign<&$rhs> for $lhs where $($where)* {
1601            #[inline]
1602            fn $method_assign(&mut self, rhs: &$rhs) {
1603                *self = <Self as $op<$rhs>>::$method(*self, *rhs);
1604            }
1605        }
1606    };
1607
1608    (@fmt_traits($ty:ty, $inner:ty)
1609        $(([$($generics:tt)*] where $($where:tt)*) $trait:ident,)*
1610    ) => { $(
1611        #[automatically_derived]
1612        impl<$($generics)*> fmt::$trait for $ty where $($where)* {
1613            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1614                fmt::$trait::fmt(&self.get(), f)
1615            }
1616        }
1617    )* }
1618}
1619
1620// Most functionality is tested in `types.rs`. But there are some things that API cannot do.
1621#[cfg(test)]
1622mod tests {
1623    use crate::unsafe_api;
1624    use core::ffi::c_int;
1625    use core::marker::PhantomData;
1626
1627    #[test]
1628    fn c_int() {
1629        #[repr(transparent)]
1630        struct S(c_int);
1631
1632        unsafe_api! {
1633            for S,
1634            unsafe repr: {
1635                type: c_int,
1636                signed: true,
1637                supersets: [i32, i64, i128],
1638                non_supersets: [],
1639                has_wide,
1640            },
1641            min: -5,
1642            max: 5,
1643            zero,
1644        }
1645    }
1646
1647    #[test]
1648    fn where_clause() {
1649        #[repr(transparent)]
1650        struct S<T: Copy>(i32, PhantomData<T>);
1651
1652        unsafe_api! {
1653            [T] for S<T> where { T: Copy },
1654            unsafe repr: i32,
1655            min: -1,
1656            max: i32::MAX,
1657            zero,
1658            one,
1659        }
1660    }
1661
1662    #[test]
1663    fn attr() {
1664        #[deprecated]
1665        #[repr(transparent)]
1666        struct S(i32);
1667
1668        unsafe_api! {
1669            #![allow(deprecated)]
1670            for S,
1671            unsafe repr: i32,
1672            min: 0,
1673            max: 1,
1674            zero,
1675            one,
1676        }
1677    }
1678}