Coverage Report

Created: 2025-09-27 06:45

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