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