Coverage Report

Created: 2026-05-30 06:54

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