1#![cfg_attr(docs_rs, feature(doc_auto_cfg))]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![deny(
4 anonymous_parameters,
5 clippy::all,
6 clippy::missing_safety_doc,
7 clippy::missing_safety_doc,
8 clippy::undocumented_unsafe_blocks,
9 illegal_floating_point_literal_pattern,
10 late_bound_lifetime_arguments,
11 patterns_in_fns_without_body,
12 rust_2018_idioms,
13 trivial_casts,
14 trivial_numeric_casts,
15 unreachable_pub,
16 unsafe_op_in_unsafe_fn,
17 unused_extern_crates
18)]
19#![warn(
20 clippy::dbg_macro,
21 clippy::decimal_literal_representation,
22 clippy::get_unwrap,
23 clippy::nursery,
24 clippy::pedantic,
25 clippy::todo,
26 clippy::unimplemented,
27 clippy::unwrap_used,
28 clippy::use_debug,
29 missing_copy_implementations,
30 missing_debug_implementations,
31 unused_qualifications,
32 variant_size_differences
33)]
34#![allow(
35 path_statements, clippy::inline_always,
37 clippy::missing_errors_doc,
38 clippy::must_use_candidate,
39 clippy::redundant_pub_crate,
40)]
41#![doc(test(attr(deny(warnings))))]
42
43#[cfg(test)]
44mod tests;
45mod traits;
46mod unsafe_wrapper;
47
48#[cfg(feature = "alloc")]
49#[allow(unused_extern_crates)]
50extern crate alloc;
51
52use core::borrow::Borrow;
53use core::cmp::Ordering;
54use core::fmt;
55use core::num::IntErrorKind;
56use core::str::FromStr;
57#[cfg(feature = "std")]
58use std::error::Error;
59
60#[cfg(feature = "powerfmt")]
61use powerfmt::smart_display;
62
63use crate::unsafe_wrapper::Unsafe;
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub struct TryFromIntError;
67
68impl fmt::Display for TryFromIntError {
69 #[inline]
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.write_str("out of range integral type conversion attempted")
72 }
73}
74#[cfg(feature = "std")]
75impl Error for TryFromIntError {}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct ParseIntError {
79 kind: IntErrorKind,
80}
81
82impl ParseIntError {
83 #[allow(clippy::missing_const_for_fn)]
86 #[inline(always)]
87 pub fn kind(&self) -> &IntErrorKind {
88 &self.kind
89 }
90}
91
92impl fmt::Display for ParseIntError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 match self.kind {
95 IntErrorKind::Empty => "cannot parse integer from empty string",
96 IntErrorKind::InvalidDigit => "invalid digit found in string",
97 IntErrorKind::PosOverflow => "number too large to fit in target type",
98 IntErrorKind::NegOverflow => "number too small to fit in target type",
99 IntErrorKind::Zero => "number would be zero for non-zero type",
100 _ => "Unknown Int error kind",
101 }
102 .fmt(f)
103 }
104}
105
106#[cfg(feature = "std")]
107impl Error for ParseIntError {}
108
109macro_rules! const_try_opt {
110 ($e:expr) => {
111 match $e {
112 Some(value) => value,
113 None => return None,
114 }
115 };
116}
117
118macro_rules! if_signed {
119 (true $($x:tt)*) => { $($x)*};
120 (false $($x:tt)*) => {};
121}
122
123macro_rules! if_unsigned {
124 (true $($x:tt)*) => {};
125 (false $($x:tt)*) => { $($x)* };
126}
127
128macro_rules! article {
129 (true) => {
130 "An"
131 };
132 (false) => {
133 "A"
134 };
135}
136
137macro_rules! unsafe_unwrap_unchecked {
138 ($e:expr) => {{
139 let opt = $e;
140 debug_assert!(opt.is_some());
141 match $e {
142 Some(value) => value,
143 None => core::hint::unreachable_unchecked(),
144 }
145 }};
146}
147
148#[inline]
155const unsafe fn assume(b: bool) {
156 debug_assert!(b);
157 if !b {
158 unsafe { core::hint::unreachable_unchecked() }
160 }
161}
162
163macro_rules! impl_ranged {
164 ($(
165 $type:ident {
166 mod_name: $mod_name:ident
167 internal: $internal:ident
168 signed: $is_signed:ident
169 unsigned: $unsigned_type:ident
170 optional: $optional_type:ident
171 }
172 )*) => {$(
173 #[doc = concat!(
174 article!($is_signed),
175 " `",
176 stringify!($internal),
177 "` that is known to be in the range `MIN..=MAX`.",
178 )]
179 #[repr(transparent)]
180 #[derive(Clone, Copy, Eq, Ord, Hash)]
181 pub struct $type<const MIN: $internal, const MAX: $internal>(
182 Unsafe<$internal>,
183 );
184
185 #[doc = concat!(
186 "A `",
187 stringify!($type),
188 "` that is optional. Equivalent to [`Option<",
189 stringify!($type),
190 ">`] with niche value optimization.",
191 )]
192 #[doc = concat!(
194 "If `MIN` is [`",
195 stringify!($internal),
196 "::MIN`] _and_ `MAX` is [`",
197 stringify!($internal)
198 ,"::MAX`] then compilation will fail. This is because there is no way to represent \
199 the niche value.",
200 )]
201 #[doc = concat!("obtained with [`", stringify!($optional_type), "::get`].")]
207 #[repr(transparent)]
208 #[derive(Clone, Copy, Eq, Hash)]
209 pub struct $optional_type<const MIN: $internal, const MAX: $internal>(
210 $internal,
211 );
212
213 impl $type<0, 0> {
214 #[inline(always)]
215 pub const fn exact<const VALUE: $internal>() -> $type<VALUE, VALUE> {
216 unsafe { $type::new_unchecked(VALUE) }
218 }
219 }
220
221 impl<const MIN: $internal, const MAX: $internal> $type<MIN, MAX> {
222 pub const MIN: Self = Self::new_static::<MIN>();
225
226 pub const MAX: Self = Self::new_static::<MAX>();
229
230 #[inline(always)]
236 pub const unsafe fn new_unchecked(value: $internal) -> Self {
237 <Self as $crate::traits::RangeIsValid>::ASSERT;
238 unsafe {
240 $crate::assume(MIN <= value && value <= MAX);
241 Self(Unsafe::new(value))
242 }
243 }
244
245 #[inline(always)]
247 pub const fn get(self) -> $internal {
248 <Self as $crate::traits::RangeIsValid>::ASSERT;
249 unsafe { $crate::assume(MIN <= *self.0.get() && *self.0.get() <= MAX) };
251 *self.0.get()
252 }
253
254 #[inline(always)]
255 pub(crate) const fn get_ref(&self) -> &$internal {
256 <Self as $crate::traits::RangeIsValid>::ASSERT;
257 let value = self.0.get();
258 unsafe { $crate::assume(MIN <= *value && *value <= MAX) };
260 value
261 }
262
263 #[inline(always)]
265 pub const fn new(value: $internal) -> Option<Self> {
266 <Self as $crate::traits::RangeIsValid>::ASSERT;
267 if value < MIN || value > MAX {
268 None
269 } else {
270 Some(unsafe { Self::new_unchecked(value) })
272 }
273 }
274
275 #[inline(always)]
278 pub const fn new_static<const VALUE: $internal>() -> Self {
279 <($type<MIN, VALUE>, $type<VALUE, MAX>) as $crate::traits::StaticIsValid>::ASSERT;
280 unsafe { Self::new_unchecked(VALUE) }
282 }
283
284 #[inline]
286 pub const fn new_saturating(value: $internal) -> Self {
287 <Self as $crate::traits::RangeIsValid>::ASSERT;
288 if value < MIN {
289 Self::MIN
290 } else if value > MAX {
291 Self::MAX
292 } else {
293 unsafe { Self::new_unchecked(value) }
295 }
296 }
297
298 pub const fn expand<const NEW_MIN: $internal, const NEW_MAX: $internal>(
301 self,
302 ) -> $type<NEW_MIN, NEW_MAX> {
303 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
304 <$type<NEW_MIN, NEW_MAX> as $crate::traits::RangeIsValid>::ASSERT;
305 <($type<MIN, MAX>, $type<NEW_MIN, NEW_MAX>) as $crate::traits::ExpandIsValid>
306 ::ASSERT;
307 unsafe { $type::new_unchecked(self.get()) }
309 }
310
311 pub const fn narrow<
315 const NEW_MIN: $internal,
316 const NEW_MAX: $internal,
317 >(self) -> Option<$type<NEW_MIN, NEW_MAX>> {
318 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
319 <$type<NEW_MIN, NEW_MAX> as $crate::traits::RangeIsValid>::ASSERT;
320 <($type<MIN, MAX>, $type<NEW_MIN, NEW_MAX>) as $crate::traits::NarrowIsValid>
321 ::ASSERT;
322 $type::<NEW_MIN, NEW_MAX>::new(self.get())
323 }
324
325 #[doc = concat!("# use deranged::", stringify!($type), ";")]
345 #[doc = concat!(
346 "assert_eq!(",
347 stringify!($type),
348 "::<5, 10>::from_str_radix(\"A\", 16), Ok(",
349 stringify!($type),
350 "::new_static::<10>()));",
351 )]
352 #[inline]
354 pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
355 <Self as $crate::traits::RangeIsValid>::ASSERT;
356 match $internal::from_str_radix(src, radix) {
357 Ok(value) if value > MAX => {
358 Err(ParseIntError { kind: IntErrorKind::PosOverflow })
359 }
360 Ok(value) if value < MIN => {
361 Err(ParseIntError { kind: IntErrorKind::NegOverflow })
362 }
363 Ok(value) => Ok(unsafe { Self::new_unchecked(value) }),
366 Err(e) => Err(ParseIntError { kind: e.kind().clone() }),
367 }
368 }
369
370 #[must_use = "this returns the result of the operation, without modifying the original"]
373 #[inline]
374 pub const fn checked_add(self, rhs: $internal) -> Option<Self> {
375 <Self as $crate::traits::RangeIsValid>::ASSERT;
376 Self::new(const_try_opt!(self.get().checked_add(rhs)))
377 }
378
379 #[must_use = "this returns the result of the operation, without modifying the original"]
386 #[inline(always)]
387 pub const unsafe fn unchecked_add(self, rhs: $internal) -> Self {
388 <Self as $crate::traits::RangeIsValid>::ASSERT;
389 unsafe {
391 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_add(rhs)))
392 }
393 }
394
395 #[must_use = "this returns the result of the operation, without modifying the original"]
398 #[inline]
399 pub const fn checked_sub(self, rhs: $internal) -> Option<Self> {
400 <Self as $crate::traits::RangeIsValid>::ASSERT;
401 Self::new(const_try_opt!(self.get().checked_sub(rhs)))
402 }
403
404 #[must_use = "this returns the result of the operation, without modifying the original"]
411 #[inline(always)]
412 pub const unsafe fn unchecked_sub(self, rhs: $internal) -> Self {
413 <Self as $crate::traits::RangeIsValid>::ASSERT;
414 unsafe {
416 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_sub(rhs)))
417 }
418 }
419
420 #[must_use = "this returns the result of the operation, without modifying the original"]
423 #[inline]
424 pub const fn checked_mul(self, rhs: $internal) -> Option<Self> {
425 <Self as $crate::traits::RangeIsValid>::ASSERT;
426 Self::new(const_try_opt!(self.get().checked_mul(rhs)))
427 }
428
429 #[must_use = "this returns the result of the operation, without modifying the original"]
436 #[inline(always)]
437 pub const unsafe fn unchecked_mul(self, rhs: $internal) -> Self {
438 <Self as $crate::traits::RangeIsValid>::ASSERT;
439 unsafe {
441 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_mul(rhs)))
442 }
443 }
444
445 #[must_use = "this returns the result of the operation, without modifying the original"]
448 #[inline]
449 pub const fn checked_div(self, rhs: $internal) -> Option<Self> {
450 <Self as $crate::traits::RangeIsValid>::ASSERT;
451 Self::new(const_try_opt!(self.get().checked_div(rhs)))
452 }
453
454 #[must_use = "this returns the result of the operation, without modifying the original"]
462 #[inline(always)]
463 pub const unsafe fn unchecked_div(self, rhs: $internal) -> Self {
464 <Self as $crate::traits::RangeIsValid>::ASSERT;
465 unsafe {
468 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_div(rhs)))
469 }
470 }
471
472 #[must_use = "this returns the result of the operation, without modifying the original"]
475 #[inline]
476 pub const fn checked_div_euclid(self, rhs: $internal) -> Option<Self> {
477 <Self as $crate::traits::RangeIsValid>::ASSERT;
478 Self::new(const_try_opt!(self.get().checked_div_euclid(rhs)))
479 }
480
481 #[must_use = "this returns the result of the operation, without modifying the original"]
489 #[inline(always)]
490 pub const unsafe fn unchecked_div_euclid(self, rhs: $internal) -> Self {
491 <Self as $crate::traits::RangeIsValid>::ASSERT;
492 unsafe {
495 Self::new_unchecked(
496 unsafe_unwrap_unchecked!(self.get().checked_div_euclid(rhs))
497 )
498 }
499 }
500
501 if_unsigned!($is_signed
502 #[must_use = "this returns the result of the operation, without modifying the original"]
505 #[inline]
506 pub const fn rem<const RHS_VALUE: $internal>(
507 self,
508 rhs: $type<RHS_VALUE, RHS_VALUE>,
509 ) -> $type<0, RHS_VALUE> {
510 <Self as $crate::traits::RangeIsValid>::ASSERT;
511 unsafe { $type::new_unchecked(self.get() % rhs.get()) }
514 });
515
516 #[must_use = "this returns the result of the operation, without modifying the original"]
519 #[inline]
520 pub const fn checked_rem(self, rhs: $internal) -> Option<Self> {
521 <Self as $crate::traits::RangeIsValid>::ASSERT;
522 Self::new(const_try_opt!(self.get().checked_rem(rhs)))
523 }
524
525 #[must_use = "this returns the result of the operation, without modifying the original"]
533 #[inline(always)]
534 pub const unsafe fn unchecked_rem(self, rhs: $internal) -> Self {
535 <Self as $crate::traits::RangeIsValid>::ASSERT;
536 unsafe {
539 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_rem(rhs)))
540 }
541 }
542
543 #[must_use = "this returns the result of the operation, without modifying the original"]
546 #[inline]
547 pub const fn checked_rem_euclid(self, rhs: $internal) -> Option<Self> {
548 <Self as $crate::traits::RangeIsValid>::ASSERT;
549 Self::new(const_try_opt!(self.get().checked_rem_euclid(rhs)))
550 }
551
552 #[must_use = "this returns the result of the operation, without modifying the original"]
560 #[inline(always)]
561 pub const unsafe fn unchecked_rem_euclid(self, rhs: $internal) -> Self {
562 <Self as $crate::traits::RangeIsValid>::ASSERT;
563 unsafe {
566 Self::new_unchecked(
567 unsafe_unwrap_unchecked!(self.get().checked_rem_euclid(rhs))
568 )
569 }
570 }
571
572 #[must_use = "this returns the result of the operation, without modifying the original"]
575 #[inline]
576 pub const fn checked_neg(self) -> Option<Self> {
577 <Self as $crate::traits::RangeIsValid>::ASSERT;
578 Self::new(const_try_opt!(self.get().checked_neg()))
579 }
580
581 #[must_use = "this returns the result of the operation, without modifying the original"]
587 #[inline(always)]
588 pub const unsafe fn unchecked_neg(self) -> Self {
589 <Self as $crate::traits::RangeIsValid>::ASSERT;
590 unsafe { Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_neg())) }
592 }
593
594 #[must_use = "this returns the result of the operation, without modifying the original"]
597 #[inline(always)]
598 pub const fn neg(self) -> Self {
599 <Self as $crate::traits::RangeIsValid>::ASSERT;
600 <Self as $crate::traits::NegIsSafe>::ASSERT;
601 unsafe { self.unchecked_neg() }
603 }
604
605 #[must_use = "this returns the result of the operation, without modifying the original"]
608 #[inline]
609 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
610 <Self as $crate::traits::RangeIsValid>::ASSERT;
611 Self::new(const_try_opt!(self.get().checked_shl(rhs)))
612 }
613
614 #[must_use = "this returns the result of the operation, without modifying the original"]
620 #[inline(always)]
621 pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
622 <Self as $crate::traits::RangeIsValid>::ASSERT;
623 unsafe {
625 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_shl(rhs)))
626 }
627 }
628
629 #[must_use = "this returns the result of the operation, without modifying the original"]
632 #[inline]
633 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
634 <Self as $crate::traits::RangeIsValid>::ASSERT;
635 Self::new(const_try_opt!(self.get().checked_shr(rhs)))
636 }
637
638 #[must_use = "this returns the result of the operation, without modifying the original"]
644 #[inline(always)]
645 pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
646 <Self as $crate::traits::RangeIsValid>::ASSERT;
647 unsafe {
649 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_shr(rhs)))
650 }
651 }
652
653 if_signed!($is_signed
654 #[must_use = "this returns the result of the operation, without modifying the original"]
657 #[inline]
658 pub const fn checked_abs(self) -> Option<Self> {
659 <Self as $crate::traits::RangeIsValid>::ASSERT;
660 Self::new(const_try_opt!(self.get().checked_abs()))
661 }
662
663 #[must_use = "this returns the result of the operation, without modifying the original"]
670 #[inline(always)]
671 pub const unsafe fn unchecked_abs(self) -> Self {
672 <Self as $crate::traits::RangeIsValid>::ASSERT;
673 unsafe { Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_abs())) }
675 }
676
677 #[must_use = "this returns the result of the operation, without modifying the original"]
680 #[inline(always)]
681 pub const fn abs(self) -> Self {
682 <Self as $crate::traits::RangeIsValid>::ASSERT;
683 <Self as $crate::traits::AbsIsSafe>::ASSERT;
684 unsafe { self.unchecked_abs() }
686 });
687
688 #[must_use = "this returns the result of the operation, without modifying the original"]
691 #[inline]
692 pub const fn checked_pow(self, exp: u32) -> Option<Self> {
693 <Self as $crate::traits::RangeIsValid>::ASSERT;
694 Self::new(const_try_opt!(self.get().checked_pow(exp)))
695 }
696
697 #[must_use = "this returns the result of the operation, without modifying the original"]
704 #[inline(always)]
705 pub const unsafe fn unchecked_pow(self, exp: u32) -> Self {
706 <Self as $crate::traits::RangeIsValid>::ASSERT;
707 unsafe {
709 Self::new_unchecked(unsafe_unwrap_unchecked!(self.get().checked_pow(exp)))
710 }
711 }
712
713 #[must_use = "this returns the result of the operation, without modifying the original"]
716 #[inline]
717 pub const fn saturating_add(self, rhs: $internal) -> Self {
718 <Self as $crate::traits::RangeIsValid>::ASSERT;
719 Self::new_saturating(self.get().saturating_add(rhs))
720 }
721
722 #[must_use = "this returns the result of the operation, without modifying the original"]
725 #[inline]
726 pub const fn saturating_sub(self, rhs: $internal) -> Self {
727 <Self as $crate::traits::RangeIsValid>::ASSERT;
728 Self::new_saturating(self.get().saturating_sub(rhs))
729 }
730
731 if_signed!($is_signed
732 #[must_use = "this returns the result of the operation, without modifying the original"]
735 #[inline]
736 pub const fn saturating_neg(self) -> Self {
737 <Self as $crate::traits::RangeIsValid>::ASSERT;
738 Self::new_saturating(self.get().saturating_neg())
739 });
740
741 if_signed!($is_signed
742 #[must_use = "this returns the result of the operation, without modifying the original"]
744 #[inline]
745 pub const fn saturating_abs(self) -> Self {
746 <Self as $crate::traits::RangeIsValid>::ASSERT;
747 Self::new_saturating(self.get().saturating_abs())
748 });
749
750 #[must_use = "this returns the result of the operation, without modifying the original"]
753 #[inline]
754 pub const fn saturating_mul(self, rhs: $internal) -> Self {
755 <Self as $crate::traits::RangeIsValid>::ASSERT;
756 Self::new_saturating(self.get().saturating_mul(rhs))
757 }
758
759 #[must_use = "this returns the result of the operation, without modifying the original"]
762 #[inline]
763 pub const fn saturating_pow(self, exp: u32) -> Self {
764 <Self as $crate::traits::RangeIsValid>::ASSERT;
765 Self::new_saturating(self.get().saturating_pow(exp))
766 }
767
768 #[must_use = "this returns the result of the operation, without modifying the original"]
773 #[inline]
774 #[allow(trivial_numeric_casts)] const fn rem_euclid_unsigned(
776 rhs: $internal,
777 range_len: $unsigned_type
778 ) -> $unsigned_type {
779 #[allow(unused_comparisons)]
780 if rhs >= 0 {
781 (rhs as $unsigned_type) % range_len
782 } else {
783 let rhs_abs = ($internal::wrapping_sub(0, rhs)) as $unsigned_type;
787 ((($unsigned_type::MAX / range_len) * range_len) - (rhs_abs)) % range_len
794 }
795 }
796
797 #[must_use = "this returns the result of the operation, without modifying the original"]
800 #[inline]
801 #[allow(trivial_numeric_casts)] pub const fn wrapping_add(self, rhs: $internal) -> Self {
803 <Self as $crate::traits::RangeIsValid>::ASSERT;
804 if MIN == $internal::MIN && MAX == $internal::MAX {
806 return unsafe { Self::new_unchecked(self.get().wrapping_add(rhs)) }
808 }
809
810 let inner = self.get();
811
812 let range_len = MAX.abs_diff(MIN) + 1;
814
815 let offset = Self::rem_euclid_unsigned(rhs, range_len);
817
818 let greater_vals = MAX.abs_diff(inner);
819 if offset <= greater_vals {
821 unsafe { Self::new_unchecked(
829 ((inner as $unsigned_type).wrapping_add(offset)) as $internal
830 ) }
831 }
832 else {
834 unsafe { Self::new_unchecked(
840 ((MIN as $unsigned_type).wrapping_add(
841 offset - (greater_vals + 1)
842 )) as $internal
843 ) }
844 }
845 }
846
847 #[must_use = "this returns the result of the operation, without modifying the original"]
850 #[inline]
851 #[allow(trivial_numeric_casts)] pub const fn wrapping_sub(self, rhs: $internal) -> Self {
853 <Self as $crate::traits::RangeIsValid>::ASSERT;
854 if MIN == $internal::MIN && MAX == $internal::MAX {
856 return unsafe { Self::new_unchecked(self.get().wrapping_sub(rhs)) }
858 }
859
860 let inner = self.get();
861
862 let range_len = MAX.abs_diff(MIN) + 1;
864
865 let offset = Self::rem_euclid_unsigned(rhs, range_len);
867
868 let lesser_vals = MIN.abs_diff(inner);
869 if offset <= lesser_vals {
871 unsafe { Self::new_unchecked(
879 ((inner as $unsigned_type).wrapping_sub(offset)) as $internal
880 ) }
881 }
882 else {
884 unsafe { Self::new_unchecked(
890 ((MAX as $unsigned_type).wrapping_sub(
891 offset - (lesser_vals + 1)
892 )) as $internal
893 ) }
894 }
895 }
896 }
897
898 impl<const MIN: $internal, const MAX: $internal> $optional_type<MIN, MAX> {
899 const NICHE: $internal = match (MIN, MAX) {
901 ($internal::MIN, $internal::MAX) => panic!("type has no niche"),
902 ($internal::MIN, _) => $internal::MAX,
903 (_, _) => $internal::MIN,
904 };
905
906 #[allow(non_upper_case_globals)]
908 pub const None: Self = Self(Self::NICHE);
909
910 #[allow(non_snake_case)]
912 #[inline(always)]
913 pub const fn Some(value: $type<MIN, MAX>) -> Self {
914 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
915 Self(value.get())
916 }
917
918 #[inline(always)]
920 pub const fn get(self) -> Option<$type<MIN, MAX>> {
921 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
922 if self.0 == Self::NICHE {
923 None
924 } else {
925 Some(unsafe { $type::new_unchecked(self.0) })
927 }
928 }
929
930 #[inline(always)]
938 pub const unsafe fn some_unchecked(value: $internal) -> Self {
939 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
940 unsafe { $crate::assume(MIN <= value && value <= MAX) };
942 Self(value)
943 }
944
945 #[inline(always)]
947 pub(crate) const fn inner(self) -> $internal {
948 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
949 self.0
950 }
951
952 #[inline(always)]
953 pub const fn get_primitive(self) -> Option<$internal> {
954 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
955 Some(const_try_opt!(self.get()).get())
956 }
957
958 #[inline(always)]
960 pub const fn is_none(self) -> bool {
961 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
962 self.get().is_none()
963 }
964
965 #[inline(always)]
967 pub const fn is_some(self) -> bool {
968 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
969 self.get().is_some()
970 }
971 }
972
973 impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $type<MIN, MAX> {
974 #[inline(always)]
975 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
976 <Self as $crate::traits::RangeIsValid>::ASSERT;
977 self.get().fmt(f)
978 }
979 }
980
981 impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $optional_type<MIN, MAX> {
982 #[inline(always)]
983 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
985 self.get().fmt(f)
986 }
987 }
988
989 impl<const MIN: $internal, const MAX: $internal> fmt::Display for $type<MIN, MAX> {
990 #[inline(always)]
991 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992 <Self as $crate::traits::RangeIsValid>::ASSERT;
993 self.get().fmt(f)
994 }
995 }
996
997 #[cfg(feature = "powerfmt")]
998 impl<
999 const MIN: $internal,
1000 const MAX: $internal,
1001 > smart_display::SmartDisplay for $type<MIN, MAX> {
1002 type Metadata = <$internal as smart_display::SmartDisplay>::Metadata;
1003
1004 #[inline(always)]
1005 fn metadata(
1006 &self,
1007 f: smart_display::FormatterOptions,
1008 ) -> smart_display::Metadata<'_, Self> {
1009 <Self as $crate::traits::RangeIsValid>::ASSERT;
1010 self.get_ref().metadata(f).reuse()
1011 }
1012
1013 #[inline(always)]
1014 fn fmt_with_metadata(
1015 &self,
1016 f: &mut fmt::Formatter<'_>,
1017 metadata: smart_display::Metadata<'_, Self>,
1018 ) -> fmt::Result {
1019 <Self as $crate::traits::RangeIsValid>::ASSERT;
1020 self.get().fmt_with_metadata(f, metadata.reuse())
1021 }
1022 }
1023
1024 impl<const MIN: $internal, const MAX: $internal> Default for $optional_type<MIN, MAX> {
1025 #[inline(always)]
1026 fn default() -> Self {
1027 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1028 Self::None
1029 }
1030 }
1031
1032 impl<const MIN: $internal, const MAX: $internal> AsRef<$internal> for $type<MIN, MAX> {
1033 #[inline(always)]
1034 fn as_ref(&self) -> &$internal {
1035 <Self as $crate::traits::RangeIsValid>::ASSERT;
1036 &self.get_ref()
1037 }
1038 }
1039
1040 impl<const MIN: $internal, const MAX: $internal> Borrow<$internal> for $type<MIN, MAX> {
1041 #[inline(always)]
1042 fn borrow(&self) -> &$internal {
1043 <Self as $crate::traits::RangeIsValid>::ASSERT;
1044 &self.get_ref()
1045 }
1046 }
1047
1048 impl<
1049 const MIN_A: $internal,
1050 const MAX_A: $internal,
1051 const MIN_B: $internal,
1052 const MAX_B: $internal,
1053 > PartialEq<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1054 #[inline(always)]
1055 fn eq(&self, other: &$type<MIN_B, MAX_B>) -> bool {
1056 <Self as $crate::traits::RangeIsValid>::ASSERT;
1057 <$type<MIN_B, MAX_B> as $crate::traits::RangeIsValid>::ASSERT;
1058 self.get() == other.get()
1059 }
1060 }
1061
1062 impl<
1063 const MIN_A: $internal,
1064 const MAX_A: $internal,
1065 const MIN_B: $internal,
1066 const MAX_B: $internal,
1067 > PartialEq<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1068 #[inline(always)]
1069 fn eq(&self, other: &$optional_type<MIN_B, MAX_B>) -> bool {
1070 <$type<MIN_A, MAX_A> as $crate::traits::RangeIsValid>::ASSERT;
1071 <$type<MIN_B, MAX_B> as $crate::traits::RangeIsValid>::ASSERT;
1072 self.inner() == other.inner()
1073 }
1074 }
1075
1076 impl<
1077 const MIN_A: $internal,
1078 const MAX_A: $internal,
1079 const MIN_B: $internal,
1080 const MAX_B: $internal,
1081 > PartialOrd<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1082 #[inline(always)]
1083 fn partial_cmp(&self, other: &$type<MIN_B, MAX_B>) -> Option<Ordering> {
1084 <Self as $crate::traits::RangeIsValid>::ASSERT;
1085 <$type<MIN_B, MAX_B> as $crate::traits::RangeIsValid>::ASSERT;
1086 self.get().partial_cmp(&other.get())
1087 }
1088 }
1089
1090 impl<
1091 const MIN_A: $internal,
1092 const MAX_A: $internal,
1093 const MIN_B: $internal,
1094 const MAX_B: $internal,
1095 > PartialOrd<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1096 #[inline]
1097 fn partial_cmp(&self, other: &$optional_type<MIN_B, MAX_B>) -> Option<Ordering> {
1098 <$type<MIN_A, MAX_A> as $crate::traits::RangeIsValid>::ASSERT;
1099 <$type<MIN_B, MAX_B> as $crate::traits::RangeIsValid>::ASSERT;
1100 if self.is_none() && other.is_none() {
1101 Some(Ordering::Equal)
1102 } else if self.is_none() {
1103 Some(Ordering::Less)
1104 } else if other.is_none() {
1105 Some(Ordering::Greater)
1106 } else {
1107 self.inner().partial_cmp(&other.inner())
1108 }
1109 }
1110 }
1111
1112 impl<
1113 const MIN: $internal,
1114 const MAX: $internal,
1115 > Ord for $optional_type<MIN, MAX> {
1116 #[inline]
1117 fn cmp(&self, other: &Self) -> Ordering {
1118 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1119 if self.is_none() && other.is_none() {
1120 Ordering::Equal
1121 } else if self.is_none() {
1122 Ordering::Less
1123 } else if other.is_none() {
1124 Ordering::Greater
1125 } else {
1126 self.inner().cmp(&other.inner())
1127 }
1128 }
1129 }
1130
1131 impl<const MIN: $internal, const MAX: $internal> fmt::Binary for $type<MIN, MAX> {
1132 #[inline(always)]
1133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1134 <Self as $crate::traits::RangeIsValid>::ASSERT;
1135 self.get().fmt(f)
1136 }
1137 }
1138
1139 impl<const MIN: $internal, const MAX: $internal> fmt::LowerHex for $type<MIN, MAX> {
1140 #[inline(always)]
1141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1142 <Self as $crate::traits::RangeIsValid>::ASSERT;
1143 self.get().fmt(f)
1144 }
1145 }
1146
1147 impl<const MIN: $internal, const MAX: $internal> fmt::UpperHex for $type<MIN, MAX> {
1148 #[inline(always)]
1149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150 <Self as $crate::traits::RangeIsValid>::ASSERT;
1151 self.get().fmt(f)
1152 }
1153 }
1154
1155 impl<const MIN: $internal, const MAX: $internal> fmt::LowerExp for $type<MIN, MAX> {
1156 #[inline(always)]
1157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1158 <Self as $crate::traits::RangeIsValid>::ASSERT;
1159 self.get().fmt(f)
1160 }
1161 }
1162
1163 impl<const MIN: $internal, const MAX: $internal> fmt::UpperExp for $type<MIN, MAX> {
1164 #[inline(always)]
1165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1166 <Self as $crate::traits::RangeIsValid>::ASSERT;
1167 self.get().fmt(f)
1168 }
1169 }
1170
1171 impl<const MIN: $internal, const MAX: $internal> fmt::Octal for $type<MIN, MAX> {
1172 #[inline(always)]
1173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1174 <Self as $crate::traits::RangeIsValid>::ASSERT;
1175 self.get().fmt(f)
1176 }
1177 }
1178
1179 impl<const MIN: $internal, const MAX: $internal> From<$type<MIN, MAX>> for $internal {
1180 #[inline(always)]
1181 fn from(value: $type<MIN, MAX>) -> Self {
1182 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1183 value.get()
1184 }
1185 }
1186
1187 impl<
1188 const MIN: $internal,
1189 const MAX: $internal,
1190 > From<$type<MIN, MAX>> for $optional_type<MIN, MAX> {
1191 #[inline(always)]
1192 fn from(value: $type<MIN, MAX>) -> Self {
1193 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1194 Self::Some(value)
1195 }
1196 }
1197
1198 impl<
1199 const MIN: $internal,
1200 const MAX: $internal,
1201 > From<Option<$type<MIN, MAX>>> for $optional_type<MIN, MAX> {
1202 #[inline(always)]
1203 fn from(value: Option<$type<MIN, MAX>>) -> Self {
1204 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1205 match value {
1206 Some(value) => Self::Some(value),
1207 None => Self::None,
1208 }
1209 }
1210 }
1211
1212 impl<
1213 const MIN: $internal,
1214 const MAX: $internal,
1215 > From<$optional_type<MIN, MAX>> for Option<$type<MIN, MAX>> {
1216 #[inline(always)]
1217 fn from(value: $optional_type<MIN, MAX>) -> Self {
1218 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1219 value.get()
1220 }
1221 }
1222
1223 impl<const MIN: $internal, const MAX: $internal> TryFrom<$internal> for $type<MIN, MAX> {
1224 type Error = TryFromIntError;
1225
1226 #[inline]
1227 fn try_from(value: $internal) -> Result<Self, Self::Error> {
1228 <Self as $crate::traits::RangeIsValid>::ASSERT;
1229 Self::new(value).ok_or(TryFromIntError)
1230 }
1231 }
1232
1233 impl<const MIN: $internal, const MAX: $internal> FromStr for $type<MIN, MAX> {
1234 type Err = ParseIntError;
1235
1236 #[inline]
1237 fn from_str(s: &str) -> Result<Self, Self::Err> {
1238 <Self as $crate::traits::RangeIsValid>::ASSERT;
1239 let value = s.parse::<$internal>().map_err(|e| ParseIntError {
1240 kind: e.kind().clone()
1241 })?;
1242 if value < MIN {
1243 Err(ParseIntError { kind: IntErrorKind::NegOverflow })
1244 } else if value > MAX {
1245 Err(ParseIntError { kind: IntErrorKind::PosOverflow })
1246 } else {
1247 Ok(unsafe { Self::new_unchecked(value) })
1249 }
1250 }
1251 }
1252
1253 #[cfg(feature = "serde")]
1254 impl<const MIN: $internal, const MAX: $internal> serde::Serialize for $type<MIN, MAX> {
1255 #[inline(always)]
1256 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1257 <Self as $crate::traits::RangeIsValid>::ASSERT;
1258 self.get().serialize(serializer)
1259 }
1260 }
1261
1262 #[cfg(feature = "serde")]
1263 impl<
1264 const MIN: $internal,
1265 const MAX: $internal,
1266 > serde::Serialize for $optional_type<MIN, MAX> {
1267 #[inline(always)]
1268 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1269 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1270 self.get().serialize(serializer)
1271 }
1272 }
1273
1274 #[cfg(feature = "serde")]
1275 impl<
1276 'de,
1277 const MIN: $internal,
1278 const MAX: $internal,
1279 > serde::Deserialize<'de> for $type<MIN, MAX> {
1280 #[inline]
1281 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1282 <Self as $crate::traits::RangeIsValid>::ASSERT;
1283 let internal = <$internal>::deserialize(deserializer)?;
1284 Self::new(internal).ok_or_else(|| <D::Error as serde::de::Error>::invalid_value(
1285 serde::de::Unexpected::Other("integer"),
1286 #[cfg(feature = "std")] {
1287 &format!("an integer in the range {}..={}", MIN, MAX).as_ref()
1288 },
1289 #[cfg(not(feature = "std"))] {
1290 &"an integer in the valid range"
1291 }
1292 ))
1293 }
1294 }
1295
1296 #[cfg(feature = "serde")]
1297 impl<
1298 'de,
1299 const MIN: $internal,
1300 const MAX: $internal,
1301 > serde::Deserialize<'de> for $optional_type<MIN, MAX> {
1302 #[inline]
1303 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1304 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1305 Ok(Self::Some($type::<MIN, MAX>::deserialize(deserializer)?))
1306 }
1307 }
1308
1309 #[cfg(feature = "rand")]
1310 impl<
1311 const MIN: $internal,
1312 const MAX: $internal,
1313 > rand::distributions::Distribution<$type<MIN, MAX>> for rand::distributions::Standard {
1314 #[inline]
1315 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1316 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1317 $type::new(rng.gen_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1318 }
1319 }
1320
1321 #[cfg(feature = "rand")]
1322 impl<
1323 const MIN: $internal,
1324 const MAX: $internal,
1325 > rand::distributions::Distribution<$optional_type<MIN, MAX>>
1326 for rand::distributions::Standard {
1327 #[inline]
1328 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1329 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1330 rng.gen::<Option<$type<MIN, MAX>>>().into()
1331 }
1332 }
1333
1334 #[cfg(feature = "num")]
1335 impl<const MIN: $internal, const MAX: $internal> num_traits::Bounded for $type<MIN, MAX> {
1336 #[inline(always)]
1337 fn min_value() -> Self {
1338 <Self as $crate::traits::RangeIsValid>::ASSERT;
1339 Self::MIN
1340 }
1341
1342 #[inline(always)]
1343 fn max_value() -> Self {
1344 <Self as $crate::traits::RangeIsValid>::ASSERT;
1345 Self::MAX
1346 }
1347 }
1348
1349 #[cfg(feature = "quickcheck")]
1350 impl<const MIN: $internal, const MAX: $internal> quickcheck::Arbitrary for $type<MIN, MAX> {
1351 #[inline]
1352 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1353 <Self as $crate::traits::RangeIsValid>::ASSERT;
1354 unsafe {
1356 Self::new_unchecked($internal::arbitrary(g).rem_euclid(MAX - MIN + 1) + MIN)
1357 }
1358 }
1359
1360 #[inline]
1361 fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1362 ::alloc::boxed::Box::new(
1363 self.get()
1364 .shrink()
1365 .filter_map(Self::new)
1366 )
1367 }
1368 }
1369
1370 #[cfg(feature = "quickcheck")]
1371 impl<
1372 const MIN: $internal,
1373 const MAX: $internal,
1374 > quickcheck::Arbitrary for $optional_type<MIN, MAX> {
1375 #[inline]
1376 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1377 <$type<MIN, MAX> as $crate::traits::RangeIsValid>::ASSERT;
1378 Option::<$type<MIN, MAX>>::arbitrary(g).into()
1379 }
1380
1381 #[inline]
1382 fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1383 ::alloc::boxed::Box::new(self.get().shrink().map(Self::from))
1384 }
1385 }
1386 )*};
1387}
1388
1389impl_ranged! {
1390 RangedU8 {
1391 mod_name: ranged_u8
1392 internal: u8
1393 signed: false
1394 unsigned: u8
1395 optional: OptionRangedU8
1396 }
1397 RangedU16 {
1398 mod_name: ranged_u16
1399 internal: u16
1400 signed: false
1401 unsigned: u16
1402 optional: OptionRangedU16
1403 }
1404 RangedU32 {
1405 mod_name: ranged_u32
1406 internal: u32
1407 signed: false
1408 unsigned: u32
1409 optional: OptionRangedU32
1410 }
1411 RangedU64 {
1412 mod_name: ranged_u64
1413 internal: u64
1414 signed: false
1415 unsigned: u64
1416 optional: OptionRangedU64
1417 }
1418 RangedU128 {
1419 mod_name: ranged_u128
1420 internal: u128
1421 signed: false
1422 unsigned: u128
1423 optional: OptionRangedU128
1424 }
1425 RangedUsize {
1426 mod_name: ranged_usize
1427 internal: usize
1428 signed: false
1429 unsigned: usize
1430 optional: OptionRangedUsize
1431 }
1432 RangedI8 {
1433 mod_name: ranged_i8
1434 internal: i8
1435 signed: true
1436 unsigned: u8
1437 optional: OptionRangedI8
1438 }
1439 RangedI16 {
1440 mod_name: ranged_i16
1441 internal: i16
1442 signed: true
1443 unsigned: u16
1444 optional: OptionRangedI16
1445 }
1446 RangedI32 {
1447 mod_name: ranged_i32
1448 internal: i32
1449 signed: true
1450 unsigned: u32
1451 optional: OptionRangedI32
1452 }
1453 RangedI64 {
1454 mod_name: ranged_i64
1455 internal: i64
1456 signed: true
1457 unsigned: u64
1458 optional: OptionRangedI64
1459 }
1460 RangedI128 {
1461 mod_name: ranged_i128
1462 internal: i128
1463 signed: true
1464 unsigned: u128
1465 optional: OptionRangedI128
1466 }
1467 RangedIsize {
1468 mod_name: ranged_isize
1469 internal: isize
1470 signed: true
1471 unsigned: usize
1472 optional: OptionRangedIsize
1473 }
1474}