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