deranged/
lib.rs

1//! `deranged` is a proof-of-concept implementation of ranged integers.
2
3#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide))]
4#![no_std]
5#![doc(test(attr(deny(warnings))))]
6#![cfg_attr(docsrs, doc(cfg_hide(docsrs)))]
7
8#[cfg(all(feature = "alloc", any(feature = "serde", feature = "quickcheck")))]
9extern crate alloc;
10
11#[cfg(test)]
12mod tests;
13mod unsafe_wrapper;
14
15use core::borrow::Borrow;
16use core::cmp::Ordering;
17use core::error::Error;
18use core::fmt;
19use core::hint::assert_unchecked;
20use core::num::{IntErrorKind, NonZero};
21use core::str::FromStr;
22
23/// A macro to define a ranged integer with an automatically computed inner type.
24///
25/// The minimum and maximum values are provided as integer literals, and the macro will compute an
26/// appropriate inner type to represent the range. This will be the smallest integer type that can
27/// store both the minimum and maximum values, with a preference for unsigned types if both are
28/// possible. To specifically request a signed or unsigned type, you can append a `i` or `u` suffix
29/// to either or both of the minimum and maximum values, respectively.
30///
31/// # Examples
32///
33/// ```rust,ignore
34/// int!(0, 100);  // RangedU8<0, 100>
35/// int!(0i, 100); // RangedI8<0, 100>
36/// int!(-5, 5);   // RangedI8<-5, 5>
37/// int!(-5u, 5);  // compile error (-5 cannot be unsigned)
38/// ```
39#[cfg(all(docsrs, feature = "macros"))]
40#[macro_export]
41macro_rules! int {
42    ($min:literal, $max:literal) => {};
43}
44
45/// A macro to define an optional ranged integer with an automatically computed inner type.
46///
47/// The minimum and maximum values are provided as integer literals, and the macro will compute an
48/// appropriate inner type to represent the range. This will be the smallest integer type that can
49/// store both the minimum and maximum values, with a preference for unsigned types if both are
50/// possible. To specifically request a signed or unsigned type, you can append a `i` or `u` suffix
51/// to either or both of the minimum and maximum values, respectively.
52///
53/// # Examples
54///
55/// ```rust,ignore
56/// opt_int!(0, 100);  // OptionRangedU8<0, 100>
57/// opt_int!(0i, 100); // OptionRangedI8<0, 100>
58/// opt_int!(-5, 5);   // OptionRangedI8<-5, 5>
59/// opt_int!(-5u, 5);  // compile error (-5 cannot be unsigned)
60/// ```
61#[cfg(all(docsrs, feature = "macros"))]
62#[macro_export]
63macro_rules! opt_int {
64    ($min:literal, $max:literal) => {};
65}
66
67#[cfg(all(not(docsrs), feature = "macros"))]
68pub use deranged_macros::int;
69#[cfg(all(not(docsrs), feature = "macros"))]
70pub use deranged_macros::opt_int;
71#[cfg(feature = "powerfmt")]
72use powerfmt::smart_display;
73
74use crate::unsafe_wrapper::Unsafe;
75
76/// The error type returned when a checked integral type conversion fails.
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub struct TryFromIntError;
79
80impl fmt::Display for TryFromIntError {
81    #[inline]
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        f.write_str("out of range integral type conversion attempted")
84    }
85}
86impl Error for TryFromIntError {}
87
88/// An error which can be returned when parsing an integer.
89///
90/// This error is used as the error type for the `from_str_radix()` functions on ranged integer
91/// types, such as [`RangedI8::from_str_radix`].
92///
93/// # Potential causes
94///
95/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
96/// in the string e.g., when it is obtained from the standard input.
97/// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
98///
99/// # Example
100///
101/// ```rust
102/// # use deranged::RangedI32;
103/// if let Err(e) = RangedI32::<0, 10>::from_str_radix("a12", 10) {
104///     println!("Failed conversion to RangedI32: {e}");
105/// }
106/// ```
107#[allow(missing_copy_implementations)] // same as `std`
108#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct ParseIntError {
110    #[allow(clippy::missing_docs_in_private_items)]
111    kind: IntErrorKind,
112}
113
114impl ParseIntError {
115    /// Outputs the detailed cause of parsing an integer failing.
116    // This function is not const because the counterpart of stdlib isn't
117    #[allow(clippy::missing_const_for_fn)]
118    #[inline(always)]
119    pub fn kind(&self) -> &IntErrorKind {
120        &self.kind
121    }
122}
123
124impl fmt::Display for ParseIntError {
125    #[inline]
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        match self.kind {
128            IntErrorKind::Empty => "cannot parse integer from empty string",
129            IntErrorKind::InvalidDigit => "invalid digit found in string",
130            IntErrorKind::PosOverflow => "number too large to fit in target type",
131            IntErrorKind::NegOverflow => "number too small to fit in target type",
132            IntErrorKind::Zero => "number would be zero for non-zero type",
133            _ => "Unknown Int error kind",
134        }
135        .fmt(f)
136    }
137}
138
139impl Error for ParseIntError {}
140
141/// `?` for `Option` types, usable in `const` contexts.
142macro_rules! const_try_opt {
143    ($e:expr) => {
144        match $e {
145            Some(value) => value,
146            None => return None,
147        }
148    };
149}
150
151/// Output the given tokens if the type is signed, otherwise output nothing.
152macro_rules! if_signed {
153    (true $($x:tt)*) => { $($x)*};
154    (false $($x:tt)*) => {};
155}
156
157/// Output the given tokens if the type is unsigned, otherwise output nothing.
158macro_rules! if_unsigned {
159    (true $($x:tt)*) => {};
160    (false $($x:tt)*) => { $($x)* };
161}
162
163/// `"A"` if `true`, `"An"` if `false`.
164macro_rules! article {
165    (true) => {
166        "An"
167    };
168    (false) => {
169        "A"
170    };
171}
172
173/// `Option::unwrap_unchecked`, but usable in `const` contexts.
174macro_rules! unsafe_unwrap_unchecked {
175    ($e:expr) => {{
176        let opt = $e;
177        debug_assert!(opt.is_some());
178        match $e {
179            Some(value) => value,
180            None => core::hint::unreachable_unchecked(),
181        }
182    }};
183}
184
185/// Output the provided code if and only if the list does not include `rand_09`.
186#[allow(unused_macro_rules)]
187macro_rules! if_not_manual_rand_09 {
188    ([rand_09 $($rest:ident)*] $($output:tt)*) => {};
189    ([] $($output:tt)*) => {
190        $($output)*
191    };
192    ([$first:ident $($rest:ident)*] $($output:tt)*) => {
193        if_not_manual_rand_09!([$($rest)*] $($output)*);
194    };
195}
196
197/// Implement a ranged integer type.
198macro_rules! impl_ranged {
199    ($(
200        $type:ident {
201            mod_name: $mod_name:ident
202            internal: $internal:ident
203            signed: $is_signed:ident
204            unsigned: $unsigned_type:ident
205            optional: $optional_type:ident
206            from: [$($from:ident($from_internal:ident))+]
207            $(manual: [$($skips:ident)+])?
208        }
209    )*) => {$(
210        #[doc = concat!(
211            article!($is_signed),
212            " `",
213            stringify!($internal),
214            "` that is known to be in the range `MIN..=MAX`.",
215        )]
216        #[repr(transparent)]
217        #[derive(Clone, Copy, Eq, Ord, Hash)]
218        pub struct $type<const MIN: $internal, const MAX: $internal>(
219            Unsafe<$internal>,
220        );
221
222        #[doc = concat!(
223            "An optional `",
224            stringify!($type),
225            "`; similar to `Option<",
226            stringify!($type),
227            ">` with better optimization.",
228        )]
229        ///
230        #[doc = concat!(
231            "If `MIN` is [`",
232            stringify!($internal),
233            "::MIN`] _and_ `MAX` is [`",
234            stringify!($internal)
235            ,"::MAX`] then compilation will fail. This is because there is no way to represent \
236            the niche value.",
237        )]
238        ///
239        /// This type is useful when you need to store an optional ranged value in a struct, but
240        /// do not want the overhead of an `Option` type. This reduces the size of the struct
241        /// overall, and is particularly useful when you have a large number of optional fields.
242        /// Note that most operations must still be performed on the [`Option`] type, which is
243        #[doc = concat!("obtained with [`", stringify!($optional_type), "::get`].")]
244        #[repr(transparent)]
245        #[derive(Clone, Copy, Eq, Hash)]
246        pub struct $optional_type<const MIN: $internal, const MAX: $internal>(
247            $internal,
248        );
249
250        impl $type<0, 0> {
251            #[doc = concat!("A ", stringify!($type), " that is always `VALUE`.")]
252            #[inline(always)]
253            pub const fn exact<const VALUE: $internal>() -> $type<VALUE, VALUE> {
254                // Safety: The value is the only one in range.
255                unsafe { $type::new_unchecked(VALUE) }
256            }
257        }
258
259        if_unsigned! { $is_signed
260        impl $type<1, { $internal::MAX }> {
261            /// Creates a ranged integer from a non-zero value.
262            #[inline(always)]
263            pub const fn from_nonzero(value: NonZero<$internal>) -> Self {
264                // Safety: The value is non-zero, so it is in range.
265                unsafe { Self::new_unchecked(value.get()) }
266            }
267
268            /// Creates a non-zero value from a ranged integer.
269            #[inline(always)]
270            pub const fn to_nonzero(self) -> NonZero<$internal> {
271                // Safety: The value is in range, so it is non-zero.
272                unsafe { NonZero::new_unchecked(self.get()) }
273            }
274        }}
275
276        impl<const MIN: $internal, const MAX: $internal> $type<MIN, MAX> {
277            /// The smallest value that can be represented by this type.
278            // Safety: `MIN` is in range by definition.
279            pub const MIN: Self = Self::new_static::<MIN>();
280
281            /// The largest value that can be represented by this type.
282            // Safety: `MAX` is in range by definition.
283            pub const MAX: Self = Self::new_static::<MAX>();
284
285            /// Creates a ranged integer without checking the value.
286            ///
287            /// # Safety
288            ///
289            /// The value must be within the range `MIN..=MAX`.
290            #[track_caller]
291            #[inline(always)]
292            pub const unsafe fn new_unchecked(value: $internal) -> Self {
293                const { assert!(MIN <= MAX); }
294                // Safety: The caller must ensure that the value is in range.
295                unsafe {
296                    assert_unchecked(MIN <= value && value <= MAX);
297                    Self(Unsafe::new(value))
298                }
299            }
300
301            /// Returns the value as a primitive type.
302            ///
303            /// A call to this function will output a hint to the compiler that the value is in
304            /// range. In general this will help the optimizer to generate better code, but in edge
305            /// cases this may lead to worse code generation. To avoid outputting the hint, you can
306            #[doc = concat!("use [`", stringify!($type), "::get_without_hint`].")]
307            #[track_caller]
308            #[inline(always)]
309            pub const fn get(self) -> $internal {
310                const { assert!(MIN <= MAX); }
311                // Safety: A stored value is always in range.
312                unsafe { assert_unchecked(MIN <= *self.0.get() && *self.0.get() <= MAX) };
313                *self.0.get()
314            }
315
316            /// Returns the value as a primitive type.
317            ///
318            #[doc = concat!("The returned value is identical to [`", stringify!($type), "::get`].")]
319            /// Unlike `get`, no hints are output to the compiler indicating the range that the
320            /// value is in. Depending on the scenario, this may with be helpful or harmful too
321            /// optimization.
322            #[inline(always)]
323            pub const fn get_without_hint(self) -> $internal {
324                const { assert!(MIN <= MAX); }
325                *self.0.get()
326            }
327
328            #[track_caller]
329            #[inline(always)]
330            pub(crate) const fn get_ref(&self) -> &$internal {
331                const { assert!(MIN <= MAX); }
332                let value = self.0.get();
333                // Safety: A stored value is always in range.
334                unsafe { assert_unchecked(MIN <= *value && *value <= MAX) };
335                value
336            }
337
338            /// Creates a ranged integer if the given value is in the range `MIN..=MAX`.
339            #[inline(always)]
340            pub const fn new(value: $internal) -> Option<Self> {
341                const { assert!(MIN <= MAX); }
342                if value < MIN || value > MAX {
343                    None
344                } else {
345                    // Safety: The value is in range.
346                    Some(unsafe { Self::new_unchecked(value) })
347                }
348            }
349
350            /// Creates a ranged integer with a statically known value. **Fails to compile** if the
351            /// value is not in range.
352            #[inline(always)]
353            pub const fn new_static<const VALUE: $internal>() -> Self {
354                const {
355                    assert!(MIN <= VALUE);
356                    assert!(VALUE <= MAX);
357                }
358                // Safety: The value is in range.
359                unsafe { Self::new_unchecked(VALUE) }
360            }
361
362            /// Creates a ranged integer with the given value, saturating if it is out of range.
363            #[inline]
364            pub const fn new_saturating(value: $internal) -> Self {
365                const { assert!(MIN <= MAX); }
366                if value < MIN {
367                    Self::MIN
368                } else if value > MAX {
369                    Self::MAX
370                } else {
371                    // Safety: The value is in range.
372                    unsafe { Self::new_unchecked(value) }
373                }
374            }
375
376            /// Emit a hint to the compiler that the value is in range.
377            ///
378            /// In some situations, this can help the optimizer to generate better code. In edge
379            /// cases this may lead to **worse** code generation. If you are unsure whether this is
380            /// helpful, harmful, or neutral, you should use [`cargo-show-asm`] to compare the
381            /// generated assembly.
382            ///
383            /// Aside from potentially affecting optimization, this function is a no-op.
384            ///
385            /// [`cargo-show-asm`]: https://crates.io/crates/cargo-show-asm
386            #[inline(always)]
387            pub const fn emit_range_hint(self) {
388                const { assert!(MIN <= MAX); }
389                let value = self.0.get();
390                // Safety: A stored value is always in range.
391                unsafe { assert_unchecked(MIN <= *value && *value <= MAX) };
392            }
393
394            /// Expand the range that the value may be in. **Fails to compile** if the new range is
395            /// not a superset of the current range.
396            #[inline(always)]
397            pub const fn expand<const NEW_MIN: $internal, const NEW_MAX: $internal>(
398                self,
399            ) -> $type<NEW_MIN, NEW_MAX> {
400                const {
401                    assert!(MIN <= MAX);
402                    assert!(NEW_MIN <= NEW_MAX);
403                    assert!(NEW_MIN <= MIN);
404                    assert!(NEW_MAX >= MAX);
405                }
406                // Safety: The range is widened.
407                unsafe { $type::new_unchecked(self.get()) }
408            }
409
410            /// Attempt to narrow the range that the value may be in. Returns `None` if the value
411            /// is outside the new range. **Fails to compile** if the new range is not a subset of
412            /// the current range.
413            #[inline(always)]
414            pub const fn narrow<
415                const NEW_MIN: $internal,
416                const NEW_MAX: $internal,
417            >(self) -> Option<$type<NEW_MIN, NEW_MAX>> {
418                const {
419                    assert!(MIN <= MAX);
420                    assert!(NEW_MIN <= NEW_MAX);
421                    assert!(NEW_MIN >= MIN);
422                    assert!(NEW_MAX <= MAX);
423                }
424                $type::<NEW_MIN, NEW_MAX>::new(self.get())
425            }
426
427            /// Converts a string slice in a given base to an integer.
428            ///
429            /// The string is expected to be an optional `+` or `-` sign followed by digits. Leading
430            /// and trailing whitespace represent an error. Digits are a subset of these characters,
431            /// depending on `radix`:
432            ///
433            /// - `0-9`
434            /// - `a-z`
435            /// - `A-Z`
436            ///
437            /// # Panics
438            ///
439            /// Panics if `radix` is not in the range `2..=36`.
440            ///
441            /// # Examples
442            ///
443            /// Basic usage:
444            ///
445            /// ```rust
446            #[doc = concat!("# use deranged::", stringify!($type), ";")]
447            #[doc = concat!(
448                "assert_eq!(",
449                stringify!($type),
450                "::<5, 10>::from_str_radix(\"A\", 16), Ok(",
451                stringify!($type),
452                "::new_static::<10>()));",
453            )]
454            /// ```
455            #[inline]
456            pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
457                const { assert!(MIN <= MAX); }
458                match $internal::from_str_radix(src, radix) {
459                    Ok(value) if value > MAX => {
460                        Err(ParseIntError { kind: IntErrorKind::PosOverflow })
461                    }
462                    Ok(value) if value < MIN => {
463                        Err(ParseIntError { kind: IntErrorKind::NegOverflow })
464                    }
465                    // Safety: If the value was out of range, it would have been caught in a
466                    // previous arm.
467                    Ok(value) => Ok(unsafe { Self::new_unchecked(value) }),
468                    Err(e) => Err(ParseIntError { kind: e.kind().clone() }),
469                }
470            }
471
472            /// Checked integer addition. Computes `self + rhs`, returning `None` if the resulting
473            /// value is out of range.
474            #[must_use = "this returns the result of the operation, without modifying the original"]
475            #[inline]
476            pub const fn checked_add(self, rhs: $internal) -> Option<Self> {
477                const { assert!(MIN <= MAX); }
478                Self::new(const_try_opt!(self.get().checked_add(rhs)))
479            }
480
481            /// Unchecked integer addition. Computes `self + rhs`, assuming that the result is in
482            /// range.
483            ///
484            /// # Safety
485            ///
486            /// The result of `self + rhs` must be in the range `MIN..=MAX`.
487            #[must_use = "this returns the result of the operation, without modifying the original"]
488            #[track_caller]
489            #[inline(always)]
490            pub const unsafe fn unchecked_add(self, rhs: $internal) -> Self {
491                const { assert!(MIN <= MAX); }
492                // Safety: The caller must ensure that the result is in range.
493                unsafe {
494                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_add(rhs)))
495                }
496            }
497
498            /// Checked integer addition. Computes `self - rhs`, returning `None` if the resulting
499            /// value is out of range.
500            #[must_use = "this returns the result of the operation, without modifying the original"]
501            #[inline]
502            pub const fn checked_sub(self, rhs: $internal) -> Option<Self> {
503                const { assert!(MIN <= MAX); }
504                Self::new(const_try_opt!(self.get().checked_sub(rhs)))
505            }
506
507            /// Unchecked integer subtraction. Computes `self - rhs`, assuming that the result is in
508            /// range.
509            ///
510            /// # Safety
511            ///
512            /// The result of `self - rhs` must be in the range `MIN..=MAX`.
513            #[must_use = "this returns the result of the operation, without modifying the original"]
514            #[track_caller]
515            #[inline(always)]
516            pub const unsafe fn unchecked_sub(self, rhs: $internal) -> Self {
517                const { assert!(MIN <= MAX); }
518                // Safety: The caller must ensure that the result is in range.
519                unsafe {
520                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_sub(rhs)))
521                }
522            }
523
524            /// Checked integer addition. Computes `self * rhs`, returning `None` if the resulting
525            /// value is out of range.
526            #[must_use = "this returns the result of the operation, without modifying the original"]
527            #[inline]
528            pub const fn checked_mul(self, rhs: $internal) -> Option<Self> {
529                const { assert!(MIN <= MAX); }
530                Self::new(const_try_opt!(self.get().checked_mul(rhs)))
531            }
532
533            /// Unchecked integer multiplication. Computes `self * rhs`, assuming that the result is
534            /// in range.
535            ///
536            /// # Safety
537            ///
538            /// The result of `self * rhs` must be in the range `MIN..=MAX`.
539            #[must_use = "this returns the result of the operation, without modifying the original"]
540            #[track_caller]
541            #[inline(always)]
542            pub const unsafe fn unchecked_mul(self, rhs: $internal) -> Self {
543                const { assert!(MIN <= MAX); }
544                // Safety: The caller must ensure that the result is in range.
545                unsafe {
546                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_mul(rhs)))
547                }
548            }
549
550            /// Checked integer addition. Computes `self / rhs`, returning `None` if `rhs == 0` or
551            /// if the resulting value is out of range.
552            #[must_use = "this returns the result of the operation, without modifying the original"]
553            #[inline]
554            pub const fn checked_div(self, rhs: $internal) -> Option<Self> {
555                const { assert!(MIN <= MAX); }
556                Self::new(const_try_opt!(self.get().checked_div(rhs)))
557            }
558
559            /// Unchecked integer division. Computes `self / rhs`, assuming that `rhs != 0` and that
560            /// the result is in range.
561            ///
562            /// # Safety
563            ///
564            /// `self` must not be zero and the result of `self / rhs` must be in the range
565            /// `MIN..=MAX`.
566            #[must_use = "this returns the result of the operation, without modifying the original"]
567            #[track_caller]
568            #[inline(always)]
569            pub const unsafe fn unchecked_div(self, rhs: $internal) -> Self {
570                const { assert!(MIN <= MAX); }
571                // Safety: The caller must ensure that the result is in range and that `rhs` is not
572                // zero.
573                unsafe {
574                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_div(rhs)))
575                }
576            }
577
578            /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None` if
579            /// `rhs == 0` or if the resulting value is out of range.
580            #[must_use = "this returns the result of the operation, without modifying the original"]
581            #[inline]
582            pub const fn checked_div_euclid(self, rhs: $internal) -> Option<Self> {
583                const { assert!(MIN <= MAX); }
584                Self::new(const_try_opt!(self.get().checked_div_euclid(rhs)))
585            }
586
587            /// Unchecked Euclidean division. Computes `self.div_euclid(rhs)`, assuming that
588            /// `rhs != 0` and that the result is in range.
589            ///
590            /// # Safety
591            ///
592            /// `self` must not be zero and the result of `self.div_euclid(rhs)` must be in the
593            /// range `MIN..=MAX`.
594            #[must_use = "this returns the result of the operation, without modifying the original"]
595            #[track_caller]
596            #[inline(always)]
597            pub const unsafe fn unchecked_div_euclid(self, rhs: $internal) -> Self {
598                const { assert!(MIN <= MAX); }
599                // Safety: The caller must ensure that the result is in range and that `rhs` is not
600                // zero.
601                unsafe {
602                    Self::new_unchecked(
603                        unsafe_unwrap_unchecked!(self.get().checked_div_euclid(rhs))
604                    )
605                }
606            }
607
608            if_unsigned!($is_signed
609            /// Remainder. Computes `self % rhs`, statically guaranteeing that the returned value
610            /// is in range.
611            #[must_use = "this returns the result of the operation, without modifying the original"]
612            #[track_caller]
613            #[inline]
614            pub const fn rem<const RHS_VALUE: $internal>(
615                self,
616                rhs: $type<RHS_VALUE, RHS_VALUE>,
617            ) -> $type<0, RHS_VALUE> {
618                const { assert!(MIN <= MAX); }
619                // Safety: The result is guaranteed to be in range due to the nature of remainder on
620                // unsigned integers.
621                unsafe { $type::new_unchecked(self.get() % rhs.get()) }
622            });
623
624            /// Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0` or
625            /// if the resulting value is out of range.
626            #[must_use = "this returns the result of the operation, without modifying the original"]
627            #[inline]
628            pub const fn checked_rem(self, rhs: $internal) -> Option<Self> {
629                const { assert!(MIN <= MAX); }
630                Self::new(const_try_opt!(self.get().checked_rem(rhs)))
631            }
632
633            /// Unchecked remainder. Computes `self % rhs`, assuming that `rhs != 0` and that the
634            /// result is in range.
635            ///
636            /// # Safety
637            ///
638            /// `self` must not be zero and the result of `self % rhs` must be in the range
639            /// `MIN..=MAX`.
640            #[must_use = "this returns the result of the operation, without modifying the original"]
641            #[track_caller]
642            #[inline(always)]
643            pub const unsafe fn unchecked_rem(self, rhs: $internal) -> Self {
644                const { assert!(MIN <= MAX); }
645                // Safety: The caller must ensure that the result is in range and that `rhs` is not
646                // zero.
647                unsafe {
648                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_rem(rhs)))
649                }
650            }
651
652            /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None` if
653            /// `rhs == 0` or if the resulting value is out of range.
654            #[must_use = "this returns the result of the operation, without modifying the original"]
655            #[inline]
656            pub const fn checked_rem_euclid(self, rhs: $internal) -> Option<Self> {
657                const { assert!(MIN <= MAX); }
658                Self::new(const_try_opt!(self.get().checked_rem_euclid(rhs)))
659            }
660
661            /// Unchecked Euclidean remainder. Computes `self.rem_euclid(rhs)`, assuming that
662            /// `rhs != 0` and that the result is in range.
663            ///
664            /// # Safety
665            ///
666            /// `self` must not be zero and the result of `self.rem_euclid(rhs)` must be in the
667            /// range `MIN..=MAX`.
668            #[must_use = "this returns the result of the operation, without modifying the original"]
669            #[track_caller]
670            #[inline(always)]
671            pub const unsafe fn unchecked_rem_euclid(self, rhs: $internal) -> Self {
672                const { assert!(MIN <= MAX); }
673                // Safety: The caller must ensure that the result is in range and that `rhs` is not
674                // zero.
675                unsafe {
676                    Self::new_unchecked(
677                        unsafe_unwrap_unchecked!(self.get().checked_rem_euclid(rhs))
678                    )
679                }
680            }
681
682            /// Checked negation. Computes `-self`, returning `None` if the resulting value is out
683            /// of range.
684            #[must_use = "this returns the result of the operation, without modifying the original"]
685            #[inline]
686            pub const fn checked_neg(self) -> Option<Self> {
687                const { assert!(MIN <= MAX); }
688                Self::new(const_try_opt!(self.get().checked_neg()))
689            }
690
691            /// Unchecked negation. Computes `-self`, assuming that `-self` is in range.
692            ///
693            /// # Safety
694            ///
695            /// The result of `-self` must be in the range `MIN..=MAX`.
696            #[must_use = "this returns the result of the operation, without modifying the original"]
697            #[track_caller]
698            #[inline(always)]
699            pub const unsafe fn unchecked_neg(self) -> Self {
700                const { assert!(MIN <= MAX); }
701                // Safety: The caller must ensure that the result is in range.
702                unsafe { Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_neg())) }
703            }
704
705            /// Negation. Computes `self.neg()`, **failing to compile** if the result is not
706            /// guaranteed to be in range.
707            #[must_use = "this returns the result of the operation, without modifying the original"]
708            #[inline(always)]
709            pub const fn neg(self) -> Self {
710                const {
711                    assert!(MIN <= MAX);
712                    if_signed! { $is_signed
713                        assert!(MIN != $internal::MIN);
714                        assert!(-MIN <= MAX);
715                        assert!(-MAX >= MIN);
716                    }
717                    if_unsigned! { $is_signed
718                        assert!(MAX == 0);
719                    }
720                }
721                // Safety: The compiler asserts that the result is in range.
722                unsafe { self.unchecked_neg() }
723            }
724
725            /// Checked shift left. Computes `self << rhs`, returning `None` if the resulting value
726            /// is out of range.
727            #[must_use = "this returns the result of the operation, without modifying the original"]
728            #[inline]
729            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
730                const { assert!(MIN <= MAX); }
731                Self::new(const_try_opt!(self.get().checked_shl(rhs)))
732            }
733
734            /// Unchecked shift left. Computes `self << rhs`, assuming that the result is in range.
735            ///
736            /// # Safety
737            ///
738            /// The result of `self << rhs` must be in the range `MIN..=MAX`.
739            #[must_use = "this returns the result of the operation, without modifying the original"]
740            #[track_caller]
741            #[inline(always)]
742            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
743                const { assert!(MIN <= MAX); }
744                // Safety: The caller must ensure that the result is in range.
745                unsafe {
746                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_shl(rhs)))
747                }
748            }
749
750            /// Checked shift right. Computes `self >> rhs`, returning `None` if
751            /// the resulting value is out of range.
752            #[must_use = "this returns the result of the operation, without modifying the original"]
753            #[inline]
754            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
755                const { assert!(MIN <= MAX); }
756                Self::new(const_try_opt!(self.get().checked_shr(rhs)))
757            }
758
759            /// Unchecked shift right. Computes `self >> rhs`, assuming that the result is in range.
760            ///
761            /// # Safety
762            ///
763            /// The result of `self >> rhs` must be in the range `MIN..=MAX`.
764            #[must_use = "this returns the result of the operation, without modifying the original"]
765            #[track_caller]
766            #[inline(always)]
767            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
768                const { assert!(MIN <= MAX); }
769                // Safety: The caller must ensure that the result is in range.
770                unsafe {
771                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_shr(rhs)))
772                }
773            }
774
775            if_signed!($is_signed
776            /// Checked absolute value. Computes `self.abs()`, returning `None` if the resulting
777            /// value is out of range.
778            #[must_use = "this returns the result of the operation, without modifying the original"]
779            #[inline]
780            pub const fn checked_abs(self) -> Option<Self> {
781                const { assert!(MIN <= MAX); }
782                Self::new(const_try_opt!(self.get().checked_abs()))
783            }
784
785            /// Unchecked absolute value. Computes `self.abs()`, assuming that the result is in
786            /// range.
787            ///
788            /// # Safety
789            ///
790            /// The result of `self.abs()` must be in the range `MIN..=MAX`.
791            #[must_use = "this returns the result of the operation, without modifying the original"]
792            #[track_caller]
793            #[inline(always)]
794            pub const unsafe fn unchecked_abs(self) -> Self {
795                const { assert!(MIN <= MAX); }
796                // Safety: The caller must ensure that the result is in range.
797                unsafe { Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_abs())) }
798            }
799
800            /// Absolute value. Computes `self.abs()`, **failing to compile** if the result is not
801            /// guaranteed to be in range.
802            #[must_use = "this returns the result of the operation, without modifying the original"]
803            #[inline(always)]
804            pub const fn abs(self) -> Self {
805                const {
806                    assert!(MIN <= MAX);
807                    assert!(MIN != $internal::MIN);
808                    assert!(-MIN <= MAX);
809                }
810                // <Self as $crate::traits::AbsIsSafe>::ASSERT;
811                // Safety: The compiler asserts that the result is in range.
812                unsafe { self.unchecked_abs() }
813            });
814
815            /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if the resulting
816            /// value is out of range.
817            #[must_use = "this returns the result of the operation, without modifying the original"]
818            #[inline]
819            pub const fn checked_pow(self, exp: u32) -> Option<Self> {
820                const { assert!(MIN <= MAX); }
821                Self::new(const_try_opt!(self.get().checked_pow(exp)))
822            }
823
824            /// Unchecked exponentiation. Computes `self.pow(exp)`, assuming that the result is in
825            /// range.
826            ///
827            /// # Safety
828            ///
829            /// The result of `self.pow(exp)` must be in the range `MIN..=MAX`.
830            #[must_use = "this returns the result of the operation, without modifying the original"]
831            #[track_caller]
832            #[inline(always)]
833            pub const unsafe fn unchecked_pow(self, exp: u32) -> Self {
834                const { assert!(MIN <= MAX); }
835                // Safety: The caller must ensure that the result is in range.
836                unsafe {
837                    Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_pow(exp)))
838                }
839            }
840
841            /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
842            /// bounds.
843            #[must_use = "this returns the result of the operation, without modifying the original"]
844            #[inline]
845            pub const fn saturating_add(self, rhs: $internal) -> Self {
846                const { assert!(MIN <= MAX); }
847                Self::new_saturating(self.get().saturating_add(rhs))
848            }
849
850            /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric
851            /// bounds.
852            #[must_use = "this returns the result of the operation, without modifying the original"]
853            #[inline]
854            pub const fn saturating_sub(self, rhs: $internal) -> Self {
855                const { assert!(MIN <= MAX); }
856                Self::new_saturating(self.get().saturating_sub(rhs))
857            }
858
859            if_signed!($is_signed
860            /// Saturating integer negation. Computes `self - rhs`, saturating at the numeric
861            /// bounds.
862            #[must_use = "this returns the result of the operation, without modifying the original"]
863            #[inline]
864            pub const fn saturating_neg(self) -> Self {
865                const { assert!(MIN <= MAX); }
866                Self::new_saturating(self.get().saturating_neg())
867            });
868
869            if_signed!($is_signed
870            /// Saturating absolute value. Computes `self.abs()`, saturating at the numeric bounds.
871            #[must_use = "this returns the result of the operation, without modifying the original"]
872            #[inline]
873            pub const fn saturating_abs(self) -> Self {
874                const { assert!(MIN <= MAX); }
875                Self::new_saturating(self.get().saturating_abs())
876            });
877
878            /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric
879            /// bounds.
880            #[must_use = "this returns the result of the operation, without modifying the original"]
881            #[inline]
882            pub const fn saturating_mul(self, rhs: $internal) -> Self {
883                const { assert!(MIN <= MAX); }
884                Self::new_saturating(self.get().saturating_mul(rhs))
885            }
886
887            /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the
888            /// numeric bounds.
889            #[must_use = "this returns the result of the operation, without modifying the original"]
890            #[inline]
891            pub const fn saturating_pow(self, exp: u32) -> Self {
892                const { assert!(MIN <= MAX); }
893                Self::new_saturating(self.get().saturating_pow(exp))
894            }
895
896            if_signed! { $is_signed
897                /// Returns `true` if the number is positive and `false` if the number is zero or
898                /// negative.
899                #[inline]
900                pub const fn is_positive(self) -> bool {
901                    const { assert!(MIN <= MAX); }
902                    self.get().is_positive()
903                }
904
905                /// Returns `true` if the number is negative and `false` if the number is zero or
906                /// positive.
907                #[inline]
908                pub const fn is_negative(self) -> bool {
909                    const { assert!(MIN <= MAX); }
910                    self.get().is_negative()
911                }
912            }
913
914            /// Compute the `rem_euclid` of this type with its unsigned type equivalent
915            // Not public because it doesn't match stdlib's "method_unsigned implemented only for signed type" tradition.
916            // Also because this isn't implemented for normal types in std.
917            #[must_use = "this returns the result of the operation, without modifying the original"]
918            #[track_caller]
919            #[inline]
920            #[allow(trivial_numeric_casts)] // needed since some casts have to send unsigned -> unsigned to handle signed -> unsigned
921            const fn rem_euclid_unsigned(
922                rhs: $internal,
923                range_len: $unsigned_type
924            ) -> $unsigned_type {
925                #[allow(unused_comparisons)]
926                if rhs >= 0 {
927                    (rhs as $unsigned_type) % range_len
928                } else {
929                    // Let ux refer to an n bit unsigned and ix refer to an n bit signed integer.
930                    // Can't write -ux or ux::abs() method. This gets around compilation error.
931                    // `wrapping_sub` is to handle rhs = ix::MIN since ix::MIN = -ix::MAX-1
932                    let rhs_abs = ($internal::wrapping_sub(0, rhs)) as $unsigned_type;
933                    // Largest multiple of range_len <= type::MAX is lowest if range_len * 2 > ux::MAX -> range_len >= ux::MAX / 2 + 1
934                    // Also = 0 in mod range_len arithmetic.
935                    // Sub from this large number rhs_abs (same as sub -rhs = -(-rhs) = add rhs) to get rhs % range_len
936                    // ix::MIN = -2^(n-1) so 0 <= rhs_abs <= 2^(n-1)
937                    // ux::MAX / 2 + 1 = 2^(n-1) so this subtraction will always be a >= 0 after subtraction
938                    // Thus converting rhs signed negative to equivalent positive value in mod range_len arithmetic
939                    ((($unsigned_type::MAX / range_len) * range_len) - (rhs_abs)) % range_len
940                }
941            }
942
943            /// Wrapping integer addition. Computes `self + rhs`, wrapping around the numeric
944            /// bounds.
945            #[must_use = "this returns the result of the operation, without modifying the original"]
946            #[inline]
947            #[allow(trivial_numeric_casts)] // needed since some casts have to send unsigned -> unsigned to handle signed -> unsigned
948            pub const fn wrapping_add(self, rhs: $internal) -> Self {
949                const { assert!(MIN <= MAX); }
950                // Forward to internal type's impl if same as type.
951                if MIN == $internal::MIN && MAX == $internal::MAX {
952                    // Safety: std's wrapping methods match ranged arithmetic when the range is the internal datatype's range.
953                    return unsafe { Self::new_unchecked(self.get().wrapping_add(rhs)) }
954                }
955
956                let inner = self.get();
957
958                // Won't overflow because of std impl forwarding.
959                let range_len = MAX.abs_diff(MIN) + 1;
960
961                // Calculate the offset with proper handling for negative rhs
962                let offset = Self::rem_euclid_unsigned(rhs, range_len);
963
964                let greater_vals = MAX.abs_diff(inner);
965                // No wrap
966                if offset <= greater_vals {
967                    // Safety:
968                    // if inner >= 0 -> No overflow beyond range (offset <= greater_vals)
969                    // if inner < 0: Same as >=0 with caveat:
970                    // `(signed as unsigned).wrapping_add(unsigned) as signed` is the same as
971                    // `signed::checked_add_unsigned(unsigned).unwrap()` or `wrapping_add_unsigned`
972                    // (the difference doesn't matter since it won't overflow),
973                    // but unsigned integers don't have either method so it won't compile that way.
974                    unsafe { Self::new_unchecked(
975                        ((inner as $unsigned_type).wrapping_add(offset)) as $internal
976                    ) }
977                }
978                // Wrap
979                else {
980                    // Safety:
981                    // - offset < range_len by rem_euclid (MIN + ... safe)
982                    // - offset > greater_vals from if statement (offset - (greater_vals + 1) safe)
983                    //
984                    // again using `(signed as unsigned).wrapping_add(unsigned) as signed` = `checked_add_unsigned` trick
985                    unsafe { Self::new_unchecked(
986                        ((MIN as $unsigned_type).wrapping_add(
987                            offset - (greater_vals + 1)
988                        )) as $internal
989                    ) }
990                }
991            }
992
993            /// Wrapping integer subtraction. Computes `self - rhs`, wrapping around the numeric
994            /// bounds.
995            #[must_use = "this returns the result of the operation, without modifying the original"]
996            #[inline]
997            #[allow(trivial_numeric_casts)] // needed since some casts have to send unsigned -> unsigned to handle signed -> unsigned
998            pub const fn wrapping_sub(self, rhs: $internal) -> Self {
999                const { assert!(MIN <= MAX); }
1000                // Forward to internal type's impl if same as type.
1001                if MIN == $internal::MIN && MAX == $internal::MAX {
1002                    // Safety: std's wrapping methods match ranged arithmetic when the range is the internal datatype's range.
1003                    return unsafe { Self::new_unchecked(self.get().wrapping_sub(rhs)) }
1004                }
1005
1006                let inner = self.get();
1007
1008                // Won't overflow because of std impl forwarding.
1009                let range_len = MAX.abs_diff(MIN) + 1;
1010
1011                // Calculate the offset with proper handling for negative rhs
1012                let offset = Self::rem_euclid_unsigned(rhs, range_len);
1013
1014                let lesser_vals = MIN.abs_diff(inner);
1015                // No wrap
1016                if offset <= lesser_vals {
1017                    // Safety:
1018                    // if inner >= 0 -> No overflow beyond range (offset <= greater_vals)
1019                    // if inner < 0: Same as >=0 with caveat:
1020                    // `(signed as unsigned).wrapping_sub(unsigned) as signed` is the same as
1021                    // `signed::checked_sub_unsigned(unsigned).unwrap()` or `wrapping_sub_unsigned`
1022                    // (the difference doesn't matter since it won't overflow below 0),
1023                    // but unsigned integers don't have either method so it won't compile that way.
1024                    unsafe { Self::new_unchecked(
1025                        ((inner as $unsigned_type).wrapping_sub(offset)) as $internal
1026                    ) }
1027                }
1028                // Wrap
1029                else {
1030                    // Safety:
1031                    // - offset < range_len by rem_euclid (MAX - ... safe)
1032                    // - offset > lesser_vals from if statement (offset - (lesser_vals + 1) safe)
1033                    //
1034                    // again using `(signed as unsigned).wrapping_sub(unsigned) as signed` = `checked_sub_unsigned` trick
1035                    unsafe { Self::new_unchecked(
1036                        ((MAX as $unsigned_type).wrapping_sub(
1037                            offset - (lesser_vals + 1)
1038                        )) as $internal
1039                    ) }
1040                }
1041            }
1042        }
1043
1044        impl<const MIN: $internal, const MAX: $internal> $optional_type<MIN, MAX> {
1045            /// The value used as the niche. Must not be in the range `MIN..=MAX`.
1046            const NICHE: $internal = match (MIN, MAX) {
1047                ($internal::MIN, $internal::MAX) => panic!("type has no niche"),
1048                ($internal::MIN, _) => $internal::MAX,
1049                (_, _) => $internal::MIN,
1050            };
1051
1052            /// An optional ranged value that is not present.
1053            #[allow(non_upper_case_globals)]
1054            pub const None: Self = Self(Self::NICHE);
1055
1056            /// Creates an optional ranged value that is present.
1057            #[allow(non_snake_case)]
1058            #[inline(always)]
1059            pub const fn Some(value: $type<MIN, MAX>) -> Self {
1060                const { assert!(MIN <= MAX); }
1061                Self(value.get())
1062            }
1063
1064            /// Returns the value as the standard library's [`Option`] type.
1065            #[inline(always)]
1066            pub const fn get(self) -> Option<$type<MIN, MAX>> {
1067                const { assert!(MIN <= MAX); }
1068                if self.0 == Self::NICHE {
1069                    None
1070                } else {
1071                    // Safety: A stored value that is not the niche is always in range.
1072                    Some(unsafe { $type::new_unchecked(self.0) })
1073                }
1074            }
1075
1076            /// Creates an optional ranged integer without checking the value.
1077            ///
1078            /// # Safety
1079            ///
1080            /// The value must be within the range `MIN..=MAX`. As the value used for niche
1081            /// value optimization is unspecified, the provided value must not be the niche
1082            /// value.
1083            #[inline(always)]
1084            #[track_caller]
1085            pub const unsafe fn some_unchecked(value: $internal) -> Self {
1086                const { assert!(MIN <= MAX); }
1087                // Safety: The caller must ensure that the value is in range.
1088                unsafe { assert_unchecked(MIN <= value && value <= MAX) };
1089                Self(value)
1090            }
1091
1092            /// Obtain the inner value of the struct. This is useful for comparisons.
1093            #[inline(always)]
1094            pub(crate) const fn inner(self) -> $internal {
1095                const { assert!(MIN <= MAX); }
1096                self.0
1097            }
1098
1099            /// Obtain the value of the struct as an `Option` of the primitive type.
1100            ///
1101            /// A call to this function will output a hint to the compiler that the value is in
1102            /// range. In general this will help the optimizer to generate better code, but in edge
1103            /// cases this may lead to worse code generation. To avoid outputting the hint, you can
1104            #[doc = concat!(
1105                "use [`", stringify!($optional_type), "::get_primitive_without_hint`]."
1106            )]
1107            #[inline(always)]
1108            pub const fn get_primitive(self) -> Option<$internal> {
1109                const { assert!(MIN <= MAX); }
1110                Some(const_try_opt!(self.get()).get())
1111            }
1112
1113            /// Obtain the value of the struct as an `Option` of the primitive type.
1114            ///
1115            #[doc = concat!(
1116                "The returned value is identical to [`", stringify!($optional_type), "::",
1117                "get_primitive`]."
1118            )]
1119            /// Unlike `get_primitive`, no hints are output to the compiler indicating the range
1120            /// that the value is in. Depending on the scenario, this may with be helpful or harmful
1121            /// too optimization.
1122            #[inline(always)]
1123            pub const fn get_primitive_without_hint(self) -> Option<$internal> {
1124                const { assert!(MIN <= MAX); }
1125                Some(const_try_opt!(self.get()).get_without_hint())
1126            }
1127
1128            /// Returns `true` if the value is the niche value.
1129            #[inline(always)]
1130            pub const fn is_none(&self) -> bool {
1131                const { assert!(MIN <= MAX); }
1132                self.get().is_none()
1133            }
1134
1135            /// Returns `true` if the value is not the niche value.
1136            #[inline(always)]
1137            pub const fn is_some(&self) -> bool {
1138                const { assert!(MIN <= MAX); }
1139                self.get().is_some()
1140            }
1141        }
1142
1143        impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $type<MIN, MAX> {
1144            #[inline(always)]
1145            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1146                const { assert!(MIN <= MAX); }
1147                self.get().fmt(f)
1148            }
1149        }
1150
1151        impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $optional_type<MIN, MAX> {
1152            #[inline(always)]
1153            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1154                const { assert!(MIN <= MAX); }
1155                self.get().fmt(f)
1156            }
1157        }
1158
1159        impl<const MIN: $internal, const MAX: $internal> fmt::Display for $type<MIN, MAX> {
1160            #[inline(always)]
1161            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1162                const { assert!(MIN <= MAX); }
1163                self.get().fmt(f)
1164            }
1165        }
1166
1167        #[cfg(feature = "powerfmt")]
1168        impl<
1169            const MIN: $internal,
1170            const MAX: $internal,
1171        > smart_display::SmartDisplay for $type<MIN, MAX> {
1172            type Metadata = <$internal as smart_display::SmartDisplay>::Metadata;
1173
1174            #[inline(always)]
1175            fn metadata(
1176                &self,
1177                f: smart_display::FormatterOptions,
1178            ) -> smart_display::Metadata<'_, Self> {
1179                const { assert!(MIN <= MAX); }
1180                self.get_ref().metadata(f).reuse()
1181            }
1182
1183            #[inline(always)]
1184            fn fmt_with_metadata(
1185                &self,
1186                f: &mut fmt::Formatter<'_>,
1187                metadata: smart_display::Metadata<'_, Self>,
1188            ) -> fmt::Result {
1189                const { assert!(MIN <= MAX); }
1190                self.get().fmt_with_metadata(f, metadata.reuse())
1191            }
1192        }
1193
1194        impl<const MIN: $internal, const MAX: $internal> Default for $optional_type<MIN, MAX> {
1195            #[inline(always)]
1196            fn default() -> Self {
1197                const { assert!(MIN <= MAX); }
1198                Self::None
1199            }
1200        }
1201
1202        impl<const MIN: $internal, const MAX: $internal> AsRef<$internal> for $type<MIN, MAX> {
1203            #[inline(always)]
1204            fn as_ref(&self) -> &$internal {
1205                const { assert!(MIN <= MAX); }
1206                &self.get_ref()
1207            }
1208        }
1209
1210        impl<const MIN: $internal, const MAX: $internal> Borrow<$internal> for $type<MIN, MAX> {
1211            #[inline(always)]
1212            fn borrow(&self) -> &$internal {
1213                const { assert!(MIN <= MAX); }
1214                &self.get_ref()
1215            }
1216        }
1217
1218        impl<
1219            const MIN_A: $internal,
1220            const MAX_A: $internal,
1221            const MIN_B: $internal,
1222            const MAX_B: $internal,
1223        > PartialEq<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1224            #[inline(always)]
1225            fn eq(&self, other: &$type<MIN_B, MAX_B>) -> bool {
1226                const {
1227                    assert!(MIN_A <= MAX_A);
1228                    assert!(MIN_B <= MAX_B);
1229                }
1230                self.get() == other.get()
1231            }
1232        }
1233
1234        impl<
1235            const MIN_A: $internal,
1236            const MAX_A: $internal,
1237            const MIN_B: $internal,
1238            const MAX_B: $internal,
1239        > PartialEq<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1240            #[inline(always)]
1241            fn eq(&self, other: &$optional_type<MIN_B, MAX_B>) -> bool {
1242                const {
1243                    assert!(MIN_A <= MAX_A);
1244                    assert!(MIN_B <= MAX_B);
1245                }
1246                self.inner() == other.inner()
1247            }
1248        }
1249
1250        impl<
1251            const MIN_A: $internal,
1252            const MAX_A: $internal,
1253            const MIN_B: $internal,
1254            const MAX_B: $internal,
1255        > PartialOrd<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1256            #[inline(always)]
1257            fn partial_cmp(&self, other: &$type<MIN_B, MAX_B>) -> Option<Ordering> {
1258                const {
1259                    assert!(MIN_A <= MAX_A);
1260                    assert!(MIN_B <= MAX_B);
1261                }
1262                self.get().partial_cmp(&other.get())
1263            }
1264        }
1265
1266        impl<
1267            const MIN_A: $internal,
1268            const MAX_A: $internal,
1269            const MIN_B: $internal,
1270            const MAX_B: $internal,
1271        > PartialOrd<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1272            #[inline]
1273            fn partial_cmp(&self, other: &$optional_type<MIN_B, MAX_B>) -> Option<Ordering> {
1274                const {
1275                    assert!(MIN_A <= MAX_A);
1276                    assert!(MIN_B <= MAX_B);
1277                }
1278                if self.is_none() && other.is_none() {
1279                    Some(Ordering::Equal)
1280                } else if self.is_none() {
1281                    Some(Ordering::Less)
1282                } else if other.is_none() {
1283                    Some(Ordering::Greater)
1284                } else {
1285                    self.inner().partial_cmp(&other.inner())
1286                }
1287            }
1288        }
1289
1290        impl<
1291            const MIN: $internal,
1292            const MAX: $internal,
1293        > Ord for $optional_type<MIN, MAX> {
1294            #[inline]
1295            fn cmp(&self, other: &Self) -> Ordering {
1296                const { assert!(MIN <= MAX); }
1297                if self.is_none() && other.is_none() {
1298                    Ordering::Equal
1299                } else if self.is_none() {
1300                    Ordering::Less
1301                } else if other.is_none() {
1302                    Ordering::Greater
1303                } else {
1304                    self.inner().cmp(&other.inner())
1305                }
1306            }
1307        }
1308
1309        impl<const MIN: $internal, const MAX: $internal> fmt::Binary for $type<MIN, MAX> {
1310            #[inline(always)]
1311            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1312                const { assert!(MIN <= MAX); }
1313                self.get().fmt(f)
1314            }
1315        }
1316
1317        impl<const MIN: $internal, const MAX: $internal> fmt::LowerHex for $type<MIN, MAX> {
1318            #[inline(always)]
1319            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1320                const { assert!(MIN <= MAX); }
1321                self.get().fmt(f)
1322            }
1323        }
1324
1325        impl<const MIN: $internal, const MAX: $internal> fmt::UpperHex for $type<MIN, MAX> {
1326            #[inline(always)]
1327            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1328                const { assert!(MIN <= MAX); }
1329                self.get().fmt(f)
1330            }
1331        }
1332
1333        impl<const MIN: $internal, const MAX: $internal> fmt::LowerExp for $type<MIN, MAX> {
1334            #[inline(always)]
1335            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1336                const { assert!(MIN <= MAX); }
1337                self.get().fmt(f)
1338            }
1339        }
1340
1341        impl<const MIN: $internal, const MAX: $internal> fmt::UpperExp for $type<MIN, MAX> {
1342            #[inline(always)]
1343            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1344                const { assert!(MIN <= MAX); }
1345                self.get().fmt(f)
1346            }
1347        }
1348
1349        impl<const MIN: $internal, const MAX: $internal> fmt::Octal for $type<MIN, MAX> {
1350            #[inline(always)]
1351            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1352                const { assert!(MIN <= MAX); }
1353                self.get().fmt(f)
1354            }
1355        }
1356
1357        if_unsigned! { $is_signed
1358            impl From<NonZero<$internal>> for $type<1, { $internal::MAX }> {
1359                #[inline(always)]
1360                fn from(value: NonZero<$internal>) -> Self {
1361                    Self::from_nonzero(value)
1362                }
1363            }
1364
1365            impl From<$type<1, { $internal::MAX }>> for NonZero<$internal> {
1366                #[inline(always)]
1367                fn from(value: $type<1, { $internal::MAX }>) -> Self {
1368                    value.to_nonzero()
1369                }
1370            }
1371        }
1372
1373        impl<const MIN: $internal, const MAX: $internal> From<$type<MIN, MAX>> for $internal {
1374            #[inline(always)]
1375            fn from(value: $type<MIN, MAX>) -> Self {
1376                const { assert!(MIN <= MAX); }
1377                value.get()
1378            }
1379        }
1380
1381        impl<
1382            const MIN: $internal,
1383            const MAX: $internal,
1384        > From<$type<MIN, MAX>> for $optional_type<MIN, MAX> {
1385            #[inline(always)]
1386            fn from(value: $type<MIN, MAX>) -> Self {
1387                const { assert!(MIN <= MAX); }
1388                Self::Some(value)
1389            }
1390        }
1391
1392        impl<
1393            const MIN: $internal,
1394            const MAX: $internal,
1395        > From<Option<$type<MIN, MAX>>> for $optional_type<MIN, MAX> {
1396            #[inline(always)]
1397            fn from(value: Option<$type<MIN, MAX>>) -> Self {
1398                const { assert!(MIN <= MAX); }
1399                match value {
1400                    Some(value) => Self::Some(value),
1401                    None => Self::None,
1402                }
1403            }
1404        }
1405
1406        impl<
1407            const MIN: $internal,
1408            const MAX: $internal,
1409        > From<$optional_type<MIN, MAX>> for Option<$type<MIN, MAX>> {
1410            #[inline(always)]
1411            fn from(value: $optional_type<MIN, MAX>) -> Self {
1412                const { assert!(MIN <= MAX); }
1413                value.get()
1414            }
1415        }
1416
1417        impl<const MIN: $internal, const MAX: $internal> TryFrom<$internal> for $type<MIN, MAX> {
1418            type Error = TryFromIntError;
1419
1420            #[inline]
1421            fn try_from(value: $internal) -> Result<Self, Self::Error> {
1422                const { assert!(MIN <= MAX); }
1423                Self::new(value).ok_or(TryFromIntError)
1424            }
1425        }
1426
1427        impl<const MIN: $internal, const MAX: $internal> FromStr for $type<MIN, MAX> {
1428            type Err = ParseIntError;
1429
1430            #[inline]
1431            fn from_str(s: &str) -> Result<Self, Self::Err> {
1432                const { assert!(MIN <= MAX); }
1433                let value = s.parse::<$internal>().map_err(|e| ParseIntError {
1434                    kind: e.kind().clone()
1435                })?;
1436                if value < MIN {
1437                    Err(ParseIntError { kind: IntErrorKind::NegOverflow })
1438                } else if value > MAX {
1439                    Err(ParseIntError { kind: IntErrorKind::PosOverflow })
1440                } else {
1441                    // Safety: The value was previously checked for validity.
1442                    Ok(unsafe { Self::new_unchecked(value) })
1443                }
1444            }
1445        }
1446
1447        $(impl<
1448                const MIN_SRC: $from_internal,
1449                const MAX_SRC: $from_internal,
1450                const MIN_DST: $internal,
1451                const MAX_DST: $internal,
1452            > From<$from<MIN_SRC, MAX_SRC>> for $type<MIN_DST, MAX_DST>
1453        {
1454            #[inline(always)]
1455            #[allow(trivial_numeric_casts, unused_comparisons)]
1456            fn from(value: $from<MIN_SRC, MAX_SRC>) -> Self {
1457                const {
1458                    assert!(MIN_SRC <= MAX_SRC, "source range is invalid");
1459                    assert!(MIN_DST <= MAX_DST, "target range is invalid");
1460
1461                    match ($from_internal::MIN == 0, $internal::MIN == 0) {
1462                        // unsigned -> unsigned
1463                        (true, true) => {
1464                            assert!(
1465                                MIN_SRC as u128 >= MIN_DST as u128,
1466                                "minimum value cannot be represented in the target range"
1467                            );
1468                            assert!(
1469                                MAX_SRC as u128 <= MAX_DST as u128,
1470                                "maximum value cannot be represented in the target range"
1471                            );
1472                        }
1473                        // signed -> signed
1474                        (false, false) => {
1475                            assert!(
1476                                MIN_SRC as i128 >= MIN_DST as i128,
1477                                "minimum value cannot be represented in the target range"
1478                            );
1479                            assert!(
1480                                MAX_SRC as i128 <= MAX_DST as i128,
1481                                "maximum value cannot be represented in the target range"
1482                            );
1483                        }
1484                        // unsigned -> signed
1485                        (true, false) => {
1486                            assert!(
1487                                MIN_DST < 0 || MIN_SRC as u128 >= MIN_DST as u128,
1488                                "minimum value cannot be represented in the target range"
1489                            );
1490                            assert!(
1491                                MAX_DST >= 0
1492                                    && MAX_SRC as u128 <= i128::MAX as u128
1493                                    && MAX_SRC as i128 <= MAX_DST as i128,
1494                                "maximum value cannot be represented in the target range"
1495                            );
1496                        }
1497                        // signed -> unsigned
1498                        (false, true) => {
1499                            assert!(
1500                                MIN_SRC >= 0 && MIN_SRC as u128 >= MIN_DST as u128,
1501                                "minimum value cannot be represented in the target range"
1502                            );
1503                            assert!(
1504                                MAX_SRC >= 0 && MAX_SRC as u128 <= MAX_DST as u128,
1505                                "maximum value cannot be represented in the target range"
1506                            );
1507                        }
1508                    }
1509                }
1510
1511                // Safety: The source range is a subset of the destination range.
1512                unsafe { $type::new_unchecked(value.get() as $internal) }
1513            }
1514        })+
1515
1516        #[cfg(feature = "serde")]
1517        impl<const MIN: $internal, const MAX: $internal> serde_core::Serialize for $type<MIN, MAX> {
1518            #[inline(always)]
1519            fn serialize<S: serde_core::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>
1520            {
1521                const { assert!(MIN <= MAX); }
1522                self.get().serialize(serializer)
1523            }
1524        }
1525
1526        #[cfg(feature = "serde")]
1527        impl<
1528            const MIN: $internal,
1529            const MAX: $internal,
1530        > serde_core::Serialize for $optional_type<MIN, MAX> {
1531            #[inline(always)]
1532            fn serialize<S: serde_core::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>
1533            {
1534                const { assert!(MIN <= MAX); }
1535                self.get().serialize(serializer)
1536            }
1537        }
1538
1539        #[cfg(feature = "serde")]
1540        impl<
1541            'de,
1542            const MIN: $internal,
1543            const MAX: $internal,
1544        > serde_core::Deserialize<'de> for $type<MIN, MAX> {
1545            #[inline]
1546            fn deserialize<D: serde_core::Deserializer<'de>>(deserializer: D)
1547                -> Result<Self, D::Error>
1548            {
1549                const { assert!(MIN <= MAX); }
1550                let internal = <$internal>::deserialize(deserializer)?;
1551                Self::new(internal).ok_or_else(||
1552                    <D::Error as serde_core::de::Error>::invalid_value(
1553                        serde_core::de::Unexpected::Other("integer"),
1554                        #[cfg(feature = "alloc")] {
1555                            &alloc::format!("an integer in the range {}..={}", MIN, MAX).as_ref()
1556                        },
1557                        #[cfg(not(feature = "alloc"))] {
1558                            &"an integer in the valid range"
1559                        }
1560                    )
1561                )
1562            }
1563        }
1564
1565        #[cfg(feature = "serde")]
1566        impl<
1567            'de,
1568            const MIN: $internal,
1569            const MAX: $internal,
1570        > serde_core::Deserialize<'de> for $optional_type<MIN, MAX> {
1571            #[inline]
1572            fn deserialize<D: serde_core::Deserializer<'de>>(deserializer: D)
1573                -> Result<Self, D::Error>
1574            {
1575                const { assert!(MIN <= MAX); }
1576                Ok(Self::Some($type::<MIN, MAX>::deserialize(deserializer)?))
1577            }
1578        }
1579
1580        #[cfg(feature = "rand08")]
1581        impl<
1582            const MIN: $internal,
1583            const MAX: $internal,
1584        > rand08::distributions::Distribution<$type<MIN, MAX>> for rand08::distributions::Standard {
1585            #[inline]
1586            fn sample<R: rand08::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1587                const { assert!(MIN <= MAX); }
1588                $type::new(rng.gen_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1589            }
1590        }
1591
1592        if_not_manual_rand_09! {
1593            [$($($skips)+)?]
1594            #[cfg(feature = "rand09")]
1595            impl<
1596                const MIN: $internal,
1597                const MAX: $internal,
1598            > rand09::distr::Distribution<$type<MIN, MAX>> for rand09::distr::StandardUniform {
1599                #[inline]
1600                fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1601                    const { assert!(MIN <= MAX); }
1602                    $type::new(rng.random_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1603                }
1604            }
1605        }
1606
1607        #[cfg(feature = "rand08")]
1608        impl<
1609            const MIN: $internal,
1610            const MAX: $internal,
1611        > rand08::distributions::Distribution<$optional_type<MIN, MAX>>
1612        for rand08::distributions::Standard {
1613            #[inline]
1614            fn sample<R: rand08::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1615                const { assert!(MIN <= MAX); }
1616                rng.r#gen::<Option<$type<MIN, MAX>>>().into()
1617            }
1618        }
1619
1620        #[cfg(feature = "rand09")]
1621        impl<
1622            const MIN: $internal,
1623            const MAX: $internal,
1624        > rand09::distr::Distribution<$optional_type<MIN, MAX>>
1625        for rand09::distr::StandardUniform {
1626            #[inline]
1627            fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1628                const { assert!(MIN <= MAX); }
1629                if rng.random() {
1630                    $optional_type::None
1631                } else {
1632                    $optional_type::Some(rng.random::<$type<MIN, MAX>>())
1633                }
1634            }
1635        }
1636
1637        #[cfg(feature = "num")]
1638        impl<const MIN: $internal, const MAX: $internal> num_traits::Bounded for $type<MIN, MAX> {
1639            #[inline(always)]
1640            fn min_value() -> Self {
1641                const { assert!(MIN <= MAX); }
1642                Self::MIN
1643            }
1644
1645            #[inline(always)]
1646            fn max_value() -> Self {
1647                const { assert!(MIN <= MAX); }
1648                Self::MAX
1649            }
1650        }
1651
1652        #[cfg(feature = "quickcheck")]
1653        impl<const MIN: $internal, const MAX: $internal> quickcheck::Arbitrary for $type<MIN, MAX> {
1654            #[inline]
1655            fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1656                const { assert!(MIN <= MAX); }
1657                // Safety: The `rem_euclid` call and addition ensure that the value is in range.
1658                unsafe {
1659                    Self::new_unchecked($internal::arbitrary(g).rem_euclid(MAX - MIN + 1) + MIN)
1660                }
1661            }
1662
1663            #[inline]
1664            fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1665                ::alloc::boxed::Box::new(
1666                    self.get()
1667                        .shrink()
1668                        .filter_map(Self::new)
1669                )
1670            }
1671        }
1672
1673        #[cfg(feature = "quickcheck")]
1674        impl<
1675            const MIN: $internal,
1676            const MAX: $internal,
1677        > quickcheck::Arbitrary for $optional_type<MIN, MAX> {
1678            #[inline]
1679            fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1680                const { assert!(MIN <= MAX); }
1681                Option::<$type<MIN, MAX>>::arbitrary(g).into()
1682            }
1683
1684            #[inline]
1685            fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1686                ::alloc::boxed::Box::new(self.get().shrink().map(Self::from))
1687            }
1688        }
1689    )*};
1690}
1691
1692impl_ranged! {
1693    RangedU8 {
1694        mod_name: ranged_u8
1695        internal: u8
1696        signed: false
1697        unsigned: u8
1698        optional: OptionRangedU8
1699        from: [
1700            RangedU16(u16)
1701            RangedU32(u32)
1702            RangedU64(u64)
1703            RangedU128(u128)
1704            RangedUsize(usize)
1705            RangedI8(i8)
1706            RangedI16(i16)
1707            RangedI32(i32)
1708            RangedI64(i64)
1709            RangedI128(i128)
1710            RangedIsize(isize)
1711        ]
1712    }
1713    RangedU16 {
1714        mod_name: ranged_u16
1715        internal: u16
1716        signed: false
1717        unsigned: u16
1718        optional: OptionRangedU16
1719        from: [
1720            RangedU8(u8)
1721            RangedU32(u32)
1722            RangedU64(u64)
1723            RangedU128(u128)
1724            RangedUsize(usize)
1725            RangedI8(i8)
1726            RangedI16(i16)
1727            RangedI32(i32)
1728            RangedI64(i64)
1729            RangedI128(i128)
1730            RangedIsize(isize)
1731        ]
1732    }
1733    RangedU32 {
1734        mod_name: ranged_u32
1735        internal: u32
1736        signed: false
1737        unsigned: u32
1738        optional: OptionRangedU32
1739        from: [
1740            RangedU8(u8)
1741            RangedU16(u16)
1742            RangedU64(u64)
1743            RangedU128(u128)
1744            RangedUsize(usize)
1745            RangedI8(i8)
1746            RangedI16(i16)
1747            RangedI32(i32)
1748            RangedI64(i64)
1749            RangedI128(i128)
1750            RangedIsize(isize)
1751        ]
1752    }
1753    RangedU64 {
1754        mod_name: ranged_u64
1755        internal: u64
1756        signed: false
1757        unsigned: u64
1758        optional: OptionRangedU64
1759        from: [
1760            RangedU8(u8)
1761            RangedU16(u16)
1762            RangedU32(u32)
1763            RangedU128(u128)
1764            RangedUsize(usize)
1765            RangedI8(i8)
1766            RangedI16(i16)
1767            RangedI32(i32)
1768            RangedI64(i64)
1769            RangedI128(i128)
1770            RangedIsize(isize)
1771        ]
1772    }
1773    RangedU128 {
1774        mod_name: ranged_u128
1775        internal: u128
1776        signed: false
1777        unsigned: u128
1778        optional: OptionRangedU128
1779        from: [
1780            RangedU8(u8)
1781            RangedU16(u16)
1782            RangedU32(u32)
1783            RangedU64(u64)
1784            RangedUsize(usize)
1785            RangedI8(i8)
1786            RangedI16(i16)
1787            RangedI32(i32)
1788            RangedI64(i64)
1789            RangedI128(i128)
1790            RangedIsize(isize)
1791        ]
1792    }
1793    RangedUsize {
1794        mod_name: ranged_usize
1795        internal: usize
1796        signed: false
1797        unsigned: usize
1798        optional: OptionRangedUsize
1799        from: [
1800            RangedU8(u8)
1801            RangedU16(u16)
1802            RangedU32(u32)
1803            RangedU64(u64)
1804            RangedU128(u128)
1805            RangedI8(i8)
1806            RangedI16(i16)
1807            RangedI32(i32)
1808            RangedI64(i64)
1809            RangedI128(i128)
1810            RangedIsize(isize)
1811        ]
1812        manual: [rand_09]
1813    }
1814    RangedI8 {
1815        mod_name: ranged_i8
1816        internal: i8
1817        signed: true
1818        unsigned: u8
1819        optional: OptionRangedI8
1820        from: [
1821            RangedU8(u8)
1822            RangedU16(u16)
1823            RangedU32(u32)
1824            RangedU64(u64)
1825            RangedU128(u128)
1826            RangedUsize(usize)
1827            RangedI16(i16)
1828            RangedI32(i32)
1829            RangedI64(i64)
1830            RangedI128(i128)
1831            RangedIsize(isize)
1832        ]
1833    }
1834    RangedI16 {
1835        mod_name: ranged_i16
1836        internal: i16
1837        signed: true
1838        unsigned: u16
1839        optional: OptionRangedI16
1840        from: [
1841            RangedU8(u8)
1842            RangedU16(u16)
1843            RangedU32(u32)
1844            RangedU64(u64)
1845            RangedU128(u128)
1846            RangedUsize(usize)
1847            RangedI8(i8)
1848            RangedI32(i32)
1849            RangedI64(i64)
1850            RangedI128(i128)
1851            RangedIsize(isize)
1852        ]
1853    }
1854    RangedI32 {
1855        mod_name: ranged_i32
1856        internal: i32
1857        signed: true
1858        unsigned: u32
1859        optional: OptionRangedI32
1860        from: [
1861            RangedU8(u8)
1862            RangedU16(u16)
1863            RangedU32(u32)
1864            RangedU64(u64)
1865            RangedU128(u128)
1866            RangedUsize(usize)
1867            RangedI8(i8)
1868            RangedI16(i16)
1869            RangedI64(i64)
1870            RangedI128(i128)
1871            RangedIsize(isize)
1872        ]
1873    }
1874    RangedI64 {
1875        mod_name: ranged_i64
1876        internal: i64
1877        signed: true
1878        unsigned: u64
1879        optional: OptionRangedI64
1880        from: [
1881            RangedU8(u8)
1882            RangedU16(u16)
1883            RangedU32(u32)
1884            RangedU64(u64)
1885            RangedU128(u128)
1886            RangedUsize(usize)
1887            RangedI8(i8)
1888            RangedI16(i16)
1889            RangedI32(i32)
1890            RangedI128(i128)
1891            RangedIsize(isize)
1892        ]
1893    }
1894    RangedI128 {
1895        mod_name: ranged_i128
1896        internal: i128
1897        signed: true
1898        unsigned: u128
1899        optional: OptionRangedI128
1900        from: [
1901            RangedU8(u8)
1902            RangedU16(u16)
1903            RangedU32(u32)
1904            RangedU64(u64)
1905            RangedU128(u128)
1906            RangedUsize(usize)
1907            RangedI8(i8)
1908            RangedI16(i16)
1909            RangedI32(i32)
1910            RangedI64(i64)
1911            RangedIsize(isize)
1912        ]
1913    }
1914    RangedIsize {
1915        mod_name: ranged_isize
1916        internal: isize
1917        signed: true
1918        unsigned: usize
1919        optional: OptionRangedIsize
1920        from: [
1921            RangedU8(u8)
1922            RangedU16(u16)
1923            RangedU32(u32)
1924            RangedU64(u64)
1925            RangedU128(u128)
1926            RangedUsize(usize)
1927            RangedI8(i8)
1928            RangedI16(i16)
1929            RangedI32(i32)
1930            RangedI64(i64)
1931            RangedI128(i128)
1932        ]
1933        manual: [rand_09]
1934    }
1935}
1936
1937#[cfg(feature = "rand09")]
1938impl<const MIN: usize, const MAX: usize> rand09::distr::Distribution<RangedUsize<MIN, MAX>>
1939    for rand09::distr::StandardUniform
1940{
1941    #[inline]
1942    fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> RangedUsize<MIN, MAX> {
1943        const {
1944            assert!(MIN <= MAX);
1945        }
1946
1947        #[cfg(target_pointer_width = "16")]
1948        let value = rng.random_range(MIN as u16..=MAX as u16) as usize;
1949        #[cfg(target_pointer_width = "32")]
1950        let value = rng.random_range(MIN as u32..=MAX as u32) as usize;
1951        #[cfg(target_pointer_width = "64")]
1952        let value = rng.random_range(MIN as u64..=MAX as u64) as usize;
1953        #[cfg(not(any(
1954            target_pointer_width = "16",
1955            target_pointer_width = "32",
1956            target_pointer_width = "64"
1957        )))]
1958        compile_error("platform has unusual (and unsupported) pointer width");
1959
1960        RangedUsize::new(value).expect("rand failed to generate a valid value")
1961    }
1962}
1963
1964#[cfg(feature = "rand09")]
1965impl<const MIN: isize, const MAX: isize> rand09::distr::Distribution<RangedIsize<MIN, MAX>>
1966    for rand09::distr::StandardUniform
1967{
1968    #[inline]
1969    fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> RangedIsize<MIN, MAX> {
1970        const {
1971            assert!(MIN <= MAX);
1972        }
1973
1974        #[cfg(target_pointer_width = "16")]
1975        let value = rng.random_range(MIN as i16..=MAX as i16) as isize;
1976        #[cfg(target_pointer_width = "32")]
1977        let value = rng.random_range(MIN as i32..=MAX as i32) as isize;
1978        #[cfg(target_pointer_width = "64")]
1979        let value = rng.random_range(MIN as i64..=MAX as i64) as isize;
1980        #[cfg(not(any(
1981            target_pointer_width = "16",
1982            target_pointer_width = "32",
1983            target_pointer_width = "64"
1984        )))]
1985        compile_error("platform has unusual (and unsupported) pointer width");
1986
1987        RangedIsize::new(value).expect("rand failed to generate a valid value")
1988    }
1989}