bounded_integer/
prim_int.rs1use core::fmt::{self, Display, Formatter};
2use core::num::NonZero;
3
4#[derive(Debug, Clone, Copy)]
6#[non_exhaustive]
7pub struct TryFromError;
8
9impl Display for TryFromError {
10 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
11 f.write_str("out of range conversion to bounded integer attempted")
12 }
13}
14
15#[cfg(feature = "std")]
16impl std::error::Error for TryFromError {}
17
18#[must_use]
19pub fn try_from_error() -> TryFromError {
20 TryFromError
21}
22
23pub trait PrimInt {
24 type Signed;
25 type Unsigned;
26}
27
28pub type Signed<T> = <T as PrimInt>::Signed;
29pub type Unsigned<T> = <T as PrimInt>::Unsigned;
30
31generate! {
32 u8 i8,
33 u16 i16,
34 u32 i32,
35 u64 i64,
36 u128 i128,
37 usize isize,
38}
39
40macro_rules! generate {
41 ($($unsigned:ident $signed:ident,)*) => { $(
42 impl PrimInt for $unsigned {
43 type Signed = $signed;
44 type Unsigned = $unsigned;
45 }
46 impl PrimInt for $signed {
47 type Signed = $signed;
48 type Unsigned = $unsigned;
49 }
50
51 impl crate::__private::Dispatch<$unsigned> {
52 pub const fn checked_add_unsigned(lhs: $unsigned, rhs: $unsigned) -> Option<$unsigned> {
53 lhs.checked_add(rhs)
54 }
55 pub const fn checked_sub_unsigned(lhs: $unsigned, rhs: $unsigned) -> Option<$unsigned> {
56 lhs.checked_sub(rhs)
57 }
58 pub const fn rem_euclid_unsigned(lhs: $unsigned, rhs: NonZero<$unsigned>) -> $unsigned {
59 lhs.rem_euclid(rhs.get())
60 }
61 }
62 impl crate::__private::Dispatch<$signed> {
63 pub const fn checked_add_unsigned(lhs: $signed, rhs: $unsigned) -> Option<$signed> {
64 lhs.checked_add_unsigned(rhs)
65 }
66 pub const fn checked_sub_unsigned(lhs: $signed, rhs: $unsigned) -> Option<$signed> {
67 lhs.checked_sub_unsigned(rhs)
68 }
69 pub const fn rem_euclid_unsigned(lhs: $signed, rhs: NonZero<$unsigned>) -> $unsigned {
70 #[expect(clippy::cast_possible_wrap)]
72 #[expect(clippy::cast_sign_loss)]
73 if 0 <= lhs {
74 (lhs as $unsigned).rem_euclid(rhs.get())
76 } else if 0 <= rhs.get() as $signed {
77 lhs.rem_euclid(rhs.get() as $signed) as $unsigned
80 } else {
81 rhs.get().checked_add_signed(lhs).unwrap().rem_euclid(rhs.get())
85 }
86 }
87 }
88 )* };
89}
90use generate;
91
92pub trait HasWide {
95 type Wide;
96}
97
98pub type Wide<T> = <T as HasWide>::Wide;
99
100impl HasWide for u8 {
101 type Wide = u16;
102}
103impl HasWide for u16 {
104 type Wide = u32;
105}
106impl HasWide for u32 {
107 type Wide = u64;
108}
109impl HasWide for u64 {
110 type Wide = u128;
111}
112impl HasWide for i8 {
113 type Wide = i16;
114}
115impl HasWide for i16 {
116 type Wide = i32;
117}
118impl HasWide for i32 {
119 type Wide = i64;
120}
121impl HasWide for i64 {
122 type Wide = i128;
123}