deranged/
lib.rs

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