1macro_rules! impl_primint {
4 ($($target:ident),*) => {$(
5 impl crate::IntegerId for $target {
6 type Int = $target;
7 const MIN_ID: Option<Self> = Some(0);
8 const MAX_ID: Option<Self> = Some($target::MAX);
9 const MIN_ID_INT: Option<Self::Int> = Some(0);
10 const MAX_ID_INT: Option<Self::Int> = Some($target::MAX);
11 const TRUSTED_RANGE: Option<crate::trusted::TrustedRangeToken<Self>> = unsafe { Some(crate::trusted::TrustedRangeToken::assume_valid()) };
13 #[inline]
14 fn from_int_checked(id: Self::Int) -> Option<Self> {
15 Some(id)
16 }
17 #[inline]
18 fn to_int(self) -> Self::Int {
19 self
20 }
21 }
22 impl crate::IntegerIdContiguous for $target {}
23 impl crate::IntegerIdCounter for $target {
24 const START: Self = 0;
25 const START_INT: Self = 0;
26 }
27 )*};
28}
29impl_primint!(u8, u16, u32, u64, u128, usize);
30macro_rules! impl_nonzero_int {
32 (@main_body $target:path, $int:ident, one => $one:expr, max => $max:expr) => {
33 type Int = $int;
34 const MIN_ID: Option<Self> = {
35 unsafe {
38 Some(<$target>::new_unchecked($one))
39 }
40 };
41 const MAX_ID: Option<Self> = {
42 unsafe {
44 Some(<$target>::new_unchecked($max))
45 }
46 };
47 const MIN_ID_INT: Option<Self::Int> = Some($one);
48 const MAX_ID_INT: Option<Self::Int> = Some($max);
49 const TRUSTED_RANGE: Option<crate::trusted::TrustedRangeToken<Self>> = unsafe { Some(crate::trusted::TrustedRangeToken::assume_valid()) };
51
52 #[inline]
53 fn from_int_checked(id: Self::Int) -> Option<Self> {
54 <$target>::new(id)
55 }
56
57 #[inline]
58 unsafe fn from_int_unchecked(id: Self::Int) -> Self {
59 unsafe {
61 <$target>::new_unchecked(id)
62 }
63 }
64
65 #[inline]
66 fn to_int(self) -> Self::Int {
67 self.get()
68 }
69 };
70 (@counter_body $target:path, $int:ident) => {
71 const START: Self = match <Self as crate::IntegerId>::MIN_ID {
72 Some(valid) => valid,
73 None => panic!("type should be inhabited")
74 };
75 const START_INT: $int = Self::START.get();
76 };
77 (@stdlib $($target:ident => $int:ident),*) => {$(
78 impl crate::IntegerId for core::num::$target {
79 impl_nonzero_int!(@main_body core::num::$target, $int, one => 1, max => $int::MAX);
80 }
81 impl crate::IntegerIdContiguous for core::num::$target {}
82 impl crate::IntegerIdCounter for core::num::$target {
83 impl_nonzero_int!(@counter_body core::num::$target, $int);
84 }
85 )*}
86}
87impl_nonzero_int!(
88 @stdlib
89 NonZeroU8 => u8,
90 NonZeroU16 => u16,
91 NonZeroU32 => u32,
92 NonZeroU64 => u64,
93 NonZeroU128 => u128,
94 NonZeroUsize => usize
95);
96#[cfg(feature = "primint-nonzero")]
97mod primint_nonzero {
98 use primint::UnsignedPrimInt;
99
100 impl<T: UnsignedPrimInt> crate::IntegerId for primint::num::NonZero<T> {
101 impl_nonzero_int!(@main_body primint::num::NonZero<T>, T, one => primint::one(), max => primint::max_value());
102 }
103 impl<T: UnsignedPrimInt> crate::IntegerIdContiguous for primint::num::NonZero<T> {}
104 impl<T: UnsignedPrimInt> crate::IntegerIdCounter for primint::num::NonZero<T> {
105 impl_nonzero_int!(@counter_body primint::num::NonZero<T>, T);
106 }
107}
108
109#[cfg(any(feature = "nonmax", feature = "primint-nonmax"))]
110macro_rules! do_nonmax_impl {
111 (@main_body $target:path, $int:ident) => {
112 type Int = $int;
113 const MIN_ID: Option<Self> = Some({
114 assert!(primint::is_signed::<$int>());
115 unsafe { <$target>::new_unchecked(primint::zero()) }
117 });
118 const MAX_ID: Option<Self> = Some(<$target>::MAX);
119 const MIN_ID_INT: Option<Self::Int> = Some(primint::zero());
120 const MAX_ID_INT: Option<Self::Int> = Some(<$target>::MAX.get());
121 const TRUSTED_RANGE: Option<crate::trusted::TrustedRangeToken<Self>> = unsafe { Some(crate::trusted::TrustedRangeToken::assume_valid()) };
123
124 #[inline]
125 fn from_int_checked(id: Self::Int) -> Option<Self> {
126 <$target>::new(id)
127 }
128 #[inline]
129 unsafe fn from_int_unchecked(id: Self::Int) -> Self {
130 unsafe { <$target>::new_unchecked(id) }
132 }
133 #[inline]
134 fn to_int(self) -> Self::Int {
135 self.get()
136 }
137 };
138 (@nonmax_crate $($target:ident => $int:ident),*) => {$(
139 impl crate::IntegerId for nonmax::$target {
140 do_nonmax_impl!(@main_body nonmax::$target, $int);
141 }
142 impl crate::IntegerIdContiguous for nonmax::$target {}
143 impl crate::IntegerIdCounter for nonmax::$target {
144 const START: Self = nonmax::$target::ZERO;
145 const START_INT: Self::Int = 0;
146 }
147 )*};
148}
149#[cfg(feature = "nonmax")]
150do_nonmax_impl!(
151 @nonmax_crate
152 NonMaxU8 => u8,
153 NonMaxU16 => u16,
154 NonMaxU32 => u32,
155 NonMaxU64 => u64,
156 NonMaxU128 => u128,
157 NonMaxUsize => usize
158);
159
160#[cfg(feature = "primint-nonmax")]
161mod primint_nonmax {
162 use primint::UnsignedPrimInt;
163
164 impl<T: UnsignedPrimInt> crate::IntegerId for primint::num::NonMax<T> {
165 do_nonmax_impl!(@main_body primint::num::NonMax<T>, T);
166 }
167 impl<T: UnsignedPrimInt> crate::IntegerIdContiguous for primint::num::NonMax<T> {}
168 impl<T: UnsignedPrimInt> crate::IntegerIdCounter for primint::num::NonMax<T> {
169 const START: Self = primint::num::NonMax::<T>::MIN;
170 const START_INT: T = primint::zero();
171 }
172}
173
174macro_rules! impl_uninhabited {
175 ($target:ty) => {
176 impl crate::IntegerId for $target {
177 type Int = u8;
178 const MIN_ID: Option<Self> = None;
179 const MAX_ID: Option<Self> = None;
180 const MIN_ID_INT: Option<Self::Int> = None;
181 const MAX_ID_INT: Option<Self::Int> = None;
182 const TRUSTED_RANGE: Option<crate::trusted::TrustedRangeToken<Self>> = {
183 unsafe { Some(crate::trusted::TrustedRangeToken::assume_valid()) }
185 };
186
187 #[track_caller]
188 #[inline]
189 fn from_int(id: Self::Int) -> Self {
190 panic!(
191 "Cannot initialize uninhabited type {this} with {id}",
192 this = stringify!($target),
193 )
194 }
195
196 #[inline]
197 fn from_int_checked(_id: Self::Int) -> Option<Self> {
198 None
199 }
200
201 #[inline]
202 unsafe fn from_int_unchecked(_id: Self::Int) -> Self {
203 unsafe {
206 core::hint::unreachable_unchecked();
207 }
208 }
209
210 #[inline]
211 fn to_int(self) -> Self::Int {
212 match self {}
213 }
214 }
215 impl crate::IntegerIdContiguous for $target {}
216 };
217}
218impl_uninhabited!(core::convert::Infallible);