Coverage Report

Created: 2025-11-16 06:16

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