1#![cfg_attr(docsrs, feature(doc_cfg))]
4#![no_std]
5#![doc(test(attr(deny(warnings))))]
6
7#[cfg(all(feature = "alloc", any(feature = "serde", feature = "quickcheck")))]
8extern crate alloc;
9
10#[cfg(test)]
11mod tests;
12mod unsafe_wrapper;
13
14use core::borrow::Borrow;
15use core::cmp::Ordering;
16use core::error::Error;
17use core::fmt;
18use core::hint::assert_unchecked;
19use core::num::{IntErrorKind, NonZero};
20use core::str::FromStr;
21
22#[cfg(docsrs)]
39#[doc(cfg(feature = "macros"))]
40#[macro_export]
41macro_rules! int {
42 ($min:literal, $max:literal) => {};
43}
44
45#[cfg(docsrs)]
62#[doc(cfg(feature = "macros"))]
63#[macro_export]
64macro_rules! opt_int {
65 ($min:literal, $max:literal) => {};
66}
67
68#[cfg(all(not(docsrs), feature = "macros"))]
69pub use deranged_macros::int;
70#[cfg(all(not(docsrs), feature = "macros"))]
71pub use deranged_macros::opt_int;
72#[cfg(feature = "powerfmt")]
73use powerfmt::smart_display;
74
75use crate::unsafe_wrapper::Unsafe;
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub struct TryFromIntError;
80
81impl fmt::Display for TryFromIntError {
82 #[inline]
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 f.write_str("out of range integral type conversion attempted")
85 }
86}
87impl Error for TryFromIntError {}
88
89#[allow(missing_copy_implementations)] #[derive(Debug, Clone, PartialEq, Eq)]
110pub struct ParseIntError {
111 #[allow(clippy::missing_docs_in_private_items)]
112 kind: IntErrorKind,
113}
114
115impl ParseIntError {
116 #[allow(clippy::missing_const_for_fn)]
119 #[inline(always)]
120 pub fn kind(&self) -> &IntErrorKind {
121 &self.kind
122 }
123}
124
125impl fmt::Display for ParseIntError {
126 #[inline]
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 match self.kind {
129 IntErrorKind::Empty => "cannot parse integer from empty string",
130 IntErrorKind::InvalidDigit => "invalid digit found in string",
131 IntErrorKind::PosOverflow => "number too large to fit in target type",
132 IntErrorKind::NegOverflow => "number too small to fit in target type",
133 IntErrorKind::Zero => "number would be zero for non-zero type",
134 _ => "Unknown Int error kind",
135 }
136 .fmt(f)
137 }
138}
139
140impl Error for ParseIntError {}
141
142macro_rules! const_try_opt {
144 ($e:expr) => {
145 match $e {
146 Some(value) => value,
147 None => return None,
148 }
149 };
150}
151
152macro_rules! if_signed {
154 (true $($x:tt)*) => { $($x)*};
155 (false $($x:tt)*) => {};
156}
157
158macro_rules! if_unsigned {
160 (true $($x:tt)*) => {};
161 (false $($x:tt)*) => { $($x)* };
162}
163
164macro_rules! article {
166 (true) => {
167 "An"
168 };
169 (false) => {
170 "A"
171 };
172}
173
174#[allow(unused_macro_rules)]
176macro_rules! if_not_manual_rand_09 {
177 ([rand_09 $($rest:ident)*] $($output:tt)*) => {};
178 ([] $($output:tt)*) => {
179 $($output)*
180 };
181 ([$first:ident $($rest:ident)*] $($output:tt)*) => {
182 if_not_manual_rand_09!([$($rest)*] $($output)*);
183 };
184}
185
186#[allow(unused_macro_rules)]
188macro_rules! if_not_manual_rand_010 {
189 ([rand_010 $($rest:ident)*] $($output:tt)*) => {};
190 ([] $($output:tt)*) => {
191 $($output)*
192 };
193 ([$first:ident $($rest:ident)*] $($output:tt)*) => {
194 if_not_manual_rand_010!([$($rest)*] $($output)*);
195 };
196}
197
198macro_rules! impl_ranged {
200 ($(
201 $type:ident {
202 mod_name: $mod_name:ident
203 alias: $alias:ident
204 internal: $internal:ident
205 signed: $is_signed:ident
206 unsigned: $unsigned_type:ident
207 optional: $optional_type:ident
208 optional_alias: $optional_alias:ident
209 from: [$($from:ident($from_internal:ident))+]
210 $(manual: [$($skips:ident)+])?
211 }
212 )*) => {$(
213 #[doc = concat!("Equivalent to `", stringify!($type), "`")]
214 #[expect(non_camel_case_types, reason = "symmetry with primitives")]
215 pub type $alias<const MIN: $internal, const MAX: $internal> = $type<MIN, MAX>;
216
217 #[doc = concat!("Equivalent to `", stringify!($optional_type), "`")]
218 #[expect(non_camel_case_types, reason = "closest visually to `Option<T>`")]
219 pub type $optional_alias<const MIN: $internal, const MAX: $internal>
220 = $optional_type<MIN, MAX>;
221
222 #[doc = concat!(
223 article!($is_signed),
224 " `",
225 stringify!($internal),
226 "` that is known to be in the range `MIN..=MAX`.",
227 )]
228 #[repr(transparent)]
229 #[derive(Clone, Copy, Eq, Ord, Hash)]
230 pub struct $type<const MIN: $internal, const MAX: $internal>(
231 Unsafe<$internal>,
232 );
233
234 #[doc = concat!(
235 "An optional `",
236 stringify!($type),
237 "`; similar to `Option<",
238 stringify!($type),
239 ">` with better optimization.",
240 )]
241 #[doc = concat!(
243 "If `MIN` is [`",
244 stringify!($internal),
245 "::MIN`] _and_ `MAX` is [`",
246 stringify!($internal)
247 ,"::MAX`] then compilation will fail. This is because there is no way to represent \
248 the niche value.",
249 )]
250 #[doc = concat!("obtained with [`", stringify!($optional_type), "::get`].")]
256 #[repr(transparent)]
257 #[derive(Clone, Copy, Eq, Hash)]
258 pub struct $optional_type<const MIN: $internal, const MAX: $internal>(
259 $internal,
260 );
261
262 impl $type<0, 0> {
263 #[doc = concat!("A ", stringify!($type), " that is always `VALUE`.")]
264 #[inline(always)]
265 pub const fn exact<const VALUE: $internal>() -> $type<VALUE, VALUE> {
266 unsafe { $type::new_unchecked(VALUE) }
268 }
269 }
270
271 if_unsigned! { $is_signed
272 impl $type<1, { $internal::MAX }> {
273 #[inline(always)]
275 pub const fn from_nonzero(value: NonZero<$internal>) -> Self {
276 unsafe { Self::new_unchecked(value.get()) }
278 }
279
280 #[inline(always)]
282 pub const fn to_nonzero(self) -> NonZero<$internal> {
283 unsafe { NonZero::new_unchecked(self.get()) }
285 }
286 }}
287
288 impl<const MIN: $internal, const MAX: $internal> $type<MIN, MAX> {
289 pub const MIN: Self = Self::new_static::<MIN>();
292
293 pub const MAX: Self = Self::new_static::<MAX>();
296
297 #[track_caller]
303 #[inline(always)]
304 pub const unsafe fn new_unchecked(value: $internal) -> Self {
305 const { assert!(MIN <= MAX); }
306 unsafe {
308 assert_unchecked(MIN <= value && value <= MAX);
309 Self(Unsafe::new(value))
310 }
311 }
312
313 #[doc = concat!("use [`", stringify!($type), "::get_without_hint`].")]
319 #[track_caller]
320 #[inline(always)]
321 pub const fn get(self) -> $internal {
322 const { assert!(MIN <= MAX); }
323 unsafe { assert_unchecked(MIN <= *self.0.get() && *self.0.get() <= MAX) };
325 *self.0.get()
326 }
327
328 #[doc = concat!("The returned value is identical to [`", stringify!($type), "::get`].")]
331 #[inline(always)]
335 pub const fn get_without_hint(self) -> $internal {
336 const { assert!(MIN <= MAX); }
337 *self.0.get()
338 }
339
340 #[track_caller]
341 #[inline(always)]
342 pub(crate) const fn get_ref(&self) -> &$internal {
343 const { assert!(MIN <= MAX); }
344 let value = self.0.get();
345 unsafe { assert_unchecked(MIN <= *value && *value <= MAX) };
347 value
348 }
349
350 #[inline(always)]
352 pub const fn new(value: $internal) -> Option<Self> {
353 const { assert!(MIN <= MAX); }
354 if value < MIN || value > MAX {
355 None
356 } else {
357 Some(unsafe { Self::new_unchecked(value) })
359 }
360 }
361
362 #[inline(always)]
365 pub const fn new_static<const VALUE: $internal>() -> Self {
366 const {
367 assert!(MIN <= VALUE);
368 assert!(VALUE <= MAX);
369 }
370 unsafe { Self::new_unchecked(VALUE) }
372 }
373
374 #[inline]
376 pub const fn new_saturating(value: $internal) -> Self {
377 const { assert!(MIN <= MAX); }
378 if value < MIN {
379 Self::MIN
380 } else if value > MAX {
381 Self::MAX
382 } else {
383 unsafe { Self::new_unchecked(value) }
385 }
386 }
387
388 #[inline(always)]
399 pub const fn emit_range_hint(self) {
400 const { assert!(MIN <= MAX); }
401 let value = self.0.get();
402 unsafe { assert_unchecked(MIN <= *value && *value <= MAX) };
404 }
405
406 #[inline(always)]
409 pub const fn expand<const NEW_MIN: $internal, const NEW_MAX: $internal>(
410 self,
411 ) -> $type<NEW_MIN, NEW_MAX> {
412 const {
413 assert!(MIN <= MAX);
414 assert!(NEW_MIN <= NEW_MAX);
415 assert!(NEW_MIN <= MIN);
416 assert!(NEW_MAX >= MAX);
417 }
418 unsafe { $type::new_unchecked(self.get()) }
420 }
421
422 #[inline(always)]
426 pub const fn narrow<
427 const NEW_MIN: $internal,
428 const NEW_MAX: $internal,
429 >(self) -> Option<$type<NEW_MIN, NEW_MAX>> {
430 const {
431 assert!(MIN <= MAX);
432 assert!(NEW_MIN <= NEW_MAX);
433 assert!(NEW_MIN >= MIN);
434 assert!(NEW_MAX <= MAX);
435 }
436 $type::<NEW_MIN, NEW_MAX>::new(self.get())
437 }
438
439 #[inline(always)]
446 pub const unsafe fn narrow_unchecked<
447 const NEW_MIN: $internal,
448 const NEW_MAX: $internal,
449 >(self) -> $type<NEW_MIN, NEW_MAX> {
450 const {
451 assert!(MIN <= MAX);
452 assert!(NEW_MIN <= NEW_MAX);
453 assert!(NEW_MIN >= MIN);
454 assert!(NEW_MAX <= MAX);
455 }
456 unsafe { $type::new_unchecked(self.get()) }
458 }
459
460 #[doc = concat!("# use deranged::", stringify!($type), ";")]
480 #[doc = concat!(
481 "assert_eq!(",
482 stringify!($type),
483 "::<5, 10>::from_str_radix(\"A\", 16), Ok(",
484 stringify!($type),
485 "::new_static::<10>()));",
486 )]
487 #[inline]
489 pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
490 const { assert!(MIN <= MAX); }
491 match $internal::from_str_radix(src, radix) {
492 Ok(value) if value > MAX => {
493 Err(ParseIntError { kind: IntErrorKind::PosOverflow })
494 }
495 Ok(value) if value < MIN => {
496 Err(ParseIntError { kind: IntErrorKind::NegOverflow })
497 }
498 Ok(value) => Ok(unsafe { Self::new_unchecked(value) }),
501 Err(e) => Err(ParseIntError { kind: e.kind().clone() }),
502 }
503 }
504
505 #[must_use = "this returns the result of the operation, without modifying the original"]
508 #[inline]
509 pub const fn checked_add(self, rhs: $internal) -> Option<Self> {
510 const { assert!(MIN <= MAX); }
511 Self::new(const_try_opt!(self.get().checked_add(rhs)))
512 }
513
514 #[must_use = "this returns the result of the operation, without modifying the original"]
521 #[track_caller]
522 #[inline(always)]
523 pub const unsafe fn unchecked_add(self, rhs: $internal) -> Self {
524 const { assert!(MIN <= MAX); }
525 unsafe {
527 Self::new_unchecked(self.get().unchecked_add(rhs))
528 }
529 }
530
531 #[must_use = "this returns the result of the operation, without modifying the original"]
534 #[inline]
535 pub const fn checked_sub(self, rhs: $internal) -> Option<Self> {
536 const { assert!(MIN <= MAX); }
537 Self::new(const_try_opt!(self.get().checked_sub(rhs)))
538 }
539
540 #[must_use = "this returns the result of the operation, without modifying the original"]
547 #[track_caller]
548 #[inline(always)]
549 pub const unsafe fn unchecked_sub(self, rhs: $internal) -> Self {
550 const { assert!(MIN <= MAX); }
551 unsafe {
553 Self::new_unchecked(self.get().unchecked_sub(rhs))
554 }
555 }
556
557 #[must_use = "this returns the result of the operation, without modifying the original"]
560 #[inline]
561 pub const fn checked_mul(self, rhs: $internal) -> Option<Self> {
562 const { assert!(MIN <= MAX); }
563 Self::new(const_try_opt!(self.get().checked_mul(rhs)))
564 }
565
566 #[must_use = "this returns the result of the operation, without modifying the original"]
573 #[track_caller]
574 #[inline(always)]
575 pub const unsafe fn unchecked_mul(self, rhs: $internal) -> Self {
576 const { assert!(MIN <= MAX); }
577 unsafe {
579 Self::new_unchecked(self.get().unchecked_mul(rhs))
580 }
581 }
582
583 #[must_use = "this returns the result of the operation, without modifying the original"]
586 #[inline]
587 pub const fn checked_div(self, rhs: $internal) -> Option<Self> {
588 const { assert!(MIN <= MAX); }
589 Self::new(const_try_opt!(self.get().checked_div(rhs)))
590 }
591
592 #[must_use = "this returns the result of the operation, without modifying the original"]
600 #[track_caller]
601 #[inline(always)]
602 pub const unsafe fn unchecked_div(self, rhs: $internal) -> Self {
603 const { assert!(MIN <= MAX); }
604 unsafe {
607 Self::new_unchecked(self.get().checked_div(rhs).unwrap_unchecked())
608 }
609 }
610
611 #[must_use = "this returns the result of the operation, without modifying the original"]
614 #[inline]
615 pub const fn checked_div_euclid(self, rhs: $internal) -> Option<Self> {
616 const { assert!(MIN <= MAX); }
617 Self::new(const_try_opt!(self.get().checked_div_euclid(rhs)))
618 }
619
620 #[must_use = "this returns the result of the operation, without modifying the original"]
628 #[track_caller]
629 #[inline(always)]
630 pub const unsafe fn unchecked_div_euclid(self, rhs: $internal) -> Self {
631 const { assert!(MIN <= MAX); }
632 unsafe {
635 Self::new_unchecked(
636 self.get().checked_div_euclid(rhs).unwrap_unchecked()
637 )
638 }
639 }
640
641 if_unsigned!($is_signed
642 #[must_use = "this returns the result of the operation, without modifying the original"]
645 #[track_caller]
646 #[inline]
647 pub const fn rem<const RHS_VALUE: $internal>(
648 self,
649 rhs: $type<RHS_VALUE, RHS_VALUE>,
650 ) -> $type<0, RHS_VALUE> {
651 const { assert!(MIN <= MAX); }
652 unsafe { $type::new_unchecked(self.get() % rhs.get()) }
655 });
656
657 #[must_use = "this returns the result of the operation, without modifying the original"]
660 #[inline]
661 pub const fn checked_rem(self, rhs: $internal) -> Option<Self> {
662 const { assert!(MIN <= MAX); }
663 Self::new(const_try_opt!(self.get().checked_rem(rhs)))
664 }
665
666 #[must_use = "this returns the result of the operation, without modifying the original"]
674 #[track_caller]
675 #[inline(always)]
676 pub const unsafe fn unchecked_rem(self, rhs: $internal) -> Self {
677 const { assert!(MIN <= MAX); }
678 unsafe {
681 Self::new_unchecked(self.get().checked_rem(rhs).unwrap_unchecked())
682 }
683 }
684
685 #[must_use = "this returns the result of the operation, without modifying the original"]
688 #[inline]
689 pub const fn checked_rem_euclid(self, rhs: $internal) -> Option<Self> {
690 const { assert!(MIN <= MAX); }
691 Self::new(const_try_opt!(self.get().checked_rem_euclid(rhs)))
692 }
693
694 #[must_use = "this returns the result of the operation, without modifying the original"]
702 #[track_caller]
703 #[inline(always)]
704 pub const unsafe fn unchecked_rem_euclid(self, rhs: $internal) -> Self {
705 const { assert!(MIN <= MAX); }
706 unsafe {
709 Self::new_unchecked(
710 self.get().checked_rem_euclid(rhs).unwrap_unchecked()
711 )
712 }
713 }
714
715 #[must_use = "this returns the result of the operation, without modifying the original"]
718 #[inline]
719 pub const fn checked_neg(self) -> Option<Self> {
720 const { assert!(MIN <= MAX); }
721 Self::new(const_try_opt!(self.get().checked_neg()))
722 }
723
724 #[must_use = "this returns the result of the operation, without modifying the original"]
730 #[track_caller]
731 #[inline(always)]
732 pub const unsafe fn unchecked_neg(self) -> Self {
733 const { assert!(MIN <= MAX); }
734 unsafe { Self::new_unchecked(self.get().checked_neg().unwrap_unchecked()) }
737 }
738
739 #[must_use = "this returns the result of the operation, without modifying the original"]
742 #[inline(always)]
743 pub const fn neg(self) -> Self {
744 const {
745 assert!(MIN <= MAX);
746 if_signed! { $is_signed
747 assert!(MIN != $internal::MIN);
748 assert!(-MIN <= MAX);
749 assert!(-MAX >= MIN);
750 }
751 if_unsigned! { $is_signed
752 assert!(MAX == 0);
753 }
754 }
755 unsafe { self.unchecked_neg() }
757 }
758
759 #[must_use = "this returns the result of the operation, without modifying the original"]
762 #[inline]
763 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
764 const { assert!(MIN <= MAX); }
765 Self::new(const_try_opt!(self.get().checked_shl(rhs)))
766 }
767
768 #[must_use = "this returns the result of the operation, without modifying the original"]
775 #[track_caller]
776 #[inline(always)]
777 pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
778 const { assert!(MIN <= MAX); }
779 unsafe {
782 Self::new_unchecked(self.get().checked_shl(rhs).unwrap_unchecked())
784 }
785 }
786
787 #[must_use = "this returns the result of the operation, without modifying the original"]
790 #[inline]
791 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
792 const { assert!(MIN <= MAX); }
793 Self::new(const_try_opt!(self.get().checked_shr(rhs)))
794 }
795
796 #[must_use = "this returns the result of the operation, without modifying the original"]
803 #[track_caller]
804 #[inline(always)]
805 pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
806 const { assert!(MIN <= MAX); }
807 unsafe {
810 Self::new_unchecked(self.get().checked_shr(rhs).unwrap_unchecked())
812 }
813 }
814
815 if_signed!($is_signed
816 #[must_use = "this returns the result of the operation, without modifying the original"]
819 #[inline]
820 pub const fn checked_abs(self) -> Option<Self> {
821 const { assert!(MIN <= MAX); }
822 Self::new(const_try_opt!(self.get().checked_abs()))
823 }
824
825 #[must_use = "this returns the result of the operation, without modifying the original"]
832 #[track_caller]
833 #[inline(always)]
834 pub const unsafe fn unchecked_abs(self) -> Self {
835 const { assert!(MIN <= MAX); }
836 unsafe { Self::new_unchecked(self.get().checked_abs().unwrap_unchecked()) }
838 }
839
840 #[must_use = "this returns the result of the operation, without modifying the original"]
843 #[inline(always)]
844 pub const fn abs(self) -> Self {
845 const {
846 assert!(MIN <= MAX);
847 assert!(MIN != $internal::MIN);
848 assert!(-MIN <= MAX);
849 }
850 unsafe { self.unchecked_abs() }
853 });
854
855 #[must_use = "this returns the result of the operation, without modifying the original"]
858 #[inline]
859 pub const fn checked_pow(self, exp: u32) -> Option<Self> {
860 const { assert!(MIN <= MAX); }
861 Self::new(const_try_opt!(self.get().checked_pow(exp)))
862 }
863
864 #[must_use = "this returns the result of the operation, without modifying the original"]
871 #[track_caller]
872 #[inline(always)]
873 pub const unsafe fn unchecked_pow(self, exp: u32) -> Self {
874 const { assert!(MIN <= MAX); }
875 unsafe {
877 Self::new_unchecked(self.get().checked_pow(exp).unwrap_unchecked())
878 }
879 }
880
881 #[must_use = "this returns the result of the operation, without modifying the original"]
884 #[inline]
885 pub const fn saturating_add(self, rhs: $internal) -> Self {
886 const { assert!(MIN <= MAX); }
887 Self::new_saturating(self.get().saturating_add(rhs))
888 }
889
890 #[must_use = "this returns the result of the operation, without modifying the original"]
893 #[inline]
894 pub const fn saturating_sub(self, rhs: $internal) -> Self {
895 const { assert!(MIN <= MAX); }
896 Self::new_saturating(self.get().saturating_sub(rhs))
897 }
898
899 if_signed!($is_signed
900 #[must_use = "this returns the result of the operation, without modifying the original"]
903 #[inline]
904 pub const fn saturating_neg(self) -> Self {
905 const { assert!(MIN <= MAX); }
906 Self::new_saturating(self.get().saturating_neg())
907 });
908
909 if_signed!($is_signed
910 #[must_use = "this returns the result of the operation, without modifying the original"]
912 #[inline]
913 pub const fn saturating_abs(self) -> Self {
914 const { assert!(MIN <= MAX); }
915 Self::new_saturating(self.get().saturating_abs())
916 });
917
918 #[must_use = "this returns the result of the operation, without modifying the original"]
921 #[inline]
922 pub const fn saturating_mul(self, rhs: $internal) -> Self {
923 const { assert!(MIN <= MAX); }
924 Self::new_saturating(self.get().saturating_mul(rhs))
925 }
926
927 #[must_use = "this returns the result of the operation, without modifying the original"]
930 #[inline]
931 pub const fn saturating_pow(self, exp: u32) -> Self {
932 const { assert!(MIN <= MAX); }
933 Self::new_saturating(self.get().saturating_pow(exp))
934 }
935
936 if_signed! { $is_signed
937 #[inline]
940 pub const fn is_positive(self) -> bool {
941 const { assert!(MIN <= MAX); }
942 self.get().is_positive()
943 }
944
945 #[inline]
948 pub const fn is_negative(self) -> bool {
949 const { assert!(MIN <= MAX); }
950 self.get().is_negative()
951 }
952 }
953
954 #[must_use = "this returns the result of the operation, without modifying the original"]
958 #[track_caller]
959 #[inline]
960 #[allow(trivial_numeric_casts)] const fn rem_euclid_unsigned(
962 rhs: $internal,
963 range_len: $unsigned_type
964 ) -> $unsigned_type {
965 #[allow(unused_comparisons)]
966 if rhs >= 0 {
967 (rhs as $unsigned_type) % range_len
968 } else {
969 let rhs_abs = ($internal::wrapping_sub(0, rhs)) as $unsigned_type;
973 ((($unsigned_type::MAX / range_len) * range_len) - (rhs_abs)) % range_len
980 }
981 }
982
983 #[must_use = "this returns the result of the operation, without modifying the original"]
986 #[inline]
987 #[allow(trivial_numeric_casts)] pub const fn wrapping_add(self, rhs: $internal) -> Self {
989 const { assert!(MIN <= MAX); }
990 if MIN == $internal::MIN && MAX == $internal::MAX {
992 return unsafe { Self::new_unchecked(self.get().wrapping_add(rhs)) }
994 }
995
996 let inner = self.get();
997
998 let range_len = MAX.abs_diff(MIN) + 1;
1000
1001 let offset = Self::rem_euclid_unsigned(rhs, range_len);
1003
1004 let greater_vals = MAX.abs_diff(inner);
1005 if offset <= greater_vals {
1007 unsafe { Self::new_unchecked(
1015 ((inner as $unsigned_type).wrapping_add(offset)) as $internal
1016 ) }
1017 }
1018 else {
1020 unsafe { Self::new_unchecked(
1026 ((MIN as $unsigned_type).wrapping_add(
1027 offset - (greater_vals + 1)
1028 )) as $internal
1029 ) }
1030 }
1031 }
1032
1033 #[must_use = "this returns the result of the operation, without modifying the original"]
1036 #[inline]
1037 #[allow(trivial_numeric_casts)] pub const fn wrapping_sub(self, rhs: $internal) -> Self {
1039 const { assert!(MIN <= MAX); }
1040 if MIN == $internal::MIN && MAX == $internal::MAX {
1042 return unsafe { Self::new_unchecked(self.get().wrapping_sub(rhs)) }
1044 }
1045
1046 let inner = self.get();
1047
1048 let range_len = MAX.abs_diff(MIN) + 1;
1050
1051 let offset = Self::rem_euclid_unsigned(rhs, range_len);
1053
1054 let lesser_vals = MIN.abs_diff(inner);
1055 if offset <= lesser_vals {
1057 unsafe { Self::new_unchecked(
1065 ((inner as $unsigned_type).wrapping_sub(offset)) as $internal
1066 ) }
1067 }
1068 else {
1070 unsafe { Self::new_unchecked(
1076 ((MAX as $unsigned_type).wrapping_sub(
1077 offset - (lesser_vals + 1)
1078 )) as $internal
1079 ) }
1080 }
1081 }
1082
1083 #[must_use = "this returns the result of the operation, without modifying the original"]
1088 #[inline]
1089 pub const fn overflowing_add(self, rhs: $internal) -> (Self, bool) {
1090 const { assert!(MIN <= MAX); }
1091
1092 if MIN == $internal::MIN && MAX == $internal::MAX {
1094 let (res, overflow) = self.get().overflowing_add(rhs);
1095
1096 return (unsafe { Self::new_unchecked(res) }, overflow)
1098 }
1099
1100 if let Some(res) = self.checked_add(rhs) {
1101 (res, false)
1102 } else {
1103 (self.wrapping_add(rhs), true)
1104 }
1105 }
1106
1107 #[must_use = "this returns the result of the operation, without modifying the original"]
1112 #[inline]
1113 pub const fn overflowing_sub(self, rhs: $internal) -> (Self, bool) {
1114 const { assert!(MIN <= MAX); }
1115
1116 if MIN == $internal::MIN && MAX == $internal::MAX {
1118 let (res, overflow) = self.get().overflowing_sub(rhs);
1119
1120 return (unsafe { Self::new_unchecked(res) }, overflow)
1122 }
1123
1124 if let Some(res) = self.checked_sub(rhs) {
1125 (res, false)
1126 } else {
1127 (self.wrapping_sub(rhs), true)
1128 }
1129 }
1130 }
1131
1132 impl<const MIN: $internal, const MAX: $internal> $optional_type<MIN, MAX> {
1133 const NICHE: $internal = match (MIN, MAX) {
1135 ($internal::MIN, $internal::MAX) => panic!("type has no niche"),
1136 ($internal::MIN, _) => $internal::MAX,
1137 (_, _) => $internal::MIN,
1138 };
1139
1140 #[allow(non_upper_case_globals)]
1142 pub const None: Self = Self(Self::NICHE);
1143
1144 #[allow(non_snake_case)]
1146 #[inline(always)]
1147 pub const fn Some(value: $type<MIN, MAX>) -> Self {
1148 const { assert!(MIN <= MAX); }
1149 Self(value.get())
1150 }
1151
1152 #[inline(always)]
1154 pub const fn get(self) -> Option<$type<MIN, MAX>> {
1155 const { assert!(MIN <= MAX); }
1156 if self.0 == Self::NICHE {
1157 None
1158 } else {
1159 Some(unsafe { $type::new_unchecked(self.0) })
1161 }
1162 }
1163
1164 #[inline(always)]
1172 #[track_caller]
1173 pub const unsafe fn some_unchecked(value: $internal) -> Self {
1174 const { assert!(MIN <= MAX); }
1175 unsafe { assert_unchecked(MIN <= value && value <= MAX) };
1177 Self(value)
1178 }
1179
1180 #[inline(always)]
1182 pub(crate) const fn inner(self) -> $internal {
1183 const { assert!(MIN <= MAX); }
1184 self.0
1185 }
1186
1187 #[doc = concat!(
1193 "use [`", stringify!($optional_type), "::get_primitive_without_hint`]."
1194 )]
1195 #[inline(always)]
1196 pub const fn get_primitive(self) -> Option<$internal> {
1197 const { assert!(MIN <= MAX); }
1198 Some(const_try_opt!(self.get()).get())
1199 }
1200
1201 #[doc = concat!(
1204 "The returned value is identical to [`", stringify!($optional_type), "::",
1205 "get_primitive`]."
1206 )]
1207 #[inline(always)]
1211 pub const fn get_primitive_without_hint(self) -> Option<$internal> {
1212 const { assert!(MIN <= MAX); }
1213 Some(const_try_opt!(self.get()).get_without_hint())
1214 }
1215
1216 #[inline(always)]
1218 pub const fn is_none(&self) -> bool {
1219 const { assert!(MIN <= MAX); }
1220 self.get().is_none()
1221 }
1222
1223 #[inline(always)]
1225 pub const fn is_some(&self) -> bool {
1226 const { assert!(MIN <= MAX); }
1227 self.get().is_some()
1228 }
1229 }
1230
1231 impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $type<MIN, MAX> {
1232 #[inline(always)]
1233 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1234 const { assert!(MIN <= MAX); }
1235 self.get().fmt(f)
1236 }
1237 }
1238
1239 impl<const MIN: $internal, const MAX: $internal> fmt::Debug for $optional_type<MIN, MAX> {
1240 #[inline(always)]
1241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1242 const { assert!(MIN <= MAX); }
1243 self.get().fmt(f)
1244 }
1245 }
1246
1247 impl<const MIN: $internal, const MAX: $internal> fmt::Display for $type<MIN, MAX> {
1248 #[inline(always)]
1249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1250 const { assert!(MIN <= MAX); }
1251 self.get().fmt(f)
1252 }
1253 }
1254
1255 #[cfg(feature = "powerfmt")]
1256 impl<
1257 const MIN: $internal,
1258 const MAX: $internal,
1259 > smart_display::SmartDisplay for $type<MIN, MAX> {
1260 type Metadata = <$internal as smart_display::SmartDisplay>::Metadata;
1261
1262 #[inline(always)]
1263 fn metadata(
1264 &self,
1265 f: smart_display::FormatterOptions,
1266 ) -> smart_display::Metadata<'_, Self> {
1267 const { assert!(MIN <= MAX); }
1268 self.get_ref().metadata(f).reuse()
1269 }
1270
1271 #[inline(always)]
1272 fn fmt_with_metadata(
1273 &self,
1274 f: &mut fmt::Formatter<'_>,
1275 metadata: smart_display::Metadata<'_, Self>,
1276 ) -> fmt::Result {
1277 const { assert!(MIN <= MAX); }
1278 self.get().fmt_with_metadata(f, metadata.reuse())
1279 }
1280 }
1281
1282 impl<const MIN: $internal, const MAX: $internal> Default for $optional_type<MIN, MAX> {
1283 #[inline(always)]
1284 fn default() -> Self {
1285 const { assert!(MIN <= MAX); }
1286 Self::None
1287 }
1288 }
1289
1290 impl<const MIN: $internal, const MAX: $internal> AsRef<$internal> for $type<MIN, MAX> {
1291 #[inline(always)]
1292 fn as_ref(&self) -> &$internal {
1293 const { assert!(MIN <= MAX); }
1294 &self.get_ref()
1295 }
1296 }
1297
1298 impl<const MIN: $internal, const MAX: $internal> Borrow<$internal> for $type<MIN, MAX> {
1299 #[inline(always)]
1300 fn borrow(&self) -> &$internal {
1301 const { assert!(MIN <= MAX); }
1302 &self.get_ref()
1303 }
1304 }
1305
1306 impl<
1307 const MIN_A: $internal,
1308 const MAX_A: $internal,
1309 const MIN_B: $internal,
1310 const MAX_B: $internal,
1311 > PartialEq<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1312 #[inline(always)]
1313 fn eq(&self, other: &$type<MIN_B, MAX_B>) -> bool {
1314 const {
1315 assert!(MIN_A <= MAX_A);
1316 assert!(MIN_B <= MAX_B);
1317 }
1318 self.get() == other.get()
1319 }
1320 }
1321
1322 impl<
1323 const MIN_A: $internal,
1324 const MAX_A: $internal,
1325 const MIN_B: $internal,
1326 const MAX_B: $internal,
1327 > PartialEq<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1328 #[inline(always)]
1329 fn eq(&self, other: &$optional_type<MIN_B, MAX_B>) -> bool {
1330 const {
1331 assert!(MIN_A <= MAX_A);
1332 assert!(MIN_B <= MAX_B);
1333 }
1334 self.get().map(|value| value.get()) == other.get().map(|value| value.get())
1335 }
1336 }
1337
1338 impl<
1339 const MIN_A: $internal,
1340 const MAX_A: $internal,
1341 const MIN_B: $internal,
1342 const MAX_B: $internal,
1343 > PartialOrd<$type<MIN_B, MAX_B>> for $type<MIN_A, MAX_A> {
1344 #[inline(always)]
1345 fn partial_cmp(&self, other: &$type<MIN_B, MAX_B>) -> Option<Ordering> {
1346 const {
1347 assert!(MIN_A <= MAX_A);
1348 assert!(MIN_B <= MAX_B);
1349 }
1350 self.get().partial_cmp(&other.get())
1351 }
1352 }
1353
1354 impl<
1355 const MIN_A: $internal,
1356 const MAX_A: $internal,
1357 const MIN_B: $internal,
1358 const MAX_B: $internal,
1359 > PartialOrd<$optional_type<MIN_B, MAX_B>> for $optional_type<MIN_A, MAX_A> {
1360 #[inline]
1361 fn partial_cmp(&self, other: &$optional_type<MIN_B, MAX_B>) -> Option<Ordering> {
1362 const {
1363 assert!(MIN_A <= MAX_A);
1364 assert!(MIN_B <= MAX_B);
1365 }
1366 if self.is_none() && other.is_none() {
1367 Some(Ordering::Equal)
1368 } else if self.is_none() {
1369 Some(Ordering::Less)
1370 } else if other.is_none() {
1371 Some(Ordering::Greater)
1372 } else {
1373 self.inner().partial_cmp(&other.inner())
1374 }
1375 }
1376 }
1377
1378 impl<
1379 const MIN: $internal,
1380 const MAX: $internal,
1381 > Ord for $optional_type<MIN, MAX> {
1382 #[inline]
1383 fn cmp(&self, other: &Self) -> Ordering {
1384 const { assert!(MIN <= MAX); }
1385 if self.is_none() && other.is_none() {
1386 Ordering::Equal
1387 } else if self.is_none() {
1388 Ordering::Less
1389 } else if other.is_none() {
1390 Ordering::Greater
1391 } else {
1392 self.inner().cmp(&other.inner())
1393 }
1394 }
1395 }
1396
1397 impl<const MIN: $internal, const MAX: $internal> fmt::Binary for $type<MIN, MAX> {
1398 #[inline(always)]
1399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1400 const { assert!(MIN <= MAX); }
1401 self.get().fmt(f)
1402 }
1403 }
1404
1405 impl<const MIN: $internal, const MAX: $internal> fmt::LowerHex for $type<MIN, MAX> {
1406 #[inline(always)]
1407 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1408 const { assert!(MIN <= MAX); }
1409 self.get().fmt(f)
1410 }
1411 }
1412
1413 impl<const MIN: $internal, const MAX: $internal> fmt::UpperHex for $type<MIN, MAX> {
1414 #[inline(always)]
1415 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1416 const { assert!(MIN <= MAX); }
1417 self.get().fmt(f)
1418 }
1419 }
1420
1421 impl<const MIN: $internal, const MAX: $internal> fmt::LowerExp for $type<MIN, MAX> {
1422 #[inline(always)]
1423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1424 const { assert!(MIN <= MAX); }
1425 self.get().fmt(f)
1426 }
1427 }
1428
1429 impl<const MIN: $internal, const MAX: $internal> fmt::UpperExp for $type<MIN, MAX> {
1430 #[inline(always)]
1431 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1432 const { assert!(MIN <= MAX); }
1433 self.get().fmt(f)
1434 }
1435 }
1436
1437 impl<const MIN: $internal, const MAX: $internal> fmt::Octal for $type<MIN, MAX> {
1438 #[inline(always)]
1439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1440 const { assert!(MIN <= MAX); }
1441 self.get().fmt(f)
1442 }
1443 }
1444
1445 if_unsigned! { $is_signed
1446 impl From<NonZero<$internal>> for $type<1, { $internal::MAX }> {
1447 #[inline(always)]
1448 fn from(value: NonZero<$internal>) -> Self {
1449 Self::from_nonzero(value)
1450 }
1451 }
1452
1453 impl From<$type<1, { $internal::MAX }>> for NonZero<$internal> {
1454 #[inline(always)]
1455 fn from(value: $type<1, { $internal::MAX }>) -> Self {
1456 value.to_nonzero()
1457 }
1458 }
1459 }
1460
1461 impl<const MIN: $internal, const MAX: $internal> From<$type<MIN, MAX>> for $internal {
1462 #[inline(always)]
1463 fn from(value: $type<MIN, MAX>) -> Self {
1464 const { assert!(MIN <= MAX); }
1465 value.get()
1466 }
1467 }
1468
1469 impl<
1470 const MIN: $internal,
1471 const MAX: $internal,
1472 > From<$type<MIN, MAX>> for $optional_type<MIN, MAX> {
1473 #[inline(always)]
1474 fn from(value: $type<MIN, MAX>) -> Self {
1475 const { assert!(MIN <= MAX); }
1476 Self::Some(value)
1477 }
1478 }
1479
1480 impl<
1481 const MIN: $internal,
1482 const MAX: $internal,
1483 > From<Option<$type<MIN, MAX>>> for $optional_type<MIN, MAX> {
1484 #[inline(always)]
1485 fn from(value: Option<$type<MIN, MAX>>) -> Self {
1486 const { assert!(MIN <= MAX); }
1487 match value {
1488 Some(value) => Self::Some(value),
1489 None => Self::None,
1490 }
1491 }
1492 }
1493
1494 impl<
1495 const MIN: $internal,
1496 const MAX: $internal,
1497 > From<$optional_type<MIN, MAX>> for Option<$type<MIN, MAX>> {
1498 #[inline(always)]
1499 fn from(value: $optional_type<MIN, MAX>) -> Self {
1500 const { assert!(MIN <= MAX); }
1501 value.get()
1502 }
1503 }
1504
1505 impl<const MIN: $internal, const MAX: $internal> TryFrom<$internal> for $type<MIN, MAX> {
1506 type Error = TryFromIntError;
1507
1508 #[inline]
1509 fn try_from(value: $internal) -> Result<Self, Self::Error> {
1510 const { assert!(MIN <= MAX); }
1511 Self::new(value).ok_or(TryFromIntError)
1512 }
1513 }
1514
1515 impl<const MIN: $internal, const MAX: $internal> FromStr for $type<MIN, MAX> {
1516 type Err = ParseIntError;
1517
1518 #[inline]
1519 fn from_str(s: &str) -> Result<Self, Self::Err> {
1520 const { assert!(MIN <= MAX); }
1521 let value = s.parse::<$internal>().map_err(|e| ParseIntError {
1522 kind: e.kind().clone()
1523 })?;
1524 if value < MIN {
1525 Err(ParseIntError { kind: IntErrorKind::NegOverflow })
1526 } else if value > MAX {
1527 Err(ParseIntError { kind: IntErrorKind::PosOverflow })
1528 } else {
1529 Ok(unsafe { Self::new_unchecked(value) })
1531 }
1532 }
1533 }
1534
1535 $(impl<
1536 const MIN_SRC: $from_internal,
1537 const MAX_SRC: $from_internal,
1538 const MIN_DST: $internal,
1539 const MAX_DST: $internal,
1540 > From<$from<MIN_SRC, MAX_SRC>> for $type<MIN_DST, MAX_DST>
1541 {
1542 #[inline(always)]
1543 #[allow(trivial_numeric_casts, unused_comparisons)]
1544 fn from(value: $from<MIN_SRC, MAX_SRC>) -> Self {
1545 const {
1546 assert!(MIN_SRC <= MAX_SRC, "source range is invalid");
1547 assert!(MIN_DST <= MAX_DST, "target range is invalid");
1548
1549 match ($from_internal::MIN == 0, $internal::MIN == 0) {
1550 (true, true) => {
1552 assert!(
1553 MIN_SRC as u128 >= MIN_DST as u128,
1554 "minimum value cannot be represented in the target range"
1555 );
1556 assert!(
1557 MAX_SRC as u128 <= MAX_DST as u128,
1558 "maximum value cannot be represented in the target range"
1559 );
1560 }
1561 (false, false) => {
1563 assert!(
1564 MIN_SRC as i128 >= MIN_DST as i128,
1565 "minimum value cannot be represented in the target range"
1566 );
1567 assert!(
1568 MAX_SRC as i128 <= MAX_DST as i128,
1569 "maximum value cannot be represented in the target range"
1570 );
1571 }
1572 (true, false) => {
1574 assert!(
1575 MIN_DST < 0 || MIN_SRC as u128 >= MIN_DST as u128,
1576 "minimum value cannot be represented in the target range"
1577 );
1578 assert!(
1579 MAX_DST >= 0
1580 && MAX_SRC as u128 <= i128::MAX as u128
1581 && MAX_SRC as i128 <= MAX_DST as i128,
1582 "maximum value cannot be represented in the target range"
1583 );
1584 }
1585 (false, true) => {
1587 assert!(
1588 MIN_SRC >= 0 && MIN_SRC as u128 >= MIN_DST as u128,
1589 "minimum value cannot be represented in the target range"
1590 );
1591 assert!(
1592 MAX_SRC >= 0 && MAX_SRC as u128 <= MAX_DST as u128,
1593 "maximum value cannot be represented in the target range"
1594 );
1595 }
1596 }
1597 }
1598
1599 unsafe { $type::new_unchecked(value.get() as $internal) }
1601 }
1602 })+
1603
1604 #[cfg(feature = "serde")]
1605 impl<const MIN: $internal, const MAX: $internal> serde_core::Serialize for $type<MIN, MAX> {
1606 #[inline(always)]
1607 fn serialize<S: serde_core::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>
1608 {
1609 const { assert!(MIN <= MAX); }
1610 self.get().serialize(serializer)
1611 }
1612 }
1613
1614 #[cfg(feature = "serde")]
1615 impl<
1616 const MIN: $internal,
1617 const MAX: $internal,
1618 > serde_core::Serialize for $optional_type<MIN, MAX> {
1619 #[inline(always)]
1620 fn serialize<S: serde_core::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>
1621 {
1622 const { assert!(MIN <= MAX); }
1623 self.get().serialize(serializer)
1624 }
1625 }
1626
1627 #[cfg(feature = "serde")]
1628 impl<
1629 'de,
1630 const MIN: $internal,
1631 const MAX: $internal,
1632 > serde_core::Deserialize<'de> for $type<MIN, MAX> {
1633 #[inline]
1634 fn deserialize<D: serde_core::Deserializer<'de>>(deserializer: D)
1635 -> Result<Self, D::Error>
1636 {
1637 const { assert!(MIN <= MAX); }
1638 let internal = <$internal>::deserialize(deserializer)?;
1639 Self::new(internal).ok_or_else(|| {
1640 #[cfg(feature = "alloc")]
1641 let s = alloc::format!("an integer in the range {}..={}", MIN, MAX);
1642 #[cfg(not(feature = "alloc"))]
1643 let s = "an integer in the valid range";
1644
1645 <D::Error as serde_core::de::Error>::invalid_value(
1646 serde_core::de::Unexpected::Other("integer"),
1647 &s.as_ref(),
1648 )
1649 })
1650 }
1651 }
1652
1653 #[cfg(feature = "serde")]
1654 impl<
1655 'de,
1656 const MIN: $internal,
1657 const MAX: $internal,
1658 > serde_core::Deserialize<'de> for $optional_type<MIN, MAX> {
1659 #[inline]
1660 fn deserialize<D: serde_core::Deserializer<'de>>(deserializer: D)
1661 -> Result<Self, D::Error>
1662 {
1663 const { assert!(MIN <= MAX); }
1664 match Option::<$type<MIN, MAX>>::deserialize(deserializer)? {
1665 Some(value) => Ok(Self::Some(value)),
1666 None => Ok(Self::None),
1667 }
1668 }
1669 }
1670
1671 #[cfg(feature = "rand08")]
1672 impl<
1673 const MIN: $internal,
1674 const MAX: $internal,
1675 > rand08::distributions::Distribution<$type<MIN, MAX>> for rand08::distributions::Standard {
1676 #[inline]
1677 fn sample<R: rand08::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1678 const { assert!(MIN <= MAX); }
1679 $type::new(rng.gen_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1680 }
1681 }
1682
1683 if_not_manual_rand_09! {
1684 [$($($skips)+)?]
1685 #[cfg(feature = "rand09")]
1686 impl<
1687 const MIN: $internal,
1688 const MAX: $internal,
1689 > rand09::distr::Distribution<$type<MIN, MAX>> for rand09::distr::StandardUniform {
1690 #[inline]
1691 fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1692 const { assert!(MIN <= MAX); }
1693 $type::new(rng.random_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1694 }
1695 }
1696 }
1697
1698 if_not_manual_rand_010! {
1699 [$($($skips)+)?]
1700 #[cfg(feature = "rand010")]
1701 impl<
1702 const MIN: $internal,
1703 const MAX: $internal,
1704 > rand010::distr::Distribution<$type<MIN, MAX>> for rand010::distr::StandardUniform {
1705 #[inline]
1706 fn sample<R: rand010::Rng + ?Sized>(&self, rng: &mut R) -> $type<MIN, MAX> {
1707 const { assert!(MIN <= MAX); }
1708 use rand010::RngExt as _;
1709 $type::new(rng.random_range(MIN..=MAX)).expect("rand failed to generate a valid value")
1710 }
1711 }
1712 }
1713
1714 #[cfg(feature = "rand08")]
1715 impl<
1716 const MIN: $internal,
1717 const MAX: $internal,
1718 > rand08::distributions::Distribution<$optional_type<MIN, MAX>>
1719 for rand08::distributions::Standard {
1720 #[inline]
1721 fn sample<R: rand08::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1722 const { assert!(MIN <= MAX); }
1723 rng.r#gen::<Option<$type<MIN, MAX>>>().into()
1724 }
1725 }
1726
1727 #[cfg(feature = "rand09")]
1728 impl<
1729 const MIN: $internal,
1730 const MAX: $internal,
1731 > rand09::distr::Distribution<$optional_type<MIN, MAX>>
1732 for rand09::distr::StandardUniform {
1733 #[inline]
1734 fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1735 const { assert!(MIN <= MAX); }
1736 if rng.random() {
1737 $optional_type::None
1738 } else {
1739 $optional_type::Some(rng.random::<$type<MIN, MAX>>())
1740 }
1741 }
1742 }
1743
1744 #[cfg(feature = "rand010")]
1745 impl<
1746 const MIN: $internal,
1747 const MAX: $internal,
1748 > rand010::distr::Distribution<$optional_type<MIN, MAX>>
1749 for rand010::distr::StandardUniform {
1750 #[inline]
1751 fn sample<R: rand010::Rng + ?Sized>(&self, rng: &mut R) -> $optional_type<MIN, MAX> {
1752 const { assert!(MIN <= MAX); }
1753 use rand010::RngExt as _;
1754 if rng.random() {
1755 $optional_type::None
1756 } else {
1757 $optional_type::Some(rng.random::<$type<MIN, MAX>>())
1758 }
1759 }
1760 }
1761
1762 #[cfg(feature = "num")]
1763 impl<const MIN: $internal, const MAX: $internal> num_traits::Bounded for $type<MIN, MAX> {
1764 #[inline(always)]
1765 fn min_value() -> Self {
1766 const { assert!(MIN <= MAX); }
1767 Self::MIN
1768 }
1769
1770 #[inline(always)]
1771 fn max_value() -> Self {
1772 const { assert!(MIN <= MAX); }
1773 Self::MAX
1774 }
1775 }
1776
1777 #[cfg(feature = "quickcheck")]
1778 impl<const MIN: $internal, const MAX: $internal> quickcheck::Arbitrary for $type<MIN, MAX> {
1779 #[allow(trivial_numeric_casts)] #[inline]
1781 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1782 const { assert!(MIN <= MAX); }
1783 if const { MIN == <$internal>::MIN && MAX == <$internal>::MAX } {
1784 unsafe { Self::new_unchecked(<$internal>::arbitrary(g)) }
1786 } else {
1787 let range = (MAX as $unsigned_type)
1788 .wrapping_sub(MIN as $unsigned_type)
1789 .wrapping_add(1);
1790 let offset = (<$internal>::arbitrary(g) as $unsigned_type)
1791 .wrapping_sub(MIN as $unsigned_type)
1792 % range;
1793 let value = (MIN as $unsigned_type).wrapping_add(offset) as $internal;
1794
1795 unsafe {
1797 Self::new_unchecked(value)
1798 }
1799 }
1800 }
1801
1802 #[inline]
1803 fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1804 ::alloc::boxed::Box::new(
1805 self.get()
1806 .shrink()
1807 .filter_map(Self::new)
1808 )
1809 }
1810 }
1811
1812 #[cfg(feature = "quickcheck")]
1813 impl<
1814 const MIN: $internal,
1815 const MAX: $internal,
1816 > quickcheck::Arbitrary for $optional_type<MIN, MAX> {
1817 #[inline]
1818 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1819 const { assert!(MIN <= MAX); }
1820 Option::<$type<MIN, MAX>>::arbitrary(g).into()
1821 }
1822
1823 #[inline]
1824 fn shrink(&self) -> ::alloc::boxed::Box<dyn Iterator<Item = Self>> {
1825 ::alloc::boxed::Box::new(self.get().shrink().map(Self::from))
1826 }
1827 }
1828 )*};
1829}
1830
1831impl_ranged! {
1832 RangedU8 {
1833 mod_name: ranged_u8
1834 alias: ru8
1835 internal: u8
1836 signed: false
1837 unsigned: u8
1838 optional: OptionRangedU8
1839 optional_alias: Option_ru8
1840 from: [
1841 RangedU16(u16)
1842 RangedU32(u32)
1843 RangedU64(u64)
1844 RangedU128(u128)
1845 RangedUsize(usize)
1846 RangedI8(i8)
1847 RangedI16(i16)
1848 RangedI32(i32)
1849 RangedI64(i64)
1850 RangedI128(i128)
1851 RangedIsize(isize)
1852 ]
1853 }
1854 RangedU16 {
1855 mod_name: ranged_u16
1856 alias: ru16
1857 internal: u16
1858 signed: false
1859 unsigned: u16
1860 optional: OptionRangedU16
1861 optional_alias: Option_ru16
1862 from: [
1863 RangedU8(u8)
1864 RangedU32(u32)
1865 RangedU64(u64)
1866 RangedU128(u128)
1867 RangedUsize(usize)
1868 RangedI8(i8)
1869 RangedI16(i16)
1870 RangedI32(i32)
1871 RangedI64(i64)
1872 RangedI128(i128)
1873 RangedIsize(isize)
1874 ]
1875 }
1876 RangedU32 {
1877 mod_name: ranged_u32
1878 alias: ru32
1879 internal: u32
1880 signed: false
1881 unsigned: u32
1882 optional: OptionRangedU32
1883 optional_alias: Option_ru32
1884 from: [
1885 RangedU8(u8)
1886 RangedU16(u16)
1887 RangedU64(u64)
1888 RangedU128(u128)
1889 RangedUsize(usize)
1890 RangedI8(i8)
1891 RangedI16(i16)
1892 RangedI32(i32)
1893 RangedI64(i64)
1894 RangedI128(i128)
1895 RangedIsize(isize)
1896 ]
1897 }
1898 RangedU64 {
1899 mod_name: ranged_u64
1900 alias: ru64
1901 internal: u64
1902 signed: false
1903 unsigned: u64
1904 optional: OptionRangedU64
1905 optional_alias: Option_ru64
1906 from: [
1907 RangedU8(u8)
1908 RangedU16(u16)
1909 RangedU32(u32)
1910 RangedU128(u128)
1911 RangedUsize(usize)
1912 RangedI8(i8)
1913 RangedI16(i16)
1914 RangedI32(i32)
1915 RangedI64(i64)
1916 RangedI128(i128)
1917 RangedIsize(isize)
1918 ]
1919 }
1920 RangedU128 {
1921 mod_name: ranged_u128
1922 alias: ru128
1923 internal: u128
1924 signed: false
1925 unsigned: u128
1926 optional: OptionRangedU128
1927 optional_alias: Option_ru128
1928 from: [
1929 RangedU8(u8)
1930 RangedU16(u16)
1931 RangedU32(u32)
1932 RangedU64(u64)
1933 RangedUsize(usize)
1934 RangedI8(i8)
1935 RangedI16(i16)
1936 RangedI32(i32)
1937 RangedI64(i64)
1938 RangedI128(i128)
1939 RangedIsize(isize)
1940 ]
1941 }
1942 RangedUsize {
1943 mod_name: ranged_usize
1944 alias: rusize
1945 internal: usize
1946 signed: false
1947 unsigned: usize
1948 optional: OptionRangedUsize
1949 optional_alias: Option_rusize
1950 from: [
1951 RangedU8(u8)
1952 RangedU16(u16)
1953 RangedU32(u32)
1954 RangedU64(u64)
1955 RangedU128(u128)
1956 RangedI8(i8)
1957 RangedI16(i16)
1958 RangedI32(i32)
1959 RangedI64(i64)
1960 RangedI128(i128)
1961 RangedIsize(isize)
1962 ]
1963 manual: [rand_09 rand_010]
1964 }
1965 RangedI8 {
1966 mod_name: ranged_i8
1967 alias: ri8
1968 internal: i8
1969 signed: true
1970 unsigned: u8
1971 optional: OptionRangedI8
1972 optional_alias: Option_ri8
1973 from: [
1974 RangedU8(u8)
1975 RangedU16(u16)
1976 RangedU32(u32)
1977 RangedU64(u64)
1978 RangedU128(u128)
1979 RangedUsize(usize)
1980 RangedI16(i16)
1981 RangedI32(i32)
1982 RangedI64(i64)
1983 RangedI128(i128)
1984 RangedIsize(isize)
1985 ]
1986 }
1987 RangedI16 {
1988 mod_name: ranged_i16
1989 alias: ri16
1990 internal: i16
1991 signed: true
1992 unsigned: u16
1993 optional: OptionRangedI16
1994 optional_alias: Option_ri16
1995 from: [
1996 RangedU8(u8)
1997 RangedU16(u16)
1998 RangedU32(u32)
1999 RangedU64(u64)
2000 RangedU128(u128)
2001 RangedUsize(usize)
2002 RangedI8(i8)
2003 RangedI32(i32)
2004 RangedI64(i64)
2005 RangedI128(i128)
2006 RangedIsize(isize)
2007 ]
2008 }
2009 RangedI32 {
2010 mod_name: ranged_i32
2011 alias: ri32
2012 internal: i32
2013 signed: true
2014 unsigned: u32
2015 optional: OptionRangedI32
2016 optional_alias: Option_ri32
2017 from: [
2018 RangedU8(u8)
2019 RangedU16(u16)
2020 RangedU32(u32)
2021 RangedU64(u64)
2022 RangedU128(u128)
2023 RangedUsize(usize)
2024 RangedI8(i8)
2025 RangedI16(i16)
2026 RangedI64(i64)
2027 RangedI128(i128)
2028 RangedIsize(isize)
2029 ]
2030 }
2031 RangedI64 {
2032 mod_name: ranged_i64
2033 alias: ri64
2034 internal: i64
2035 signed: true
2036 unsigned: u64
2037 optional: OptionRangedI64
2038 optional_alias: Option_ri64
2039 from: [
2040 RangedU8(u8)
2041 RangedU16(u16)
2042 RangedU32(u32)
2043 RangedU64(u64)
2044 RangedU128(u128)
2045 RangedUsize(usize)
2046 RangedI8(i8)
2047 RangedI16(i16)
2048 RangedI32(i32)
2049 RangedI128(i128)
2050 RangedIsize(isize)
2051 ]
2052 }
2053 RangedI128 {
2054 mod_name: ranged_i128
2055 alias: ri128
2056 internal: i128
2057 signed: true
2058 unsigned: u128
2059 optional: OptionRangedI128
2060 optional_alias: Option_ri128
2061 from: [
2062 RangedU8(u8)
2063 RangedU16(u16)
2064 RangedU32(u32)
2065 RangedU64(u64)
2066 RangedU128(u128)
2067 RangedUsize(usize)
2068 RangedI8(i8)
2069 RangedI16(i16)
2070 RangedI32(i32)
2071 RangedI64(i64)
2072 RangedIsize(isize)
2073 ]
2074 }
2075 RangedIsize {
2076 mod_name: ranged_isize
2077 alias: risize
2078 internal: isize
2079 signed: true
2080 unsigned: usize
2081 optional: OptionRangedIsize
2082 optional_alias: Option_risize
2083 from: [
2084 RangedU8(u8)
2085 RangedU16(u16)
2086 RangedU32(u32)
2087 RangedU64(u64)
2088 RangedU128(u128)
2089 RangedUsize(usize)
2090 RangedI8(i8)
2091 RangedI16(i16)
2092 RangedI32(i32)
2093 RangedI64(i64)
2094 RangedI128(i128)
2095 ]
2096 manual: [rand_09 rand_010]
2097 }
2098}
2099
2100#[cfg(feature = "rand09")]
2101impl<const MIN: usize, const MAX: usize> rand09::distr::Distribution<RangedUsize<MIN, MAX>>
2102 for rand09::distr::StandardUniform
2103{
2104 #[inline]
2105 fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> RangedUsize<MIN, MAX> {
2106 const {
2107 assert!(MIN <= MAX);
2108 }
2109
2110 #[cfg(target_pointer_width = "16")]
2111 let value = rng.random_range(MIN as u16..=MAX as u16) as usize;
2112 #[cfg(target_pointer_width = "32")]
2113 let value = rng.random_range(MIN as u32..=MAX as u32) as usize;
2114 #[cfg(target_pointer_width = "64")]
2115 let value = rng.random_range(MIN as u64..=MAX as u64) as usize;
2116 #[cfg(not(any(
2117 target_pointer_width = "16",
2118 target_pointer_width = "32",
2119 target_pointer_width = "64"
2120 )))]
2121 compile_error("platform has unusual (and unsupported) pointer width");
2122
2123 RangedUsize::new(value).expect("rand failed to generate a valid value")
2124 }
2125}
2126
2127#[cfg(feature = "rand09")]
2128impl<const MIN: isize, const MAX: isize> rand09::distr::Distribution<RangedIsize<MIN, MAX>>
2129 for rand09::distr::StandardUniform
2130{
2131 #[inline]
2132 fn sample<R: rand09::Rng + ?Sized>(&self, rng: &mut R) -> RangedIsize<MIN, MAX> {
2133 const {
2134 assert!(MIN <= MAX);
2135 }
2136
2137 #[cfg(target_pointer_width = "16")]
2138 let value = rng.random_range(MIN as i16..=MAX as i16) as isize;
2139 #[cfg(target_pointer_width = "32")]
2140 let value = rng.random_range(MIN as i32..=MAX as i32) as isize;
2141 #[cfg(target_pointer_width = "64")]
2142 let value = rng.random_range(MIN as i64..=MAX as i64) as isize;
2143 #[cfg(not(any(
2144 target_pointer_width = "16",
2145 target_pointer_width = "32",
2146 target_pointer_width = "64"
2147 )))]
2148 compile_error("platform has unusual (and unsupported) pointer width");
2149
2150 RangedIsize::new(value).expect("rand failed to generate a valid value")
2151 }
2152}
2153
2154#[cfg(feature = "rand010")]
2155impl<const MIN: usize, const MAX: usize> rand010::distr::Distribution<RangedUsize<MIN, MAX>>
2156 for rand010::distr::StandardUniform
2157{
2158 #[inline]
2159 fn sample<R: rand010::Rng + ?Sized>(&self, rng: &mut R) -> RangedUsize<MIN, MAX> {
2160 const {
2161 assert!(MIN <= MAX);
2162 }
2163
2164 use rand010::RngExt as _;
2165
2166 #[cfg(target_pointer_width = "16")]
2167 let value = rng.random_range(MIN as u16..=MAX as u16) as usize;
2168 #[cfg(target_pointer_width = "32")]
2169 let value = rng.random_range(MIN as u32..=MAX as u32) as usize;
2170 #[cfg(target_pointer_width = "64")]
2171 let value = rng.random_range(MIN as u64..=MAX as u64) as usize;
2172 #[cfg(not(any(
2173 target_pointer_width = "16",
2174 target_pointer_width = "32",
2175 target_pointer_width = "64"
2176 )))]
2177 compile_error("platform has unusual (and unsupported) pointer width");
2178
2179 RangedUsize::new(value).expect("rand failed to generate a valid value")
2180 }
2181}
2182
2183#[cfg(feature = "rand010")]
2184impl<const MIN: isize, const MAX: isize> rand010::distr::Distribution<RangedIsize<MIN, MAX>>
2185 for rand010::distr::StandardUniform
2186{
2187 #[inline]
2188 fn sample<R: rand010::Rng + ?Sized>(&self, rng: &mut R) -> RangedIsize<MIN, MAX> {
2189 const {
2190 assert!(MIN <= MAX);
2191 }
2192
2193 use rand010::RngExt as _;
2194
2195 #[cfg(target_pointer_width = "16")]
2196 let value = rng.random_range(MIN as i16..=MAX as i16) as isize;
2197 #[cfg(target_pointer_width = "32")]
2198 let value = rng.random_range(MIN as i32..=MAX as i32) as isize;
2199 #[cfg(target_pointer_width = "64")]
2200 let value = rng.random_range(MIN as i64..=MAX as i64) as isize;
2201 #[cfg(not(any(
2202 target_pointer_width = "16",
2203 target_pointer_width = "32",
2204 target_pointer_width = "64"
2205 )))]
2206 compile_error("platform has unusual (and unsupported) pointer width");
2207
2208 RangedIsize::new(value).expect("rand failed to generate a valid value")
2209 }
2210}