Coverage Report

Created: 2025-08-26 07:04

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