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            /// Returns the value of the bounded integer as a primitive type.
339            #[must_use]
340            #[inline]
341            pub const fn get(self) -> $inner {
342                unsafe { ::core::mem::transmute(self) }
343            }
344
345            /// Returns a shared reference to the value of the bounded integer.
346            #[must_use]
347            #[inline]
348            pub const fn get_ref(&self) -> &$inner {
349                unsafe { &*<*const _>::cast(self) }
350            }
351
352            /// Returns a mutable reference to the value of the bounded integer.
353            ///
354            /// # Safety
355            ///
356            /// This value must never be set to a value beyond the range of the bounded integer.
357            #[must_use]
358            #[inline]
359            pub const unsafe fn get_mut(&mut self) -> &mut $inner {
360                unsafe { &mut *<*mut _>::cast(self) }
361            }
362
363            $($(if $signed)?
364                /// Computes the absolute value of `self`, panicking if it is out of range.
365                #[must_use]
366                #[inline]
367                pub const fn abs(self) -> Self {
368                    Self::new(self.get().abs()).expect("Absolute value out of range")
369                }
370            )*
371
372            /// Raises `self` to the power of `exp`, using exponentiation by squaring. Panics if it
373            /// is out of range.
374            #[must_use]
375            #[inline]
376            pub const fn pow(self, exp: u32) -> Self {
377                Self::new(self.get().pow(exp)).expect("Value raised to power out of range")
378            }
379
380            /// Calculates the quotient of Euclidean division of `self` by `rhs`. Panics if `rhs`
381            /// is 0 or the result is out of range.
382            #[must_use]
383            #[inline]
384            pub const fn div_euclid(self, rhs: $inner) -> Self {
385                Self::new(self.get().div_euclid(rhs)).expect("Attempted to divide out of range")
386            }
387
388            /// Calculates the least nonnegative remainder of `self (mod rhs)`. Panics if `rhs` is 0
389            /// or the result is out of range.
390            #[must_use]
391            #[inline]
392            pub const fn rem_euclid(self, rhs: $inner) -> Self {
393                Self::new(self.get().rem_euclid(rhs))
394                    .expect("Attempted to divide with remainder out of range")
395            }
396
397            /// Checked integer addition.
398            ///
399            /// Returns `None` if the result would be out of range.
400            #[must_use]
401            #[inline]
402            pub const fn checked_add(self, rhs: $inner) -> Option<Self> {
403                match self.get().checked_add(rhs) {
404                    Some(val) => Self::new(val),
405                    None => None,
406                }
407            }
408
409            /// Saturating integer addition.
410            #[must_use]
411            #[inline]
412            pub const fn saturating_add(self, rhs: $inner) -> Self {
413                Self::new_saturating(self.get().saturating_add(rhs))
414            }
415
416            /// Wrapping (modular) integer addition.
417            #[must_use]
418            #[inline]
419            #[cfg(not(all($($(if $has_wide)? false)?)))]
420            pub const fn wrapping_add(self, rhs: $inner) -> Self {
421                Self::new_wrapping((self.get() as Wide<$inner>) + (rhs as Wide<$inner>))
422            }
423
424            /// Checked integer subtraction.
425            ///
426            /// Returns `None` if the result would be out of range.
427            #[must_use]
428            #[inline]
429            pub const fn checked_sub(self, rhs: $inner) -> Option<Self> {
430                match self.get().checked_sub(rhs) {
431                    Some(val) => Self::new(val),
432                    None => None,
433                }
434            }
435
436            /// Saturating integer subtraction.
437            #[must_use]
438            #[inline]
439            pub const fn saturating_sub(self, rhs: $inner) -> Self {
440                Self::new_saturating(self.get().saturating_sub(rhs))
441            }
442
443            /// Wrapping (modular) integer subtraction.
444            #[must_use]
445            #[inline]
446            #[cfg(not(all($($(if $has_wide)? false)?)))]
447            pub const fn wrapping_sub(self, rhs: $inner) -> Self {
448                Self::new_wrapping(
449                    (self.get() as Signed<Wide<$inner>>) - (rhs as Signed<Wide<$inner>>)
450                )
451            }
452
453            /// Checked integer multiplication.
454            ///
455            /// Returns `None` if the result would be out of range.
456            #[must_use]
457            #[inline]
458            pub const fn checked_mul(self, rhs: $inner) -> Option<Self> {
459                match self.get().checked_mul(rhs) {
460                    Some(val) => Self::new(val),
461                    None => None,
462                }
463            }
464
465            /// Saturating integer multiplication.
466            #[must_use]
467            #[inline]
468            pub const fn saturating_mul(self, rhs: $inner) -> Self {
469                Self::new_saturating(self.get().saturating_mul(rhs))
470            }
471
472            /// Wrapping (modular) integer multiplication.
473            #[must_use]
474            #[inline]
475            #[cfg(not(all($($(if $has_wide)? false)?)))]
476            pub const fn wrapping_mul(self, rhs: $inner) -> Self {
477                Self::new_wrapping((self.get() as Wide<$inner>) * (rhs as Wide<$inner>))
478            }
479
480            /// Checked integer division.
481            ///
482            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
483            #[must_use]
484            #[inline]
485            pub const fn checked_div(self, rhs: $inner) -> Option<Self> {
486                match self.get().checked_div(rhs) {
487                    Some(val) => Self::new(val),
488                    None => None,
489                }
490            }
491
492            /// Wrapping (modular) integer division.
493            #[must_use]
494            #[inline]
495            #[cfg(not(all($($(if $has_wide)? false)?)))]
496            pub const fn wrapping_div(self, rhs: $inner) -> Self {
497                // We need to widen for the case of `$inner::MIN / −1`.
498                Self::new_wrapping((self.get() as Wide<$inner>) / (rhs as Wide<$inner>))
499            }
500
501            /// Checked Euclidean division.
502            ///
503            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
504            #[must_use]
505            #[inline]
506            pub const fn checked_div_euclid(self, rhs: $inner) -> Option<Self> {
507                match self.get().checked_div_euclid(rhs) {
508                    Some(val) => Self::new(val),
509                    None => None,
510                }
511            }
512
513            /// Wrapping (modular) Euclidean division.
514            #[must_use]
515            #[inline]
516            #[cfg(not(all($($(if $has_wide)? false)?)))]
517            pub const fn wrapping_div_euclid(self, rhs: $inner) -> Self {
518                // We need to widen for the case of `$inner::MIN / −1`.
519                Self::new_wrapping((self.get() as Wide<$inner>).div_euclid(rhs as Wide<$inner>))
520            }
521
522            /// Checked integer remainder.
523            ///
524            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
525            #[must_use]
526            #[inline]
527            pub const fn checked_rem(self, rhs: $inner) -> Option<Self> {
528                match self.get().checked_rem(rhs) {
529                    Some(val) => Self::new(val),
530                    None => None,
531                }
532            }
533
534            /// Wrapping (modular) integer remainder.
535            #[must_use]
536            #[inline]
537            #[cfg(not(all($($(if $has_wide)? false)?)))]
538            pub const fn wrapping_rem(self, rhs: $inner) -> Self {
539                // We need to widen for the case of `$inner::MIN % −1`.
540                Self::new_wrapping((self.get() as Wide<$inner>) % (rhs as Wide<$inner>))
541            }
542
543            /// Checked Euclidean remainder.
544            ///
545            /// Returns `None` if the result would be out of range, or if `rhs` is zero.
546            #[must_use]
547            #[inline]
548            pub const fn checked_rem_euclid(self, rhs: $inner) -> Option<Self> {
549                match self.get().checked_rem_euclid(rhs) {
550                    Some(val) => Self::new(val),
551                    None => None,
552                }
553            }
554
555            /// Wrapping (modular) Euclidean remainder.
556            #[must_use]
557            #[inline]
558            #[cfg(not(all($($(if $has_wide)? false)?)))]
559            pub const fn wrapping_rem_euclid(self, rhs: $inner) -> Self {
560                // We need to widen for the case of `$inner::MIN % −1`.
561                Self::new_wrapping((self.get() as Wide<$inner>).rem_euclid(rhs as Wide<$inner>))
562            }
563
564            /// Checked negation.
565            ///
566            /// Returns `None` if the result would be out of range.
567            #[must_use]
568            #[inline]
569            pub const fn checked_neg(self) -> Option<Self> {
570                match self.get().checked_neg() {
571                    Some(val) => Self::new(val),
572                    None => None,
573                }
574            }
575
576            /// Saturating negation.
577            #[must_use]
578            #[inline]
579            #[cfg(not(all($($(if $signed)? false)?)))]
580            pub const fn saturating_neg(self) -> Self {
581                Self::new_saturating(self.get().saturating_neg())
582            }
583
584            /// Wrapping (modular) negation.
585            #[must_use]
586            #[inline]
587            #[cfg(not(all($($(if $signed)? false)?)))]
588            #[cfg(not(all($($(if $has_wide)? false)?)))]
589            pub const fn wrapping_neg(self) -> Self {
590                Self::new_wrapping(-(self.get() as Wide<$inner>))
591            }
592
593            /// Checked absolute value.
594            #[must_use]
595            #[inline]
596            #[cfg(not(all($($(if $signed)? false)?)))]
597            pub const fn checked_abs(self) -> Option<Self> {
598                match self.get().checked_abs() {
599                    Some(val) => Self::new(val),
600                    None => None,
601                }
602            }
603
604            /// Saturating absolute value.
605            #[must_use]
606            #[inline]
607            #[cfg(not(all($($(if $signed)? false)?)))]
608            pub const fn saturating_abs(self) -> Self {
609                Self::new_saturating(self.get().saturating_abs())
610            }
611
612            /// Wrapping (modular) absolute value.
613            #[must_use]
614            #[inline]
615            #[cfg(not(all($($(if $signed)? false)?)))]
616            #[cfg(not(all($($(if $has_wide)? false)?)))]
617            pub const fn wrapping_abs(self) -> Self {
618                Self::new_wrapping((self.get() as Wide<$inner>).abs())
619            }
620
621            /// Checked exponentiation.
622            #[must_use]
623            #[inline]
624            pub const fn checked_pow(self, rhs: u32) -> Option<Self> {
625                match self.get().checked_pow(rhs) {
626                    Some(val) => Self::new(val),
627                    None => None,
628                }
629            }
630
631            /// Saturating exponentiation.
632            #[must_use]
633            #[inline]
634            pub const fn saturating_pow(self, rhs: u32) -> Self {
635                Self::new_saturating(self.get().saturating_pow(rhs))
636            }
637
638            /// Wrapping (modular) exponentiation.
639            #[must_use]
640            #[inline]
641            #[cfg(not(all($($(if $has_wide)? false)?)))]
642            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
643                let range_sub_one = Self::MAX_VALUE.abs_diff(Self::MIN_VALUE);
644                let Some(range) = range_sub_one.checked_add(1) else {
645                    return unsafe { Self::new_unchecked(self.get().wrapping_pow(exp)) };
646                };
647
648                // Exponentiation by squaring (same algorithm as used in std), but taking modulo
649                // each time. We keep our values in the range [0, MAX − MIN].
650                if exp == 0 {
651                    return Self::new_wrapping::<$inner>(1);
652                }
653                let mut base = self.get() as Wide<$inner>;
654                let mut acc: Wide<$inner> = 1;
655                let range = range as Wide<$inner>;
656                loop {
657                    if (exp & 1) == 1 {
658                        acc = (acc * base).rem_euclid(range);
659                        if exp == 1 {
660                            return Self::new_wrapping(acc);
661                        }
662                    }
663                    exp /= 2;
664                    base = (base * base).rem_euclid(range);
665                }
666            }
667
668            /// Checked shift left.
669            #[must_use]
670            #[inline]
671            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
672                match self.get().checked_shl(rhs) {
673                    Some(val) => Self::new(val),
674                    None => None,
675                }
676            }
677
678            /// Checked shift right.
679            #[must_use]
680            #[inline]
681            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
682                match self.get().checked_shr(rhs) {
683                    Some(val) => Self::new(val),
684                    None => None,
685                }
686            }
687        }
688
689        pub trait LargerInt: Copy {
690            const KIND: &'static str;
691        }
692
693        $(#[automatically_derived]
694        impl LargerInt for $super { const KIND: &'static str = stringify!($super); })*
695
696        $crate::__unsafe_api_internal!(@with_super($ty, $inner)
697            $({ super: $super, generics: $generics_single_token })*
698        );
699        $crate::__unsafe_api_internal!(@with_non_super($ty, $inner)
700            $({ non_super: $non_super, generics: $generics_single_token })*
701        );
702        $crate::__unsafe_api_internal!(@with_all_int($ty, $inner)
703            { int: u8, generics: $generics_single_token }
704            { int: u16, generics: $generics_single_token }
705            { int: u32, generics: $generics_single_token }
706            { int: u64, generics: $generics_single_token }
707            { int: u128, generics: $generics_single_token }
708            { int: usize, generics: $generics_single_token }
709            { int: i8, generics: $generics_single_token }
710            { int: i16, generics: $generics_single_token }
711            { int: i32, generics: $generics_single_token }
712            { int: i64, generics: $generics_single_token }
713            { int: i128, generics: $generics_single_token }
714            { int: isize, generics: $generics_single_token }
715        );
716
717        // === Clone / Copy ===
718
719        #[automatically_derived]
720        impl<$($generics)*> Clone for $ty where $($where)* {
721            fn clone(&self) -> Self { *self }
722        }
723        #[automatically_derived]
724        impl<$($generics)*> Copy for $ty where $($where)* {}
725
726        // === Default ===
727
728        #[cfg(not(all($($($zero)? false)?)))]
729        #[automatically_derived]
730        impl<$($generics)*> Default for $ty where $($where)* {
731            fn default() -> Self {
732                const {
733                    Self::new(0).expect("used `zero` on a type whose range does not include zero")
734                }
735            }
736        }
737
738        // Use a function to force post-mono errors even if `num-traits02` is disabled.
739        #[cfg(not(all($($($one)? false)?)))]
740        impl<$($generics)*> $ty where $($where)* {
741            #[allow(unused)]
742            fn one() -> Self {
743                const {
744                    Self::new(1).expect("used `one` on a type whose range does not include one")
745                }
746            }
747        }
748
749        // === Operators ===
750
751        $crate::__unsafe_api_internal!(@bin_ops($ty, $inner)
752            ($generics_single_token, Add::add/AddAssign::add_assign, "add"),
753            ($generics_single_token, Sub::sub/SubAssign::sub_assign, "subtract"),
754            ($generics_single_token, Mul::mul/MulAssign::mul_assign, "multiply"),
755            ($generics_single_token, Div::div/DivAssign::div_assign, "divide"),
756            ($generics_single_token, Rem::rem/RemAssign::rem_assign, "take remainder"),
757            ($generics_single_token, BitAnd::bitand/BitAndAssign::bitand_assign, "binary and"),
758            ($generics_single_token, BitOr::bitor/BitOrAssign::bitor_assign, "binary or"),
759            ($generics_single_token, BitXor::bitxor/BitXorAssign::bitxor_assign, "binary xor"),
760        );
761        use ::core::ops::{Shl, Shr, ShlAssign, ShrAssign};
762        #[automatically_derived]
763        impl<$($generics)*> Shl<u32> for $ty where $($where)* {
764            type Output = Self;
765            #[inline]
766            fn shl(self, rhs: u32) -> Self::Output {
767                Self::new(self.get().shl(rhs))
768                    .expect("Attempted to shift left out of range")
769            }
770        }
771        $crate::__unsafe_api_internal!(@bin_op_variations
772            $generics_single_token,
773            $ty, u32, Shl::shl/ShlAssign::shl_assign
774        );
775        #[automatically_derived]
776        impl<$($generics)*> Shr<u32> for $ty where $($where)* {
777            type Output = Self;
778            #[inline]
779            fn shr(self, rhs: u32) -> Self::Output {
780                Self::new(self.get().shr(rhs))
781                    .expect("Attempted to shift right out of range")
782            }
783        }
784        $crate::__unsafe_api_internal!(@bin_op_variations
785            $generics_single_token,
786            $ty, u32, Shr::shr/ShrAssign::shr_assign
787        );
788
789        #[cfg(not(all($($(if $signed)? false)?)))]
790        use ::core::ops::Neg;
791
792        #[cfg(not(all($($(if $signed)? false)?)))]
793        #[automatically_derived]
794        impl<$($generics)*> Neg for $ty where $($where)* {
795            type Output = Self;
796            #[inline]
797            fn neg(self) -> Self::Output {
798                Self::new(-self.get())
799                    .expect("Attempted to negate out of range")
800            }
801        }
802        #[cfg(not(all($($(if $signed)? false)?)))]
803        #[automatically_derived]
804        impl<$($generics)*> Neg for &$ty where $($where)* {
805            type Output = $ty;
806            #[inline]
807            fn neg(self) -> Self::Output {
808                -*self
809            }
810        }
811
812        use ::core::ops::Not;
813
814        #[automatically_derived]
815        impl<$($generics)*> Not for $ty where $($where)* {
816            type Output = Self;
817            #[inline]
818            fn not(self) -> Self::Output {
819                Self::new(!self.get())
820                    .expect("Attempted to invert bits out of range")
821            }
822        }
823        #[automatically_derived]
824        impl<$($generics)*> Not for &$ty where $($where)* {
825            type Output = $ty;
826            #[inline]
827            fn not(self) -> Self::Output {
828                !*self
829            }
830        }
831
832        // === Comparisons and Hash ===
833
834        #[automatically_derived]
835        impl<$($generics)*> PartialEq<$inner> for $ty where $($where)* {
836            #[inline]
837            fn eq(&self, other: &$inner) -> bool {
838                self.get() == *other
839            }
840        }
841        #[automatically_derived]
842        impl<$($generics)*> PartialEq<$ty> for $inner where $($where)* {
843            #[inline]
844            fn eq(&self, other: &$ty) -> bool {
845                *self == other.get()
846            }
847        }
848        #[automatically_derived]
849        impl<$($generics)*> PartialEq for $ty where $($where)* {
850            #[inline]
851            fn eq(&self, other: &$ty) -> bool {
852                self.get() == other.get()
853            }
854        }
855        #[automatically_derived]
856        impl<$($generics)*> Eq for $ty where $($where)* {}
857
858        #[automatically_derived]
859        impl<$($generics)*> PartialOrd<$inner> for $ty where $($where)* {
860            #[inline]
861            fn partial_cmp(&self, other: &$inner) -> Option<cmp::Ordering> {
862                self.get().partial_cmp(other)
863            }
864        }
865        #[automatically_derived]
866        impl<$($generics)*> PartialOrd<$ty> for $inner where $($where)* {
867            #[inline]
868            fn partial_cmp(&self, other: &$ty) -> Option<cmp::Ordering> {
869                self.partial_cmp(&other.get())
870            }
871        }
872        #[automatically_derived]
873        impl<$($generics)*> PartialOrd for $ty where $($where)* {
874            #[inline]
875            fn partial_cmp(&self, other: &$ty) -> Option<cmp::Ordering> {
876                Some(self.cmp(other))
877            }
878        }
879        #[automatically_derived]
880        impl<$($generics)*> Ord for $ty where $($where)* {
881            #[inline]
882            fn cmp(&self, other: &$ty) -> cmp::Ordering {
883                self.get().cmp(&other.get())
884            }
885        }
886
887        #[automatically_derived]
888        impl<$($generics)*> Hash for $ty where $($where)* {
889            #[inline]
890            fn hash<H: Hasher>(&self, state: &mut H) {
891                self.get().hash(state);
892            }
893        }
894
895        // === AsRef, Borrow ===
896
897        #[automatically_derived]
898        impl<$($generics)*> AsRef<$inner> for $ty where $($where)* {
899            #[inline]
900            fn as_ref(&self) -> &$inner {
901                self.get_ref()
902            }
903        }
904        #[automatically_derived]
905        impl<$($generics)*> Borrow<$inner> for $ty where $($where)* {
906            #[inline]
907            fn borrow(&self) -> &$inner {
908                self.get_ref()
909            }
910        }
911
912        // === Iterator traits ===
913
914        // Sum bounded to bounded
915        #[automatically_derived]
916        impl<$($generics)*> iter::Sum for $ty where $($where)* {
917            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
918                iter.reduce(Add::add)
919                    .unwrap_or_else(|| Self::new(0).expect("Attempted to sum to zero"))
920            }
921        }
922        #[automatically_derived]
923        impl<'__a, $($generics)*> iter::Sum<&'__a Self> for $ty where $($where)* {
924            fn sum<I: Iterator<Item = &'__a Self>>(iter: I) -> Self {
925                iter.copied().sum()
926            }
927        }
928
929        // Sum bounded to primitive
930        #[automatically_derived]
931        impl<$($generics)*> iter::Sum<$ty> for $inner where $($where)* {
932            fn sum<I: Iterator<Item = $ty>>(iter: I) -> Self {
933                iter.map(<$ty>::get).sum()
934            }
935        }
936        #[automatically_derived]
937        impl<'__a, $($generics)*> iter::Sum<&'__a $ty> for $inner where $($where)* {
938            fn sum<I: Iterator<Item = &'__a $ty>>(iter: I) -> Self {
939                iter.copied().sum()
940            }
941        }
942
943        // Take product of bounded to bounded
944        #[automatically_derived]
945        impl<$($generics)*> iter::Product for $ty where $($where)* {
946            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
947                iter.reduce(Mul::mul)
948                    .unwrap_or_else(|| Self::new(1).expect("Attempted to take product to one"))
949            }
950        }
951        #[automatically_derived]
952        impl<'__a, $($generics)*> iter::Product<&'__a Self> for $ty where $($where)* {
953            fn product<I: Iterator<Item = &'__a Self>>(iter: I) -> Self {
954                iter.copied().product()
955            }
956        }
957
958        // Take product of bounded to primitive
959        #[automatically_derived]
960        impl<$($generics)*> iter::Product<$ty> for $inner where $($where)* {
961            fn product<I: Iterator<Item = $ty>>(iter: I) -> Self {
962                iter.map(<$ty>::get).product()
963            }
964        }
965        #[automatically_derived]
966        impl<'__a, $($generics)*> iter::Product<&'__a $ty> for $inner where $($where)* {
967            fn product<I: Iterator<Item = &'__a $ty>>(iter: I) -> Self {
968                iter.copied().product()
969            }
970        }
971
972        $crate::__private::__cfg_step_trait! {
973            #[automatically_derived]
974            impl<$($generics)*> iter::Step for $ty where $($where)* {
975                #[inline]
976                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
977                    iter::Step::steps_between(&start.get(), &end.get())
978                }
979                #[inline]
980                fn forward_checked(start: Self, count: usize) -> Option<Self> {
981                    iter::Step::forward_checked(start.get(), count).and_then(Self::new)
982                }
983                #[inline]
984                fn backward_checked(start: Self, count: usize) -> Option<Self> {
985                    iter::Step::backward_checked(start.get(), count).and_then(Self::new)
986                }
987            }
988        }
989
990        // === Parsing ===
991
992        #[automatically_derived]
993        impl<$($generics)*> FromStr for $ty where $($where)* {
994            type Err = ParseError;
995            fn from_str(s: &str) -> Result<Self, Self::Err> {
996                Self::from_str_radix(s, 10)
997            }
998        }
999
1000        // === Formatting ===
1001
1002        #[automatically_derived]
1003        impl<$($generics)*> fmt::Debug for $ty where $($where)* {
1004            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1005                f.debug_tuple("Bounded").field(&self.get()).finish()
1006            }
1007        }
1008
1009        $crate::__unsafe_api_internal!(@fmt_traits($ty, $inner)
1010            $generics_single_token Binary,
1011            $generics_single_token Display,
1012            $generics_single_token LowerExp,
1013            $generics_single_token LowerHex,
1014            $generics_single_token Octal,
1015            $generics_single_token UpperExp,
1016            $generics_single_token UpperHex,
1017        );
1018
1019        // === Arbitrary ===
1020
1021        $crate::__private::__cfg_arbitrary1! {
1022            use $crate::__private::arbitrary1::{self, Arbitrary, Unstructured};
1023
1024            #[automatically_derived]
1025            impl<'__a, $($generics)*> Arbitrary<'__a> for $ty where $($where)* {
1026                fn arbitrary(u: &mut Unstructured<'__a>) -> arbitrary1::Result<Self> {
1027                    Self::new(u.arbitrary()?).ok_or(arbitrary1::Error::IncorrectFormat)
1028                }
1029
1030                #[inline]
1031                fn size_hint(depth: usize) -> (usize, Option<usize>) {
1032                    <$inner as Arbitrary<'__a>>::size_hint(depth)
1033                }
1034            }
1035        }
1036
1037        // === Bytemuck ===
1038
1039        $crate::__private::__cfg_bytemuck1! {
1040            use $crate::__private::bytemuck1;
1041
1042            #[automatically_derived]
1043            unsafe impl<$($generics)*> bytemuck1::Contiguous for $ty
1044            where
1045                Self: 'static,
1046                $($where)*
1047            {
1048                type Int = $inner;
1049                const MAX_VALUE: $inner = Self::MAX_VALUE;
1050                const MIN_VALUE: $inner = Self::MIN_VALUE;
1051            }
1052
1053            #[automatically_derived]
1054            unsafe impl<$($generics)*> bytemuck1::NoUninit for $ty
1055            where
1056                Self: 'static,
1057                $($where)*
1058            {}
1059
1060            #[cfg(not(all($($(if $zero)? false)?)))]
1061            #[automatically_derived]
1062            unsafe impl<$($generics)*> bytemuck1::Zeroable for $ty where $($where)* {}
1063        }
1064
1065        // === Num ===
1066
1067        $crate::__private::__cfg_num_traits02! {
1068            use $crate::__private::num_traits02;
1069
1070            #[automatically_derived]
1071            impl<$($generics)*> num_traits02::Bounded for $ty where $($where)* {
1072                fn min_value() -> Self {
1073                    Self::MIN
1074                }
1075                fn max_value() -> Self {
1076                    Self::MAX
1077                }
1078            }
1079
1080            #[automatically_derived]
1081            impl<__T, $($generics)*> num_traits02::AsPrimitive<__T> for $ty
1082            where
1083                $inner: num_traits02::AsPrimitive<__T>,
1084                __T: 'static + Copy,
1085                Self: 'static,
1086                $($where)*
1087            {
1088                fn as_(self) -> __T {
1089                    self.get().as_()
1090                }
1091            }
1092
1093            #[automatically_derived]
1094            impl<$($generics)*> num_traits02::FromPrimitive for $ty
1095            where
1096                $inner: num_traits02::FromPrimitive,
1097                $($where)*
1098            {
1099                fn from_i64(n: i64) -> Option<Self> {
1100                    <$inner>::from_i64(n).and_then(Self::new)
1101                }
1102                fn from_u64(n: u64) -> Option<Self> {
1103                    <$inner>::from_u64(n).and_then(Self::new)
1104                }
1105                fn from_isize(n: isize) -> Option<Self> {
1106                    <$inner>::from_isize(n).and_then(Self::new)
1107                }
1108                fn from_i8(n: i8) -> Option<Self> {
1109                    <$inner>::from_i8(n).and_then(Self::new)
1110                }
1111                fn from_i16(n: i16) -> Option<Self> {
1112                    <$inner>::from_i16(n).and_then(Self::new)
1113                }
1114                fn from_i32(n: i32) -> Option<Self> {
1115                    <$inner>::from_i32(n).and_then(Self::new)
1116                }
1117                fn from_i128(n: i128) -> Option<Self> {
1118                    <$inner>::from_i128(n).and_then(Self::new)
1119                }
1120                fn from_usize(n: usize) -> Option<Self> {
1121                    <$inner>::from_usize(n).and_then(Self::new)
1122                }
1123                fn from_u8(n: u8) -> Option<Self> {
1124                    <$inner>::from_u8(n).and_then(Self::new)
1125                }
1126                fn from_u16(n: u16) -> Option<Self> {
1127                    <$inner>::from_u16(n).and_then(Self::new)
1128                }
1129                fn from_u32(n: u32) -> Option<Self> {
1130                    <$inner>::from_u32(n).and_then(Self::new)
1131                }
1132                fn from_u128(n: u128) -> Option<Self> {
1133                    <$inner>::from_u128(n).and_then(Self::new)
1134                }
1135                fn from_f32(n: f32) -> Option<Self> {
1136                    <$inner>::from_f32(n).and_then(Self::new)
1137                }
1138                fn from_f64(n: f64) -> Option<Self> {
1139                    <$inner>::from_f64(n).and_then(Self::new)
1140                }
1141            }
1142
1143            #[automatically_derived]
1144            impl<$($generics)*> num_traits02::NumCast for $ty
1145            where
1146                $inner: num_traits02::NumCast,
1147                $($where)*
1148            {
1149                fn from<__T: num_traits02::ToPrimitive>(n: __T) -> Option<Self> {
1150                    <$inner as num_traits02::NumCast>::from(n).map(Self::new).flatten()
1151                }
1152            }
1153
1154            #[automatically_derived]
1155            impl<$($generics)*> num_traits02::ToPrimitive for $ty
1156            where
1157                $inner: num_traits02::ToPrimitive,
1158                $($where)*
1159            {
1160                fn to_i64(&self) -> Option<i64> {
1161                    self.get().to_i64()
1162                }
1163                fn to_u64(&self) -> Option<u64> {
1164                    self.get().to_u64()
1165                }
1166                fn to_isize(&self) -> Option<isize> {
1167                    self.get().to_isize()
1168                }
1169                fn to_i8(&self) -> Option<i8> {
1170                    self.get().to_i8()
1171                }
1172                fn to_i16(&self) -> Option<i16> {
1173                    self.get().to_i16()
1174                }
1175                fn to_i32(&self) -> Option<i32> {
1176                    self.get().to_i32()
1177                }
1178                fn to_i128(&self) -> Option<i128> {
1179                    self.get().to_i128()
1180                }
1181                fn to_usize(&self) -> Option<usize> {
1182                    self.get().to_usize()
1183                }
1184                fn to_u8(&self) -> Option<u8> {
1185                    self.get().to_u8()
1186                }
1187                fn to_u16(&self) -> Option<u16> {
1188                    self.get().to_u16()
1189                }
1190                fn to_u32(&self) -> Option<u32> {
1191                    self.get().to_u32()
1192                }
1193                fn to_u128(&self) -> Option<u128> {
1194                    self.get().to_u128()
1195                }
1196                fn to_f32(&self) -> Option<f32> {
1197                    self.get().to_f32()
1198                }
1199                fn to_f64(&self) -> Option<f64> {
1200                    self.get().to_f64()
1201                }
1202            }
1203
1204            #[automatically_derived]
1205            impl<$($generics)*> num_traits02::CheckedAdd for $ty where $($where)* {
1206                fn checked_add(&self, v: &Self) -> Option<Self> {
1207                    Self::checked_add(*self, v.get())
1208                }
1209            }
1210
1211            #[automatically_derived]
1212            impl<$($generics)*> num_traits02::CheckedDiv for $ty where $($where)* {
1213                fn checked_div(&self, v: &Self) -> Option<Self> {
1214                    Self::checked_div(*self, v.get())
1215                }
1216            }
1217
1218            #[automatically_derived]
1219            impl<$($generics)*> num_traits02::CheckedMul for $ty where $($where)* {
1220                fn checked_mul(&self, v: &Self) -> Option<Self> {
1221                    Self::checked_mul(*self, v.get())
1222                }
1223            }
1224
1225            #[automatically_derived]
1226            impl<$($generics)*> num_traits02::CheckedNeg for $ty where $($where)* {
1227                fn checked_neg(&self) -> Option<Self> {
1228                    Self::checked_neg(*self)
1229                }
1230            }
1231
1232            #[automatically_derived]
1233            impl<$($generics)*> num_traits02::CheckedRem for $ty where $($where)* {
1234                fn checked_rem(&self, v: &Self) -> Option<Self> {
1235                    Self::checked_rem(*self, v.get())
1236                }
1237            }
1238
1239            #[automatically_derived]
1240            impl<$($generics)*> num_traits02::CheckedShl for $ty where $($where)* {
1241                fn checked_shl(&self, v: u32) -> Option<Self> {
1242                    Self::checked_shl(*self, v)
1243                }
1244            }
1245
1246            #[automatically_derived]
1247            impl<$($generics)*> num_traits02::CheckedShr for $ty where $($where)* {
1248                fn checked_shr(&self, v: u32) -> Option<Self> {
1249                    Self::checked_shr(*self, v)
1250                }
1251            }
1252
1253            #[automatically_derived]
1254            impl<$($generics)*> num_traits02::CheckedSub for $ty where $($where)* {
1255                fn checked_sub(&self, v: &Self) -> Option<Self> {
1256                    Self::checked_sub(*self, v.get())
1257                }
1258            }
1259
1260            #[automatically_derived]
1261            impl<__A, __B, $($generics)*> num_traits02::MulAdd<__A, __B> for $ty
1262            where
1263                $inner: num_traits02::MulAdd<__A, __B, Output = $inner>,
1264                $($where)*
1265            {
1266                type Output = $inner;
1267
1268                fn mul_add(self, a: __A, b: __B) -> Self::Output {
1269                    self.get().mul_add(a, b)
1270                }
1271            }
1272
1273            #[automatically_derived]
1274            impl<$($generics)*> num_traits02::SaturatingAdd for $ty where $($where)* {
1275                fn saturating_add(&self, v: &Self) -> Self {
1276                    Self::saturating_add(*self, v.get())
1277                }
1278            }
1279
1280            #[automatically_derived]
1281            impl<$($generics)*> num_traits02::SaturatingMul for $ty where $($where)* {
1282                fn saturating_mul(&self, v: &Self) -> Self {
1283                    Self::saturating_mul(*self, v.get())
1284                }
1285            }
1286
1287            #[automatically_derived]
1288            impl<$($generics)*> num_traits02::SaturatingSub for $ty where $($where)* {
1289                fn saturating_sub(&self, v: &Self) -> Self {
1290                    Self::saturating_sub(*self, v.get())
1291                }
1292            }
1293
1294            #[cfg(not(all($($($zero)? false)?)))]
1295            #[automatically_derived]
1296            impl<$($generics)*> num_traits02::Zero for $ty where $($where)* {
1297                fn zero() -> Self {
1298                    Self::default()
1299                }
1300                fn is_zero(&self) -> bool {
1301                    self.get() == 0
1302                }
1303            }
1304
1305            #[cfg(not(all($($($one)? false)?)))]
1306            #[automatically_derived]
1307            impl<$($generics)*> num_traits02::One for $ty where $($where)* {
1308                fn one() -> Self {
1309                    Self::one()
1310                }
1311            }
1312        }
1313
1314        // === Serde ===
1315
1316        $crate::__private::__cfg_serde1! {
1317            use $crate::__private::serde1::{self, Deserialize, Deserializer, Serialize, Serializer};
1318
1319            #[automatically_derived]
1320            impl<$($generics)*> Serialize for $ty where $($where)* {
1321                fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1322                    self.get().serialize(serializer)
1323                }
1324            }
1325
1326            // Disable this to prevent triggering `clippy::unsafe_derive_deserialize`. I couldn’t
1327            // figure out how to `#[allow]` it.
1328            // #[automatically_derived]
1329            impl<'__de, $($generics)*> Deserialize<'__de> for $ty where $($where)* {
1330                fn deserialize<D: Deserializer<'__de>>(deserializer: D) -> Result<Self, D::Error> {
1331                    Self::new(<$inner>::deserialize(deserializer)?)
1332                        .ok_or_else(|| {
1333                            <D::Error as serde1::de::Error>::custom(format_args!(
1334                                "integer out of range, expected it to be between {} and {}",
1335                                Self::MIN_VALUE,
1336                                Self::MAX_VALUE,
1337                            ))
1338                        })
1339                }
1340            }
1341        }
1342    }; };
1343
1344    (@repr u8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1345        @repr {
1346            type: u8,
1347            signed: false,
1348            supersets: [u8, u16, u32, u64, u128, usize, i16, i32, i64, i128, isize],
1349            non_supersets: [i8],
1350            has_wide,
1351        },
1352        $($rest)*
1353    } };
1354    (@repr u16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1355        @repr {
1356            type: u16,
1357            signed: false,
1358            supersets: [u16, u32, u64, u128, usize, i32, i64, i128],
1359            non_supersets: [u8, i8, i16, isize],
1360            has_wide,
1361        },
1362        $($rest)*
1363    } };
1364    (@repr u32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1365        @repr {
1366            type: u32,
1367            signed: false,
1368            supersets: [u32, u64, u128, i64, i128],
1369            non_supersets: [u8, u16, usize, i8, i16, i32, isize],
1370            has_wide,
1371        },
1372        $($rest)*
1373    } };
1374    (@repr u64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1375        @repr {
1376            type: u64,
1377            signed: false,
1378            supersets: [u64, u128, i128],
1379            non_supersets: [u8, u16, u32, usize, i8, i16, i32, i64, isize],
1380            has_wide,
1381        },
1382        $($rest)*
1383    } };
1384    (@repr u128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1385        @repr {
1386            type: u128,
1387            signed: false,
1388            supersets: [u128],
1389            non_supersets: [u8, u16, u32, u64, usize, i8, i16, i32, i64, i128, isize],
1390        },
1391        $($rest)*
1392    } };
1393    (@repr usize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1394        @repr {
1395            type: usize,
1396            signed: false,
1397            supersets: [usize],
1398            non_supersets: [u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize],
1399        },
1400        $($rest)*
1401    } };
1402    (@repr i8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1403        @repr {
1404            type: i8,
1405            signed: true,
1406            supersets: [i8, i16, i32, i64, i128, isize],
1407            non_supersets: [u8, u16, u32, u64, u128, usize],
1408            has_wide,
1409        },
1410        $($rest)*
1411    } };
1412    (@repr i16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1413        @repr {
1414            type: i16,
1415            signed: true,
1416            supersets: [i16, i32, i64, i128, isize],
1417            non_supersets: [u8, u16, u32, u64, u128, usize, i8],
1418            has_wide,
1419        },
1420        $($rest)*
1421    } };
1422    (@repr i32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1423        @repr {
1424            type: i32,
1425            signed: true,
1426            supersets: [i32, i64, i128],
1427            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, isize],
1428            has_wide,
1429        },
1430        $($rest)*
1431    } };
1432    (@repr i64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1433        @repr {
1434            type: i64,
1435            signed: true,
1436            supersets: [i64, i128],
1437            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, isize],
1438            has_wide,
1439        },
1440        $($rest)*
1441    } };
1442    (@repr i128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1443        @repr {
1444            type: i128,
1445            signed: true,
1446            supersets: [i128],
1447            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, isize],
1448        },
1449        $($rest)*
1450    } };
1451    (@repr isize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1452        @repr {
1453            type: isize,
1454            signed: true,
1455            supersets: [isize],
1456            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128],
1457        },
1458        $($rest)*
1459    } };
1460
1461    (@with_super($ty:ty, $inner:ty)
1462        $({ super: $super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1463    ) => { $(
1464        #[automatically_derived]
1465        impl<$($generics)*> From<$ty> for $super where $($where)* {
1466            fn from(bounded: $ty) -> Self {
1467                Self::from(bounded.get())
1468            }
1469        }
1470    )* };
1471
1472    (@with_non_super($ty:ty, $inner:ty)
1473        $({ non_super: $non_super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1474    ) => { $(
1475        #[automatically_derived]
1476        impl<$($generics)*> TryFrom<$ty> for $non_super where $($where)* {
1477            type Error = ::core::num::TryFromIntError;
1478            fn try_from(n: $ty) -> Result<Self, Self::Error> {
1479                <$non_super as TryFrom<$inner>>::try_from(n.get())
1480            }
1481        }
1482    )* };
1483
1484    (@with_all_int($ty:ty, $inner:ty)
1485        $({ int: $int:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1486    ) => { $(
1487        #[automatically_derived]
1488        impl<$($generics)*> TryFrom<$int> for $ty where $($where)* {
1489            type Error = $crate::TryFromError;
1490            fn try_from(n: $int) -> Result<Self, Self::Error> {
1491                <$inner as TryFrom<$int>>::try_from(n)
1492                    .ok()
1493                    .and_then(Self::new)
1494                    .ok_or_else($crate::__private::try_from_error)
1495            }
1496        }
1497    )* };
1498
1499    (@bin_ops($ty:ty, $inner:ty)
1500        $((
1501            ([$($generics:tt)*] where $($where:tt)*),
1502            $op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal
1503        ),)*
1504    ) => { $(
1505        use ::core::ops::{$op, $op_assign};
1506
1507        #[automatically_derived]
1508        impl<$($generics)*> $op<$inner> for $ty where $($where)* {
1509            type Output = Self;
1510            #[inline]
1511            fn $method(self, rhs: $inner) -> Self::Output {
1512                Self::new(self.get().$method(rhs))
1513                    .expect(concat!("Attempted to ", $desc, " out of range"))
1514            }
1515        }
1516        $crate::__unsafe_api_internal!(@bin_op_variations
1517            ([$($generics)*] where $($where)*),
1518            $ty, $inner, $op::$method/$op_assign::$method_assign
1519        );
1520
1521        #[automatically_derived]
1522        impl<$($generics)*> $op<$ty> for $inner where $($where)* {
1523            type Output = Self;
1524            #[inline]
1525            fn $method(self, rhs: $ty) -> Self::Output {
1526                self.$method(rhs.get())
1527            }
1528        }
1529        $crate::__unsafe_api_internal!(@bin_op_variations
1530            ([$($generics)*] where $($where)*),
1531            $inner, $ty, $op::$method/$op_assign::$method_assign
1532        );
1533
1534        #[automatically_derived]
1535        impl<$($generics)*> $op<$ty> for $ty where $($where)* {
1536            type Output = Self;
1537            #[inline]
1538            fn $method(self, rhs: $ty) -> Self::Output {
1539                self.$method(rhs.get())
1540            }
1541        }
1542        $crate::__unsafe_api_internal!(@bin_op_variations
1543            ([$($generics)*] where $($where)*),
1544            $ty, $ty, $op::$method/$op_assign::$method_assign
1545        );
1546    )* };
1547
1548    (@bin_op_variations
1549        ([$($generics:tt)*] where $($where:tt)*),
1550        $lhs:ty, $rhs:ty, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident
1551    ) => {
1552        #[automatically_derived]
1553        impl<$($generics)*> $op<$rhs> for &$lhs where $($where)* {
1554            type Output = $lhs;
1555            #[inline]
1556            fn $method(self, rhs: $rhs) -> Self::Output {
1557                <$lhs as $op<$rhs>>::$method(*self, rhs)
1558            }
1559        }
1560        #[automatically_derived]
1561        impl<$($generics)*> $op<&$rhs> for $lhs where $($where)* {
1562            type Output = $lhs;
1563            #[inline]
1564            fn $method(self, rhs: &$rhs) -> Self::Output {
1565                <$lhs as $op<$rhs>>::$method(self, *rhs)
1566            }
1567        }
1568        #[automatically_derived]
1569        impl<$($generics)*> $op<&$rhs> for &$lhs where $($where)* {
1570            type Output = $lhs;
1571            #[inline]
1572            fn $method(self, rhs: &$rhs) -> Self::Output {
1573                <$lhs as $op<$rhs>>::$method(*self, *rhs)
1574            }
1575        }
1576
1577        #[automatically_derived]
1578        impl<$($generics)*> $op_assign<$rhs> for $lhs where $($where)* {
1579            #[inline]
1580            fn $method_assign(&mut self, rhs: $rhs) {
1581                *self = <Self as $op<$rhs>>::$method(*self, rhs);
1582            }
1583        }
1584        #[automatically_derived]
1585        impl<$($generics)*> $op_assign<&$rhs> for $lhs where $($where)* {
1586            #[inline]
1587            fn $method_assign(&mut self, rhs: &$rhs) {
1588                *self = <Self as $op<$rhs>>::$method(*self, *rhs);
1589            }
1590        }
1591    };
1592
1593    (@fmt_traits($ty:ty, $inner:ty)
1594        $(([$($generics:tt)*] where $($where:tt)*) $trait:ident,)*
1595    ) => { $(
1596        #[automatically_derived]
1597        impl<$($generics)*> fmt::$trait for $ty where $($where)* {
1598            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1599                fmt::$trait::fmt(&self.get(), f)
1600            }
1601        }
1602    )* }
1603}
1604
1605// Most functionality is tested in `types.rs`. But there are some things that API cannot do.
1606#[cfg(test)]
1607mod tests {
1608    use crate::unsafe_api;
1609    use core::ffi::c_int;
1610    use core::marker::PhantomData;
1611
1612    #[test]
1613    fn c_int() {
1614        #[repr(transparent)]
1615        struct S(c_int);
1616
1617        unsafe_api! {
1618            for S,
1619            unsafe repr: {
1620                type: c_int,
1621                signed: true,
1622                supersets: [i32, i64, i128],
1623                non_supersets: [],
1624                has_wide,
1625            },
1626            min: -5,
1627            max: 5,
1628            zero,
1629        }
1630    }
1631
1632    #[test]
1633    fn where_clause() {
1634        #[repr(transparent)]
1635        struct S<T: Copy>(i32, PhantomData<T>);
1636
1637        unsafe_api! {
1638            [T] for S<T> where { T: Copy },
1639            unsafe repr: i32,
1640            min: -1,
1641            max: i32::MAX,
1642            zero,
1643            one,
1644        }
1645    }
1646
1647    #[test]
1648    fn attr() {
1649        #[deprecated]
1650        #[repr(transparent)]
1651        struct S(i32);
1652
1653        unsafe_api! {
1654            #![allow(deprecated)]
1655            for S,
1656            unsafe repr: i32,
1657            min: 0,
1658            max: 1,
1659            zero,
1660            one,
1661        }
1662    }
1663}