deranged/
lib.rs

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