Skip to main content

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 forward_overflowing(start: Self, count: usize) -> (Self, bool) {
1000                    let this = <Self as iter::Step>::forward_checked(start, count);
1001                    (this.unwrap_or(start), this.is_none())
1002                }
1003                #[inline]
1004                unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
1005                    unsafe {
1006                        Self::new_unchecked(iter::Step::forward_unchecked(start.get(), count))
1007                    }
1008                }
1009                #[inline]
1010                fn backward_checked(start: Self, count: usize) -> Option<Self> {
1011                    iter::Step::backward_checked(start.get(), count).and_then(Self::new)
1012                }
1013                #[inline]
1014                fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
1015                    let this = <Self as iter::Step>::backward_checked(start, count);
1016                    (this.unwrap_or(start), this.is_none())
1017                }
1018                #[inline]
1019                unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
1020                    unsafe {
1021                        Self::new_unchecked(iter::Step::backward_unchecked(start.get(), count))
1022                    }
1023                }
1024            }
1025        }
1026
1027        // === Parsing ===
1028
1029        #[automatically_derived]
1030        impl<$($generics)*> FromStr for $ty where $($where)* {
1031            type Err = ParseError;
1032            fn from_str(s: &str) -> Result<Self, Self::Err> {
1033                Self::from_str_radix(s, 10)
1034            }
1035        }
1036
1037        // === Formatting ===
1038
1039        #[automatically_derived]
1040        impl<$($generics)*> fmt::Debug for $ty where $($where)* {
1041            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1042                f.debug_tuple("Bounded").field(&self.get()).finish()
1043            }
1044        }
1045
1046        $crate::__unsafe_api_internal!(@fmt_traits($ty, $inner)
1047            $generics_single_token Binary,
1048            $generics_single_token Display,
1049            $generics_single_token LowerExp,
1050            $generics_single_token LowerHex,
1051            $generics_single_token Octal,
1052            $generics_single_token UpperExp,
1053            $generics_single_token UpperHex,
1054        );
1055
1056        // === Arbitrary ===
1057
1058        $crate::__private::__cfg_arbitrary1! {
1059            use $crate::__private::arbitrary1::{self, Arbitrary, Unstructured};
1060
1061            #[automatically_derived]
1062            impl<'__a, $($generics)*> Arbitrary<'__a> for $ty where $($where)* {
1063                fn arbitrary(u: &mut Unstructured<'__a>) -> arbitrary1::Result<Self> {
1064                    Self::new(u.arbitrary()?).ok_or(arbitrary1::Error::IncorrectFormat)
1065                }
1066
1067                #[inline]
1068                fn size_hint(depth: usize) -> (usize, Option<usize>) {
1069                    <$inner as Arbitrary<'__a>>::size_hint(depth)
1070                }
1071            }
1072        }
1073
1074        // === Bytemuck ===
1075
1076        $crate::__private::__cfg_bytemuck1! {
1077            use $crate::__private::bytemuck1;
1078
1079            #[automatically_derived]
1080            unsafe impl<$($generics)*> bytemuck1::Contiguous for $ty
1081            where
1082                Self: 'static,
1083                $($where)*
1084            {
1085                type Int = $inner;
1086                const MAX_VALUE: $inner = Self::MAX_VALUE;
1087                const MIN_VALUE: $inner = Self::MIN_VALUE;
1088            }
1089
1090            #[automatically_derived]
1091            unsafe impl<$($generics)*> bytemuck1::NoUninit for $ty
1092            where
1093                Self: 'static,
1094                $($where)*
1095            {}
1096
1097            #[cfg(not(all($($(if $zero)? false)?)))]
1098            #[automatically_derived]
1099            unsafe impl<$($generics)*> bytemuck1::Zeroable for $ty where $($where)* {}
1100        }
1101
1102        // === Num ===
1103
1104        $crate::__private::__cfg_num_traits02! {
1105            use $crate::__private::num_traits02;
1106
1107            #[automatically_derived]
1108            impl<$($generics)*> num_traits02::Bounded for $ty where $($where)* {
1109                fn min_value() -> Self {
1110                    Self::MIN
1111                }
1112                fn max_value() -> Self {
1113                    Self::MAX
1114                }
1115            }
1116
1117            #[automatically_derived]
1118            impl<__T, $($generics)*> num_traits02::AsPrimitive<__T> for $ty
1119            where
1120                $inner: num_traits02::AsPrimitive<__T>,
1121                __T: 'static + Copy,
1122                Self: 'static,
1123                $($where)*
1124            {
1125                fn as_(self) -> __T {
1126                    self.get().as_()
1127                }
1128            }
1129
1130            #[automatically_derived]
1131            impl<$($generics)*> num_traits02::FromPrimitive for $ty
1132            where
1133                $inner: num_traits02::FromPrimitive,
1134                $($where)*
1135            {
1136                fn from_i64(n: i64) -> Option<Self> {
1137                    <$inner>::from_i64(n).and_then(Self::new)
1138                }
1139                fn from_u64(n: u64) -> Option<Self> {
1140                    <$inner>::from_u64(n).and_then(Self::new)
1141                }
1142                fn from_isize(n: isize) -> Option<Self> {
1143                    <$inner>::from_isize(n).and_then(Self::new)
1144                }
1145                fn from_i8(n: i8) -> Option<Self> {
1146                    <$inner>::from_i8(n).and_then(Self::new)
1147                }
1148                fn from_i16(n: i16) -> Option<Self> {
1149                    <$inner>::from_i16(n).and_then(Self::new)
1150                }
1151                fn from_i32(n: i32) -> Option<Self> {
1152                    <$inner>::from_i32(n).and_then(Self::new)
1153                }
1154                fn from_i128(n: i128) -> Option<Self> {
1155                    <$inner>::from_i128(n).and_then(Self::new)
1156                }
1157                fn from_usize(n: usize) -> Option<Self> {
1158                    <$inner>::from_usize(n).and_then(Self::new)
1159                }
1160                fn from_u8(n: u8) -> Option<Self> {
1161                    <$inner>::from_u8(n).and_then(Self::new)
1162                }
1163                fn from_u16(n: u16) -> Option<Self> {
1164                    <$inner>::from_u16(n).and_then(Self::new)
1165                }
1166                fn from_u32(n: u32) -> Option<Self> {
1167                    <$inner>::from_u32(n).and_then(Self::new)
1168                }
1169                fn from_u128(n: u128) -> Option<Self> {
1170                    <$inner>::from_u128(n).and_then(Self::new)
1171                }
1172                fn from_f32(n: f32) -> Option<Self> {
1173                    <$inner>::from_f32(n).and_then(Self::new)
1174                }
1175                fn from_f64(n: f64) -> Option<Self> {
1176                    <$inner>::from_f64(n).and_then(Self::new)
1177                }
1178            }
1179
1180            #[automatically_derived]
1181            impl<$($generics)*> num_traits02::NumCast for $ty
1182            where
1183                $inner: num_traits02::NumCast,
1184                $($where)*
1185            {
1186                fn from<__T: num_traits02::ToPrimitive>(n: __T) -> Option<Self> {
1187                    <$inner as num_traits02::NumCast>::from(n).map(Self::new).flatten()
1188                }
1189            }
1190
1191            #[automatically_derived]
1192            impl<$($generics)*> num_traits02::ToPrimitive for $ty
1193            where
1194                $inner: num_traits02::ToPrimitive,
1195                $($where)*
1196            {
1197                fn to_i64(&self) -> Option<i64> {
1198                    self.get().to_i64()
1199                }
1200                fn to_u64(&self) -> Option<u64> {
1201                    self.get().to_u64()
1202                }
1203                fn to_isize(&self) -> Option<isize> {
1204                    self.get().to_isize()
1205                }
1206                fn to_i8(&self) -> Option<i8> {
1207                    self.get().to_i8()
1208                }
1209                fn to_i16(&self) -> Option<i16> {
1210                    self.get().to_i16()
1211                }
1212                fn to_i32(&self) -> Option<i32> {
1213                    self.get().to_i32()
1214                }
1215                fn to_i128(&self) -> Option<i128> {
1216                    self.get().to_i128()
1217                }
1218                fn to_usize(&self) -> Option<usize> {
1219                    self.get().to_usize()
1220                }
1221                fn to_u8(&self) -> Option<u8> {
1222                    self.get().to_u8()
1223                }
1224                fn to_u16(&self) -> Option<u16> {
1225                    self.get().to_u16()
1226                }
1227                fn to_u32(&self) -> Option<u32> {
1228                    self.get().to_u32()
1229                }
1230                fn to_u128(&self) -> Option<u128> {
1231                    self.get().to_u128()
1232                }
1233                fn to_f32(&self) -> Option<f32> {
1234                    self.get().to_f32()
1235                }
1236                fn to_f64(&self) -> Option<f64> {
1237                    self.get().to_f64()
1238                }
1239            }
1240
1241            #[automatically_derived]
1242            impl<$($generics)*> num_traits02::CheckedAdd for $ty where $($where)* {
1243                fn checked_add(&self, v: &Self) -> Option<Self> {
1244                    Self::checked_add(*self, v.get())
1245                }
1246            }
1247
1248            #[automatically_derived]
1249            impl<$($generics)*> num_traits02::CheckedDiv for $ty where $($where)* {
1250                fn checked_div(&self, v: &Self) -> Option<Self> {
1251                    Self::checked_div(*self, v.get())
1252                }
1253            }
1254
1255            #[automatically_derived]
1256            impl<$($generics)*> num_traits02::CheckedMul for $ty where $($where)* {
1257                fn checked_mul(&self, v: &Self) -> Option<Self> {
1258                    Self::checked_mul(*self, v.get())
1259                }
1260            }
1261
1262            #[automatically_derived]
1263            impl<$($generics)*> num_traits02::CheckedNeg for $ty where $($where)* {
1264                fn checked_neg(&self) -> Option<Self> {
1265                    Self::checked_neg(*self)
1266                }
1267            }
1268
1269            #[automatically_derived]
1270            impl<$($generics)*> num_traits02::CheckedRem for $ty where $($where)* {
1271                fn checked_rem(&self, v: &Self) -> Option<Self> {
1272                    Self::checked_rem(*self, v.get())
1273                }
1274            }
1275
1276            #[automatically_derived]
1277            impl<$($generics)*> num_traits02::CheckedShl for $ty where $($where)* {
1278                fn checked_shl(&self, v: u32) -> Option<Self> {
1279                    Self::checked_shl(*self, v)
1280                }
1281            }
1282
1283            #[automatically_derived]
1284            impl<$($generics)*> num_traits02::CheckedShr for $ty where $($where)* {
1285                fn checked_shr(&self, v: u32) -> Option<Self> {
1286                    Self::checked_shr(*self, v)
1287                }
1288            }
1289
1290            #[automatically_derived]
1291            impl<$($generics)*> num_traits02::CheckedSub for $ty where $($where)* {
1292                fn checked_sub(&self, v: &Self) -> Option<Self> {
1293                    Self::checked_sub(*self, v.get())
1294                }
1295            }
1296
1297            #[automatically_derived]
1298            impl<__A, __B, $($generics)*> num_traits02::MulAdd<__A, __B> for $ty
1299            where
1300                $inner: num_traits02::MulAdd<__A, __B, Output = $inner>,
1301                $($where)*
1302            {
1303                type Output = $inner;
1304
1305                fn mul_add(self, a: __A, b: __B) -> Self::Output {
1306                    self.get().mul_add(a, b)
1307                }
1308            }
1309
1310            #[automatically_derived]
1311            impl<$($generics)*> num_traits02::SaturatingAdd for $ty where $($where)* {
1312                fn saturating_add(&self, v: &Self) -> Self {
1313                    Self::saturating_add(*self, v.get())
1314                }
1315            }
1316
1317            #[automatically_derived]
1318            impl<$($generics)*> num_traits02::SaturatingMul for $ty where $($where)* {
1319                fn saturating_mul(&self, v: &Self) -> Self {
1320                    Self::saturating_mul(*self, v.get())
1321                }
1322            }
1323
1324            #[automatically_derived]
1325            impl<$($generics)*> num_traits02::SaturatingSub for $ty where $($where)* {
1326                fn saturating_sub(&self, v: &Self) -> Self {
1327                    Self::saturating_sub(*self, v.get())
1328                }
1329            }
1330
1331            #[cfg(not(all($($($zero)? false)?)))]
1332            #[automatically_derived]
1333            impl<$($generics)*> num_traits02::Zero for $ty where $($where)* {
1334                fn zero() -> Self {
1335                    Self::default()
1336                }
1337                fn is_zero(&self) -> bool {
1338                    self.get() == 0
1339                }
1340            }
1341
1342            #[cfg(not(all($($($one)? false)?)))]
1343            #[automatically_derived]
1344            impl<$($generics)*> num_traits02::One for $ty where $($where)* {
1345                fn one() -> Self {
1346                    Self::one()
1347                }
1348            }
1349        }
1350
1351        // === Serde ===
1352
1353        $crate::__private::__cfg_serde1! {
1354            use $crate::__private::serde1::{self, Deserialize, Deserializer, Serialize, Serializer};
1355
1356            #[automatically_derived]
1357            impl<$($generics)*> Serialize for $ty where $($where)* {
1358                fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1359                    self.get().serialize(serializer)
1360                }
1361            }
1362
1363            // Disable this to prevent triggering `clippy::unsafe_derive_deserialize`. I couldn’t
1364            // figure out how to `#[allow]` it.
1365            // #[automatically_derived]
1366            impl<'__de, $($generics)*> Deserialize<'__de> for $ty where $($where)* {
1367                fn deserialize<D: Deserializer<'__de>>(deserializer: D) -> Result<Self, D::Error> {
1368                    Self::new(<$inner>::deserialize(deserializer)?)
1369                        .ok_or_else(|| {
1370                            <D::Error as serde1::de::Error>::custom(format_args!(
1371                                "integer out of range, expected it to be between {} and {}",
1372                                Self::MIN_VALUE,
1373                                Self::MAX_VALUE,
1374                            ))
1375                        })
1376                }
1377            }
1378        }
1379
1380        // === Schemars ===
1381
1382        $crate::__private::__cfg_schemars1! {
1383            use $crate::__private::alloc::borrow::{Cow, ToOwned};
1384            use $crate::__private::schemars1::{JsonSchema, Schema, SchemaGenerator};
1385            use $crate::__private::serde_json1::to_value;
1386
1387            #[automatically_derived]
1388            impl<$($generics)*> JsonSchema for $ty where $($where)* {
1389                // Like the primitive integers, a bounded integer is a simple constrained scalar
1390                // that is clearer inlined than referenced through `$defs`.
1391                fn inline_schema() -> bool {
1392                    true
1393                }
1394
1395                fn schema_name() -> Cow<'static, str> {
1396                    <$inner as JsonSchema>::schema_name()
1397                }
1398
1399                fn json_schema(generator: &mut SchemaGenerator) -> Schema {
1400                    let mut schema = <$inner as JsonSchema>::json_schema(generator);
1401
1402                    // `to_value` only fails for `i128`/`u128` bounds outside the `i64`/`u64`
1403                    // range, which serde_json can represent solely with its `arbitrary_precision`
1404                    // feature (at significant runtime cost); when it fails we leave the bound
1405                    // unspecified.
1406                    if let Ok(minimum) = to_value(Self::MIN_VALUE) {
1407                        schema.insert("minimum".to_owned(), minimum);
1408                    } else {
1409                        schema.remove("minimum");
1410                    }
1411                    if let Ok(maximum) = to_value(Self::MAX_VALUE) {
1412                        schema.insert("maximum".to_owned(), maximum);
1413                    } else {
1414                        schema.remove("maximum");
1415                    }
1416
1417                    schema
1418                }
1419            }
1420        }
1421    }; };
1422
1423    (@repr u8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1424        @repr {
1425            type: u8,
1426            signed: false,
1427            supersets: [u8, u16, u32, u64, u128, usize, i16, i32, i64, i128, isize],
1428            non_supersets: [i8],
1429            has_wide,
1430        },
1431        $($rest)*
1432    } };
1433    (@repr u16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1434        @repr {
1435            type: u16,
1436            signed: false,
1437            supersets: [u16, u32, u64, u128, usize, i32, i64, i128],
1438            non_supersets: [u8, i8, i16, isize],
1439            has_wide,
1440        },
1441        $($rest)*
1442    } };
1443    (@repr u32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1444        @repr {
1445            type: u32,
1446            signed: false,
1447            supersets: [u32, u64, u128, i64, i128],
1448            non_supersets: [u8, u16, usize, i8, i16, i32, isize],
1449            has_wide,
1450        },
1451        $($rest)*
1452    } };
1453    (@repr u64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1454        @repr {
1455            type: u64,
1456            signed: false,
1457            supersets: [u64, u128, i128],
1458            non_supersets: [u8, u16, u32, usize, i8, i16, i32, i64, isize],
1459            has_wide,
1460        },
1461        $($rest)*
1462    } };
1463    (@repr u128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1464        @repr {
1465            type: u128,
1466            signed: false,
1467            supersets: [u128],
1468            non_supersets: [u8, u16, u32, u64, usize, i8, i16, i32, i64, i128, isize],
1469        },
1470        $($rest)*
1471    } };
1472    (@repr usize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1473        @repr {
1474            type: usize,
1475            signed: false,
1476            supersets: [usize],
1477            non_supersets: [u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize],
1478        },
1479        $($rest)*
1480    } };
1481    (@repr i8, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1482        @repr {
1483            type: i8,
1484            signed: true,
1485            supersets: [i8, i16, i32, i64, i128, isize],
1486            non_supersets: [u8, u16, u32, u64, u128, usize],
1487            has_wide,
1488        },
1489        $($rest)*
1490    } };
1491    (@repr i16, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1492        @repr {
1493            type: i16,
1494            signed: true,
1495            supersets: [i16, i32, i64, i128, isize],
1496            non_supersets: [u8, u16, u32, u64, u128, usize, i8],
1497            has_wide,
1498        },
1499        $($rest)*
1500    } };
1501    (@repr i32, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1502        @repr {
1503            type: i32,
1504            signed: true,
1505            supersets: [i32, i64, i128],
1506            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, isize],
1507            has_wide,
1508        },
1509        $($rest)*
1510    } };
1511    (@repr i64, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1512        @repr {
1513            type: i64,
1514            signed: true,
1515            supersets: [i64, i128],
1516            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, isize],
1517            has_wide,
1518        },
1519        $($rest)*
1520    } };
1521    (@repr i128, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1522        @repr {
1523            type: i128,
1524            signed: true,
1525            supersets: [i128],
1526            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, isize],
1527        },
1528        $($rest)*
1529    } };
1530    (@repr isize, $($rest:tt)*) => { $crate::__unsafe_api_internal! {
1531        @repr {
1532            type: isize,
1533            signed: true,
1534            supersets: [isize],
1535            non_supersets: [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128],
1536        },
1537        $($rest)*
1538    } };
1539
1540    (@with_super($ty:ty, $inner:ty)
1541        $({ super: $super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1542    ) => { $(
1543        #[automatically_derived]
1544        impl<$($generics)*> From<$ty> for $super where $($where)* {
1545            fn from(bounded: $ty) -> Self {
1546                Self::from(bounded.get())
1547            }
1548        }
1549    )* };
1550
1551    (@with_non_super($ty:ty, $inner:ty)
1552        $({ non_super: $non_super:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1553    ) => { $(
1554        #[automatically_derived]
1555        impl<$($generics)*> TryFrom<$ty> for $non_super where $($where)* {
1556            type Error = ::core::num::TryFromIntError;
1557            fn try_from(n: $ty) -> Result<Self, Self::Error> {
1558                <$non_super as TryFrom<$inner>>::try_from(n.get())
1559            }
1560        }
1561    )* };
1562
1563    (@with_all_int($ty:ty, $inner:ty)
1564        $({ int: $int:ty, generics: ([$($generics:tt)*] where $($where:tt)*) })*
1565    ) => { $(
1566        #[automatically_derived]
1567        impl<$($generics)*> TryFrom<$int> for $ty where $($where)* {
1568            type Error = $crate::TryFromError;
1569            fn try_from(n: $int) -> Result<Self, Self::Error> {
1570                <$inner as TryFrom<$int>>::try_from(n)
1571                    .ok()
1572                    .and_then(Self::new)
1573                    .ok_or_else($crate::__private::try_from_error)
1574            }
1575        }
1576    )* };
1577
1578    (@bin_ops($ty:ty, $inner:ty)
1579        $((
1580            ([$($generics:tt)*] where $($where:tt)*),
1581            $op:ident::$method:ident/$op_assign:ident::$method_assign:ident, $desc:literal
1582        ),)*
1583    ) => { $(
1584        use ::core::ops::{$op, $op_assign};
1585
1586        #[automatically_derived]
1587        impl<$($generics)*> $op<$inner> for $ty where $($where)* {
1588            type Output = Self;
1589            #[inline]
1590            fn $method(self, rhs: $inner) -> Self::Output {
1591                Self::new(self.get().$method(rhs))
1592                    .expect(concat!("Attempted to ", $desc, " out of range"))
1593            }
1594        }
1595        $crate::__unsafe_api_internal!(@bin_op_variations
1596            ([$($generics)*] where $($where)*),
1597            $ty, $inner, $op::$method/$op_assign::$method_assign
1598        );
1599
1600        #[automatically_derived]
1601        impl<$($generics)*> $op<$ty> for $inner where $($where)* {
1602            type Output = Self;
1603            #[inline]
1604            fn $method(self, rhs: $ty) -> Self::Output {
1605                self.$method(rhs.get())
1606            }
1607        }
1608        $crate::__unsafe_api_internal!(@bin_op_variations
1609            ([$($generics)*] where $($where)*),
1610            $inner, $ty, $op::$method/$op_assign::$method_assign
1611        );
1612
1613        #[automatically_derived]
1614        impl<$($generics)*> $op<$ty> for $ty where $($where)* {
1615            type Output = Self;
1616            #[inline]
1617            fn $method(self, rhs: $ty) -> Self::Output {
1618                self.$method(rhs.get())
1619            }
1620        }
1621        $crate::__unsafe_api_internal!(@bin_op_variations
1622            ([$($generics)*] where $($where)*),
1623            $ty, $ty, $op::$method/$op_assign::$method_assign
1624        );
1625    )* };
1626
1627    (@bin_op_variations
1628        ([$($generics:tt)*] where $($where:tt)*),
1629        $lhs:ty, $rhs:ty, $op:ident::$method:ident/$op_assign:ident::$method_assign:ident
1630    ) => {
1631        #[automatically_derived]
1632        impl<$($generics)*> $op<$rhs> for &$lhs where $($where)* {
1633            type Output = $lhs;
1634            #[inline]
1635            fn $method(self, rhs: $rhs) -> Self::Output {
1636                <$lhs as $op<$rhs>>::$method(*self, rhs)
1637            }
1638        }
1639        #[automatically_derived]
1640        impl<$($generics)*> $op<&$rhs> for $lhs where $($where)* {
1641            type Output = $lhs;
1642            #[inline]
1643            fn $method(self, rhs: &$rhs) -> Self::Output {
1644                <$lhs as $op<$rhs>>::$method(self, *rhs)
1645            }
1646        }
1647        #[automatically_derived]
1648        impl<$($generics)*> $op<&$rhs> for &$lhs where $($where)* {
1649            type Output = $lhs;
1650            #[inline]
1651            fn $method(self, rhs: &$rhs) -> Self::Output {
1652                <$lhs as $op<$rhs>>::$method(*self, *rhs)
1653            }
1654        }
1655
1656        #[automatically_derived]
1657        impl<$($generics)*> $op_assign<$rhs> for $lhs where $($where)* {
1658            #[inline]
1659            fn $method_assign(&mut self, rhs: $rhs) {
1660                *self = <Self as $op<$rhs>>::$method(*self, rhs);
1661            }
1662        }
1663        #[automatically_derived]
1664        impl<$($generics)*> $op_assign<&$rhs> for $lhs where $($where)* {
1665            #[inline]
1666            fn $method_assign(&mut self, rhs: &$rhs) {
1667                *self = <Self as $op<$rhs>>::$method(*self, *rhs);
1668            }
1669        }
1670    };
1671
1672    (@fmt_traits($ty:ty, $inner:ty)
1673        $(([$($generics:tt)*] where $($where:tt)*) $trait:ident,)*
1674    ) => { $(
1675        #[automatically_derived]
1676        impl<$($generics)*> fmt::$trait for $ty where $($where)* {
1677            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1678                fmt::$trait::fmt(&self.get(), f)
1679            }
1680        }
1681    )* }
1682}
1683
1684// Most functionality is tested in `types.rs`. But there are some things that API cannot do.
1685#[cfg(test)]
1686mod tests {
1687    use core::ffi::c_int;
1688    use core::marker::PhantomData;
1689
1690    #[test]
1691    fn c_int() {
1692        #[repr(transparent)]
1693        struct S(c_int);
1694
1695        unsafe_api! {
1696            for S,
1697            unsafe repr: {
1698                type: c_int,
1699                signed: true,
1700                supersets: [i32, i64, i128],
1701                non_supersets: [],
1702                has_wide,
1703            },
1704            min: -5,
1705            max: 5,
1706            zero,
1707        }
1708    }
1709
1710    #[test]
1711    fn where_clause() {
1712        #[repr(transparent)]
1713        struct S<T: Copy>(i32, PhantomData<T>);
1714
1715        unsafe_api! {
1716            [T] for S<T> where { T: Copy },
1717            unsafe repr: i32,
1718            min: -1,
1719            max: i32::MAX,
1720            zero,
1721            one,
1722        }
1723    }
1724
1725    #[test]
1726    fn attr() {
1727        #[deprecated]
1728        #[repr(transparent)]
1729        struct S(i32);
1730
1731        unsafe_api! {
1732            #![allow(deprecated)]
1733            for S,
1734            unsafe repr: i32,
1735            min: 0,
1736            max: 1,
1737            zero,
1738            one,
1739        }
1740    }
1741}