numera/number/integer/pz/
sized.rs1#[cfg(feature = "try_from")]
13use crate::number::integer::PositiveIntegers;
14use crate::{
15 error::{IntegerErrors, NumeraErrors, NumeraResult},
16 number::{
17 macros::impl_larger_smaller,
18 traits::{
19 Bound, ConstLowerBounded, ConstOne, ConstUpperBounded, Count, Countable, Ident,
20 LowerBounded, NonNegative, NonZero, Number, One, Positive, Sign, UpperBounded,
21 },
22 },
23};
24use core::{
25 fmt,
26 num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8},
27};
28use devela::paste;
29
30macro_rules! define_positive_integer_sized {
52 (multi $name:ident, $abbr:ident, $p:ident,
54 $doc_num:literal, $doc_type:literal, $doc_sign:literal, $doc_lower:expr, $doc_upper:expr,
56 $(
57 (
58 $doc_det:literal, $b:expr,
59 larger: $larger:literal, $larger_b:literal,
60 smaller: $smaller:literal, $smaller_b:literal
61 )
62 ),+
63 ) => {
64 $(
65 define_positive_integer_sized![single $name, $abbr, $p,
66 $doc_num, $doc_type, $doc_sign, $doc_lower, $doc_upper,
68 ($doc_det, $b,
69 larger: $larger, $larger_b,
70 smaller: $smaller, $smaller_b
71 )];
72 )+
73 };
74 (single $name:ident, $abbr:ident, $p:ident,
76 $doc_num:literal, $doc_type:literal, $doc_sign:literal, $doc_lower:expr, $doc_upper:expr,
78 (
79 $doc_det:literal, $b:expr,
80 larger: $larger:literal, $larger_b:literal,
81 smaller: $smaller:literal, $smaller_b:literal
82 )
83 ) => { paste! {
84 #[doc = $doc_det " "$b "-bit " $doc_num $doc_type ","]
85 #[doc = "also known as [`" [<$abbr$b>] "`][super::" [<$abbr$b>] "]."]
86 #[doc = "\n\nThe range of valid numeric values is $\\lbrack" $doc_sign
87 "1 \\dots$ [`" u$b
88 "::" $doc_upper "`]$\\rbrack$."]
89 #[doc = "\n\nIt is equivalent to the [`" [<NonZeroU$b>] "`] primitive."]
90 #[doc = "[`Counting" $b "`][super::Counting" $b "]."]
93 #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
96 pub struct [<$name$b>](pub [<$p$b>]);
97
98 impl fmt::Display for [<$name$b>] {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 write!(f, "{}", self.0)
101 }
102 }
103 impl fmt::Debug for [<$name$b>] {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(f, "{}({})", stringify!([<$abbr$b>]), self.0)
106 }
107 }
108
109 impl [<$name$b>] {
110 #[doc = "Returns a new `" [<$name$b>] "`."]
111 #[inline]
117 pub const fn new(value: [<u$b>]) -> NumeraResult<Self> {
118 if let Some(n) = [<$p$b>]::new(value) {
119 Ok(Self(n))
120 } else {
121 Err(NumeraErrors::Integer(IntegerErrors::Zero))
122 }
123 }
124
125 #[doc = "Returns a new `" [<$name$b>] "`."]
126 #[inline]
133 #[cfg(not(feature = "safe"))]
134 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
135 pub const unsafe fn new_unchecked(value: [<u$b>]) -> Self {
136 debug_assert![value != 0];
137 Self([<$p$b>]::new_unchecked(value))
138 }
139 }
140
141 impl_larger_smaller![$name, $b, PositiveIntegers,
145 larger: $larger, $larger_b, smaller: $smaller, $smaller_b
146 ];
147
148 impl Sign for [<$name$b>] {
151 #[inline]
152 fn can_negative(&self) -> bool { false }
153 #[inline]
154 fn can_positive(&self) -> bool { true }
155 #[inline]
156 fn is_negative(&self) -> bool { false }
157 #[inline]
158 fn is_positive(&self) -> bool { true }
159 }
160 impl NonNegative for [<$name$b>] {}
161 impl Positive for [<$name$b>] {}
162
163 impl Bound for [<$name$b>] {
166 #[inline]
167 fn is_lower_bounded(&self) -> bool { true }
168 #[inline]
169 fn is_upper_bounded(&self) -> bool { true }
170 #[inline]
171 fn lower_bound(&self) -> Option<Self> { Some([<$name$b>]::MIN) }
172 #[inline]
173 fn upper_bound(&self) -> Option<Self> { Some([<$name$b>]::MAX) }
174 }
175 impl LowerBounded for [<$name$b>] {
176 #[inline]
177 fn new_min() -> Self { [<$name$b>]::MIN }
178 }
179 impl UpperBounded for [<$name$b>] {
180 #[inline]
181 fn new_max() -> Self { [<$name$b>]::MAX }
182 }
183 impl ConstLowerBounded for [<$name$b>] {
184 const MIN: Self = Self([<$p$b>]::MIN);
185 }
186 impl ConstUpperBounded for [<$name$b>] {
187 const MAX: Self = Self([<$p$b>]::MAX);
188 }
189
190 impl Count for [<$name$b>] {
193 #[inline]
194 fn is_countable(&self) -> bool { true }
195 }
196
197 impl Countable for [<$name$b>] {
198 #[inline]
203 fn next(&self) -> NumeraResult<Self> {
204 let next = self.0.get().checked_add(1).ok_or(IntegerErrors::Overflow)?;
205
206 #[cfg(feature = "safe")]
207 return Ok(Self([<$p$b>]::new(next).unwrap()));
208
209 #[cfg(not(feature = "safe"))]
210 return Ok(Self(unsafe { [<$p$b>]::new_unchecked(next) }));
212 }
213 #[inline]
218 fn previous(&self) -> NumeraResult<Self> {
219 let prev = self.0.get().checked_sub(1).ok_or(IntegerErrors::Underflow)?;
220
221 #[cfg(feature = "safe")]
222 return Ok(Self([<$p$b>]::new(prev).unwrap()));
223
224 #[cfg(not(feature = "safe"))]
225 return Ok(Self(unsafe { [<$p$b>]::new_unchecked(prev) }));
227 }
228 }
229
230 impl Ident for [<$name$b>] {
233 #[inline]
234 fn can_zero(&self) -> bool { false }
235 #[inline]
236 fn can_one(&self) -> bool { true }
237 #[inline]
238 fn can_neg_one(&self) -> bool { false }
239
240 #[inline]
241 fn is_zero(&self) -> bool { false }
242 #[inline]
243 fn is_one(&self) -> bool { self.0.get() == 1 }
244 #[inline]
245 fn is_neg_one(&self) -> bool { false }
246 }
247 impl NonZero for [<$name$b>] {}
248 impl ConstOne for [<$name$b>] {
249 #[cfg(feature = "safe")]
250 const ONE: Self = Self(
251 if let Some(n) = [<$p$b>]::new(1)
252 { n } else { unreachable!() }
253 );
254
255 #[cfg(not(feature = "safe"))]
256 const ONE: Self = Self(unsafe { [<$p$b>]::new_unchecked(1) });
258 }
259 impl One for [<$name$b>] {
260 #[inline]
261 fn new_one() -> Self {
262 #[cfg(feature = "safe")]
263 return Self([<$p$b>]::new(1).unwrap());
264
265 #[cfg(not(feature = "safe"))]
266 return Self(unsafe { [<$p$b>]::new_unchecked(1) });
268 }
269 }
270
271 impl Number for [<$name$b>] {
274 type InnerRepr = [<NonZeroU$b>];
275 type InnermostRepr = [<u$b>];
276
277 #[doc = "Returns a new `" [<$name$b>] "` from the inner representation."]
278 #[inline]
282 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
283 Ok(Self(value))
284 }
285
286 #[doc = "Returns a new `" [<$name$b>] "` from the inner representation."]
287 #[inline]
291 #[cfg(not(feature = "safe"))]
292 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
293 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
294 Self(value)
295 }
296
297 #[doc = "Returns a new `" [<$name$b>] "` from the innermost representation."]
298 #[inline]
302 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
303 Ok(Self([<$p$b>]::new(value).ok_or(IntegerErrors::Zero)?))
304 }
305
306 #[doc = "Returns a new `" [<$name$b>] "` from the innermost representation."]
307 #[inline]
314 #[cfg(not(feature = "safe"))]
315 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
316 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
317 debug_assert![value != 0];
318 Self([<$p$b>]::new_unchecked(value))
319 }
320
321 #[inline]
322 fn into_inner_repr(self) -> Self::InnerRepr { self.0 }
323
324 #[inline]
325 fn into_innermost_repr(self) -> Self::InnermostRepr { self.0.get() }
326 }
327 }};
328}
329
330define_positive_integer_sized![multi PositiveInteger, Pz, NonZeroU,
333 "positive integer number", ", from the set $\\Z^+$ ($\\N _1$)",
334 "", MIN, MAX,
336 ("An", 8, larger: true, 16, smaller: false, 8),
337 ("A", 16, larger: true, 32, smaller: true, 8),
338 ("A", 32, larger: true, 64, smaller: true, 16),
339 ("A", 64, larger: true, 128, smaller: true, 32),
340 ("A", 128, larger: false, 128, smaller: true, 64)
341];