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