deranged/
lib.rs

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