Skip to main content

deranged/
lib.rs

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