arbitrary_int/unsigned.rs
1use crate::common::{
2 bytes_operation_impl, from_arbitrary_int_impl, from_native_impl, impl_borsh, impl_extract,
3 impl_num_traits, impl_schemars, impl_step, impl_sum_product,
4};
5use crate::traits::{sealed::Sealed, BuiltinInteger, Integer, UnsignedInteger};
6use crate::TryNewError;
7use core::fmt::{Binary, Debug, Display, Formatter, LowerHex, Octal, UpperHex};
8use core::ops::{
9 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
10 Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
11};
12
13macro_rules! impl_integer_native {
14 // `$const_keyword` is marked as an optional fragment here so that it can conditionally be put on the impl.
15 // This macro will be invoked with `(u8,i8) as const, ...` if `const_convert_and_const_trait_impl` is enabled.
16 ($(($type:ident, $signed_type:ident) $(as $const_keyword:ident)?),+) => {
17 $(
18 #[allow(deprecated)]
19 impl crate::v1_number_compat::Number for $type {
20 type UnderlyingType = $type;
21 }
22
23 impl $($const_keyword)? Sealed for $type {}
24
25 impl $($const_keyword)? BuiltinInteger for $type {}
26
27 impl $($const_keyword)? UnsignedInteger for $type {}
28
29 impl $($const_keyword)? Integer for $type {
30 type UnderlyingType = $type;
31 type UnsignedInteger = $type;
32 type SignedInteger = $signed_type;
33
34 const BITS: usize = Self::BITS as usize;
35 const ZERO: Self = 0;
36 const MIN: Self = Self::MIN;
37 const MAX: Self = Self::MAX;
38
39 #[inline]
40 fn new(value: Self::UnderlyingType) -> Self { value }
41
42 #[inline]
43 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> { Ok(value) }
44
45 #[inline]
46 fn value(self) -> Self::UnderlyingType { self }
47
48 #[cfg(not(feature = "const_convert_and_const_trait_impl"))]
49 #[inline]
50 fn from_<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
51 if T::BITS > Self::BITS as usize {
52 assert!(value <= T::masked_new(Self::MAX));
53 }
54 Self::masked_new(value)
55 }
56
57 #[inline]
58 fn masked_new<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
59 // Primitive types don't need masking
60 match Self::BITS {
61 8 => value.as_u8() as Self,
62 16 => value.as_u16() as Self,
63 32 => value.as_u32() as Self,
64 64 => value.as_u64() as Self,
65 128 => value.as_u128() as Self,
66 _ => panic!("Unhandled Integer type")
67 }
68 }
69
70 #[inline]
71 fn as_u8(self) -> u8 { self as u8 }
72
73 #[inline]
74 fn as_u16(self) -> u16 { self as u16 }
75
76 #[inline]
77 fn as_u32(self) -> u32 { self as u32 }
78
79 #[inline]
80 fn as_u64(self) -> u64 { self as u64 }
81
82 #[inline]
83 fn as_u128(self) -> u128 { self as u128 }
84
85 #[inline]
86 fn as_usize(self) -> usize { self as usize }
87
88 #[inline]
89 fn as_i8(self) -> i8 { self as i8 }
90
91 #[inline]
92 fn as_i16(self) -> i16 { self as i16 }
93
94 #[inline]
95 fn as_i32(self) -> i32 { self as i32 }
96
97 #[inline]
98 fn as_i64(self) -> i64 { self as i64 }
99
100 #[inline]
101 fn as_i128(self) -> i128 { self as i128 }
102
103 #[inline]
104 fn as_isize(self) -> isize { self as isize }
105
106 #[inline]
107 fn to_unsigned(self) -> Self::UnsignedInteger { self }
108
109 #[inline]
110 fn from_unsigned(value: Self::UnsignedInteger) -> Self { value }
111 }
112 )+
113 };
114}
115
116#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
117impl_integer_native!((u8, i8), (u16, i16), (u32, i32), (u64, i64), (u128, i128));
118
119#[cfg(feature = "const_convert_and_const_trait_impl")]
120impl_integer_native!((u8, i8) as const, (u16, i16) as const, (u32, i32) as const, (u64, i64) as const, (u128, i128) as const);
121
122#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
123pub struct UInt<T: UnsignedInteger + BuiltinInteger, const BITS: usize> {
124 value: T,
125}
126
127impl<T: UnsignedInteger + BuiltinInteger, const BITS: usize> UInt<T, BITS> {
128 /// The number of bits in the underlying type that are not present in this type.
129 const UNUSED_BITS: usize = (core::mem::size_of::<T>() << 3) - Self::BITS;
130
131 pub const BITS: usize = BITS;
132
133 /// Returns the type as a fundamental data type
134 #[cfg(not(feature = "hint"))]
135 #[inline]
136 pub const fn value(self) -> T {
137 self.value
138 }
139
140 /// Initializes a new value without checking the bounds
141 ///
142 /// # Safety
143 /// Must only be called with a value less than or equal to [Self::MAX](Self::MAX) value.
144 #[inline]
145 pub const unsafe fn new_unchecked(value: T) -> Self {
146 Self { value }
147 }
148}
149
150impl<T: UnsignedInteger + BuiltinInteger, const BITS: usize> UInt<T, BITS>
151where
152 Self: Integer,
153 T: Copy,
154{
155 pub const MASK: T = Self::MAX.value;
156}
157
158// Next are specific implementations for u8, u16, u32, u64 and u128. A couple notes:
159// - The existence of MAX also serves as a neat bounds-check for BITS: If BITS is too large,
160// the subtraction overflows which will fail to compile. This simplifies things a lot.
161// However, that only works if every constructor also uses MAX somehow (doing let _ = MAX is enough)
162
163macro_rules! uint_impl_num {
164 // `$const_keyword` is marked as an optional fragment here so that it can conditionally be put on the impl.
165 // This macro will be invoked with `(u8, i8) as const, ...` if `const_convert_and_const_trait_impl` is enabled.
166 ($(($type:ident, $signed_type:ident) $(as $const_keyword:ident)?),+) => {
167 $(
168 #[allow(deprecated)]
169 impl<const BITS: usize> crate::v1_number_compat::Number for UInt<$type, BITS> {
170 type UnderlyingType = $type;
171 }
172
173 impl<const BITS: usize> $($const_keyword)? Sealed for UInt<$type, BITS> {}
174
175 impl<const BITS: usize> $($const_keyword)? UnsignedInteger for UInt<$type, BITS> {}
176
177 impl<const BITS: usize> $($const_keyword)? Integer for UInt<$type, BITS> {
178 type UnderlyingType = $type;
179 type SignedInteger = crate::Int<$signed_type, BITS>;
180 type UnsignedInteger = Self;
181
182 const BITS: usize = BITS;
183
184 const ZERO: Self = Self { value: 0 };
185
186 const MIN: Self = Self { value: 0 };
187
188 // The existence of MAX also serves as a bounds check: If NUM_BITS is > available bits,
189 // we will get a compiler error right here
190 const MAX: Self = Self { value: (<$type as Integer>::MAX >> (<$type as Integer>::BITS - Self::BITS)) };
191
192 #[inline]
193 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> {
194 if value <= Self::MAX.value {
195 Ok(Self { value })
196 } else {
197 Err(TryNewError{})
198 }
199 }
200
201 #[inline]
202 fn new(value: $type) -> Self {
203 assert!(value <= Self::MAX.value);
204
205 Self { value }
206 }
207
208 #[cfg(not(feature = "const_convert_and_const_trait_impl"))]
209 #[inline]
210 fn from_<T: Integer>(value: T) -> Self {
211 if Self::BITS < T::BITS {
212 assert!(value <= Self::MAX.value.as_());
213 }
214 Self { value: Self::UnderlyingType::masked_new(value) }
215 }
216
217 fn masked_new<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
218 if Self::BITS < T::BITS {
219 Self { value: Self::UnderlyingType::masked_new(value.as_::<Self::UnderlyingType>() & Self::MASK) }
220 } else {
221 Self { value: Self::UnderlyingType::masked_new(value) }
222 }
223 }
224
225 fn as_u8(self) -> u8 {
226 self.value() as _
227 }
228
229 fn as_u16(self) -> u16 {
230 self.value() as _
231 }
232
233 fn as_u32(self) -> u32 {
234 self.value() as _
235 }
236
237 fn as_u64(self) -> u64 {
238 self.value() as _
239 }
240
241 fn as_u128(self) -> u128 {
242 self.value() as _
243 }
244
245 fn as_usize(self) -> usize {
246 self.value() as _
247 }
248
249 fn as_i8(self) -> i8 {
250 self.value() as _
251 }
252
253 fn as_i16(self) -> i16 {
254 self.value() as _
255 }
256
257 fn as_i32(self) -> i32 {
258 self.value() as _
259 }
260
261 fn as_i64(self) -> i64 {
262 self.value() as _
263 }
264
265 fn as_i128(self) -> i128 {
266 self.value() as _
267 }
268
269 fn as_isize(self) -> isize {
270 self.value() as _
271 }
272
273 #[inline]
274 fn to_unsigned(self) -> Self::UnsignedInteger { self }
275
276 #[inline]
277 fn from_unsigned(value: Self::UnsignedInteger) -> Self { value }
278
279 #[inline]
280 fn value(self) -> $type {
281 #[cfg(feature = "hint")]
282 unsafe {
283 core::hint::assert_unchecked(self.value <= Self::MAX.value);
284 }
285
286 self.value
287 }
288 }
289 )+
290 };
291}
292
293#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
294uint_impl_num!((u8, i8), (u16, i16), (u32, i32), (u64, i64), (u128, i128));
295
296#[cfg(feature = "const_convert_and_const_trait_impl")]
297uint_impl_num!((u8, i8) as const, (u16, i16) as const, (u32, i32) as const, (u64, i64) as const, (u128, i128) as const);
298
299macro_rules! uint_impl {
300 ($(($type:ident, doctest = $doctest_attr:literal)),+) => {
301 $(
302 impl<const BITS: usize> UInt<$type, BITS> {
303 /// Creates an instance. Panics if the given value is outside of the valid range
304 #[inline]
305 pub const fn new(value: $type) -> Self {
306 assert!(value <= Self::MAX.value);
307
308 Self { value }
309 }
310
311 /// Creates an instance. Panics if the given value is outside of the valid range
312 #[inline]
313 pub const fn from_u8(value: u8) -> Self {
314 if Self::BITS < 8 {
315 assert!(value <= Self::MAX.value as u8);
316 }
317 Self { value: value as $type }
318 }
319
320 /// Creates an instance. Panics if the given value is outside of the valid range
321 #[inline]
322 pub const fn from_u16(value: u16) -> Self {
323 if Self::BITS < 16 {
324 assert!(value <= Self::MAX.value as u16);
325 }
326 Self { value: value as $type }
327 }
328
329 /// Creates an instance. Panics if the given value is outside of the valid range
330 #[inline]
331 pub const fn from_u32(value: u32) -> Self {
332 if Self::BITS < 32 {
333 assert!(value <= Self::MAX.value as u32);
334 }
335 Self { value: value as $type }
336 }
337
338 /// Creates an instance. Panics if the given value is outside of the valid range
339 #[inline]
340 pub const fn from_u64(value: u64) -> Self {
341 if Self::BITS < 64 {
342 assert!(value <= Self::MAX.value as u64);
343 }
344 Self { value: value as $type }
345 }
346
347 /// Creates an instance. Panics if the given value is outside of the valid range
348 #[inline]
349 pub const fn from_u128(value: u128) -> Self {
350 if Self::BITS < 128 {
351 assert!(value <= Self::MAX.value as u128);
352 }
353 Self { value: value as $type }
354 }
355
356 /// Creates an instance or an error if the given value is outside of the valid range
357 #[inline]
358 pub const fn try_new(value: $type) -> Result<Self, TryNewError> {
359 if value <= Self::MAX.value {
360 Ok(Self { value })
361 } else {
362 Err(TryNewError {})
363 }
364 }
365
366 /// Returns the type as a fundamental data type
367 #[cfg(feature = "hint")]
368 #[inline]
369 pub const fn value(self) -> $type {
370 // The hint feature requires the type to be const-comparable,
371 // which isn't possible in the generic version above. So we have
372 // an entirely different function if this feature is enabled.
373 // It only works for primitive types, which should be ok in practice
374 // (but is technically an API change)
375 unsafe {
376 core::hint::assert_unchecked(self.value <= Self::MAX.value);
377 }
378 self.value
379 }
380
381 #[deprecated(note = "Use one of the specific functions like extract_u32")]
382 pub const fn extract(value: $type, start_bit: usize) -> Self {
383 assert!(start_bit + BITS <= $type::BITS as usize);
384 // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
385 let _ = Self::MAX;
386
387 Self {
388 value: (value >> start_bit) & Self::MAX.value,
389 }
390 }
391
392 // Generate the `extract_{i,u}{8,16,32,64,128}` functions.
393 impl_extract!(
394 $type,
395 "new((value >> start_bit) & MASK)",
396 |value| value & Self::MASK,
397
398 (8, (u8, extract_u8), (i8, extract_i8)),
399 (16, (u16, extract_u16), (i16, extract_i16)),
400 (32, (u32, extract_u32), (i32, extract_i32)),
401 (64, (u64, extract_u64), (i64, extract_i64)),
402 (128, (u128, extract_u128), (i128, extract_i128))
403 );
404
405 /// Returns a [`UInt`] with a wider bit depth but with the same base data type
406 #[inline]
407 #[must_use = "this returns the result of the operation, without modifying the original"]
408 pub const fn widen<const BITS_RESULT: usize>(
409 self,
410 ) -> UInt<$type, BITS_RESULT> {
411 const { if BITS >= BITS_RESULT {
412 panic!("Can not call widen() with the given bit widths");
413 } };
414
415 // Query MAX of the result to ensure we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
416 let _ = UInt::<$type, BITS_RESULT>::MAX;
417 UInt::<$type, BITS_RESULT> { value: self.value() }
418 }
419
420 /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
421 /// boundary of the type.
422 ///
423 /// # Examples
424 ///
425 /// Basic usage:
426 ///
427 #[doc = concat!(" ```", $doctest_attr)]
428 /// # use arbitrary_int::prelude::*;
429 /// assert_eq!(u14::new(200).wrapping_add(u14::new(55)), u14::new(255));
430 /// assert_eq!(u14::new(200).wrapping_add(u14::MAX), u14::new(199));
431 /// ```
432 #[inline]
433 #[must_use = "this returns the result of the operation, without modifying the original"]
434 pub const fn wrapping_add(self, rhs: Self) -> Self {
435 let sum = self.value().wrapping_add(rhs.value());
436 Self {
437 value: sum & Self::MASK,
438 }
439 }
440
441 /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
442 /// boundary of the type.
443 ///
444 /// # Examples
445 ///
446 /// Basic usage:
447 ///
448 #[doc = concat!(" ```", $doctest_attr)]
449 /// # use arbitrary_int::prelude::*;
450 /// assert_eq!(u14::new(100).wrapping_sub(u14::new(100)), u14::new(0));
451 /// assert_eq!(u14::new(100).wrapping_sub(u14::MAX), u14::new(101));
452 /// ```
453 #[inline]
454 #[must_use = "this returns the result of the operation, without modifying the original"]
455 pub const fn wrapping_sub(self, rhs: Self) -> Self {
456 let sum = self.value().wrapping_sub(rhs.value());
457 Self {
458 value: sum & Self::MASK,
459 }
460 }
461
462 /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at the
463 /// boundary of the type.
464 ///
465 /// # Examples
466 ///
467 /// Basic usage:
468 ///
469 #[doc = concat!(" ```", $doctest_attr)]
470 /// # use arbitrary_int::u7;
471 /// assert_eq!(u7::new(10).wrapping_mul(u7::new(12)), u7::new(120));
472 /// assert_eq!(u7::new(25).wrapping_mul(u7::new(12)), u7::new(44));
473 /// ```
474 #[inline]
475 #[must_use = "this returns the result of the operation, without modifying the original"]
476 pub const fn wrapping_mul(self, rhs: Self) -> Self {
477 let sum = self.value().wrapping_mul(rhs.value());
478 Self {
479 value: sum & Self::MASK,
480 }
481 }
482
483 /// Wrapping (modular) division. Computes `self / rhs`.
484 ///
485 /// Wrapped division on unsigned types is just normal division. There’s no way
486 /// wrapping could ever happen. This function exists so that all operations are
487 /// accounted for in the wrapping operations.
488 ///
489 /// # Panics
490 ///
491 /// This function will panic if `rhs` is zero.
492 ///
493 /// # Examples
494 ///
495 /// Basic usage:
496 ///
497 #[doc = concat!(" ```", $doctest_attr)]
498 /// # use arbitrary_int::u14;
499 /// assert_eq!(u14::new(100).wrapping_div(u14::new(10)), u14::new(10));
500 /// ```
501 #[inline]
502 #[must_use = "this returns the result of the operation, without modifying the original"]
503 pub const fn wrapping_div(self, rhs: Self) -> Self {
504 let sum = self.value().wrapping_div(rhs.value());
505 Self {
506 // No need to mask here - divisions always produce a result that is <= self
507 value: sum,
508 }
509 }
510
511 /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask
512 /// removes any high-order bits of `rhs` that would cause the shift to
513 /// exceed the bitwidth of the type.
514 ///
515 /// Note that this is not the same as a rotate-left; the RHS of a wrapping
516 /// shift-left is restricted to the range of the type, rather than the bits
517 /// shifted out of the LHS being returned to the other end.
518 /// A [`rotate_left`](Self::rotate_left) function exists as well, which may
519 /// be what you want instead.
520 ///
521 /// # Examples
522 ///
523 /// Basic usage:
524 ///
525 #[doc = concat!(" ```", $doctest_attr)]
526 /// # use arbitrary_int::u14;
527 /// assert_eq!(u14::new(1).wrapping_shl(7), u14::new(128));
528 /// assert_eq!(u14::new(1).wrapping_shl(128), u14::new(4));
529 /// ```
530 #[inline]
531 #[must_use = "this returns the result of the operation, without modifying the original"]
532 pub const fn wrapping_shl(self, rhs: u32) -> Self {
533 // modulo is expensive on some platforms, so only do it when necessary
534 let shift_amount = if rhs >= (BITS as u32) {
535 rhs % (BITS as u32)
536 } else {
537 rhs
538 };
539
540 Self {
541 // We could use wrapping_shl here to make Debug builds slightly smaller;
542 // the downside would be that on weird CPUs that don't do wrapping_shl by
543 // default release builds would get slightly worse. Using << should give
544 // good release performance everywere
545 value: (self.value() << shift_amount) & Self::MASK,
546 }
547 }
548
549 /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any
550 /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
551 ///
552 /// Note that this is not the same as a rotate-right; the RHS of a wrapping shift-right is
553 /// restricted to the range of the type, rather than the bits shifted out of the LHS being
554 /// returned to the other end.
555 /// A [`rotate_right`](Self::rotate_right) function exists as well, which may be what you
556 /// want instead.
557 ///
558 /// # Examples
559 ///
560 /// Basic usage:
561 ///
562 #[doc = concat!(" ```", $doctest_attr)]
563 /// # use arbitrary_int::u14;
564 /// assert_eq!(u14::new(128).wrapping_shr(7), u14::new(1));
565 /// assert_eq!(u14::new(128).wrapping_shr(128), u14::new(32));
566 /// ```
567 #[inline]
568 #[must_use = "this returns the result of the operation, without modifying the original"]
569 pub const fn wrapping_shr(self, rhs: u32) -> Self {
570 // modulo is expensive on some platforms, so only do it when necessary
571 let shift_amount = if rhs >= (BITS as u32) {
572 rhs % (BITS as u32)
573 } else {
574 rhs
575 };
576
577 Self {
578 value: (self.value() >> shift_amount),
579 }
580 }
581
582 /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
583 /// bounds instead of overflowing.
584 ///
585 /// # Examples
586 ///
587 /// Basic usage:
588 ///
589 #[doc = concat!(" ```", $doctest_attr)]
590 /// # use arbitrary_int::prelude::*;
591 /// assert_eq!(u14::new(100).saturating_add(u14::new(1)), u14::new(101));
592 /// assert_eq!(u14::MAX.saturating_add(u14::new(100)), u14::MAX);
593 /// ```
594 #[inline]
595 #[must_use = "this returns the result of the operation, without modifying the original"]
596 pub const fn saturating_add(self, rhs: Self) -> Self {
597 let saturated = if Self::UNUSED_BITS == 0 {
598 // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
599 // This is very unlikely to happen in practice, but checking allows us to use
600 // `wrapping_add` instead of `saturating_add` in the common case, which is faster.
601 self.value().saturating_add(rhs.value())
602 } else {
603 // We're dealing with fewer bits than the underlying type (e.g. u7).
604 // That means the addition can never overflow the underlying type
605 let sum = self.value().wrapping_add(rhs.value());
606 let max = Self::MAX.value();
607 if sum > max { max } else { sum }
608 };
609 Self {
610 value: saturated,
611 }
612 }
613
614 /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric
615 /// bounds instead of overflowing.
616 ///
617 /// # Examples
618 ///
619 /// Basic usage:
620 ///
621 #[doc = concat!(" ```", $doctest_attr)]
622 /// # use arbitrary_int::u14;
623 /// assert_eq!(u14::new(100).saturating_sub(u14::new(27)), u14::new(73));
624 /// assert_eq!(u14::new(13).saturating_sub(u14::new(127)), u14::new(0));
625 /// ```
626 #[inline]
627 #[must_use = "this returns the result of the operation, without modifying the original"]
628 pub const fn saturating_sub(self, rhs: Self) -> Self {
629 // For unsigned numbers, the only difference is when we reach 0 - which is the same
630 // no matter the data size
631 Self {
632 value: self.value().saturating_sub(rhs.value()),
633 }
634 }
635
636 /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric
637 /// bounds instead of overflowing.
638 ///
639 /// # Examples
640 ///
641 /// Basic usage:
642 ///
643 #[doc = concat!(" ```", $doctest_attr)]
644 /// # use arbitrary_int::prelude::*;
645 /// assert_eq!(u14::new(2).saturating_mul(u14::new(10)), u14::new(20));
646 /// assert_eq!(u14::MAX.saturating_mul(u14::new(10)), u14::MAX);
647 /// ```
648 #[inline]
649 #[must_use = "this returns the result of the operation, without modifying the original"]
650 pub const fn saturating_mul(self, rhs: Self) -> Self {
651 let product = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
652 // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type
653 // wrapping_mul likely provides the best performance on all cpus
654 self.value().wrapping_mul(rhs.value())
655 } else {
656 // We have more than half the bits (e.g. u6 * u6)
657 self.value().saturating_mul(rhs.value())
658 };
659
660 let max = Self::MAX.value();
661 let saturated = if product > max { max } else { product };
662 Self {
663 value: saturated,
664 }
665 }
666
667 /// Saturating integer division. Computes `self / rhs`, saturating at the numeric
668 /// bounds instead of overflowing.
669 ///
670 /// # Panics
671 ///
672 /// This function will panic if rhs is zero.
673 ///
674 /// # Examples
675 ///
676 /// Basic usage:
677 ///
678 #[doc = concat!(" ```", $doctest_attr)]
679 /// # use arbitrary_int::u14;
680 /// assert_eq!(u14::new(5).saturating_div(u14::new(2)), u14::new(2));
681 /// ```
682 #[inline]
683 #[must_use = "this returns the result of the operation, without modifying the original"]
684 pub const fn saturating_div(self, rhs: Self) -> Self {
685 // When dividing unsigned numbers, we never need to saturate.
686 // Division by zero in saturating_div throws an exception (in debug and release mode),
687 // so no need to do anything special there either
688 Self {
689 value: self.value().saturating_div(rhs.value()),
690 }
691 }
692
693 /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the numeric
694 /// bounds instead of overflowing.
695 ///
696 /// # Examples
697 ///
698 /// Basic usage:
699 ///
700 #[doc = concat!(" ```", $doctest_attr)]
701 /// # use arbitrary_int::prelude::*;
702 /// assert_eq!(u14::new(4).saturating_pow(3), u14::new(64));
703 /// assert_eq!(u14::MAX.saturating_pow(2), u14::MAX);
704 /// ```
705 #[inline]
706 #[must_use = "this returns the result of the operation, without modifying the original"]
707 pub const fn saturating_pow(self, exp: u32) -> Self {
708 // It might be possible to handwrite this to be slightly faster as both
709 // `saturating_pow` has to do a bounds-check and then we do second one.
710 let powed = self.value().saturating_pow(exp);
711 let max = Self::MAX.value();
712 let saturated = if powed > max { max } else { powed };
713 Self {
714 value: saturated,
715 }
716 }
717
718 /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
719 ///
720 /// # Examples
721 ///
722 /// Basic usage:
723 ///
724 #[doc = concat!(" ```", $doctest_attr)]
725 /// # use arbitrary_int::prelude::*;
726 /// assert_eq!((u14::MAX - u14::new(2)).checked_add(u14::new(1)), Some(u14::MAX - u14::new(1)));
727 /// assert_eq!((u14::MAX - u14::new(2)).checked_add(u14::new(3)), None);
728 /// ```
729 #[inline]
730 #[must_use = "this returns the result of the operation, without modifying the original"]
731 pub const fn checked_add(self, rhs: Self) -> Option<Self> {
732 if Self::UNUSED_BITS == 0 {
733 // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
734 // This is very unlikely to happen in practice, but checking allows us to use
735 // `wrapping_add` instead of `checked_add` in the common case, which is faster.
736 match self.value().checked_add(rhs.value()) {
737 Some(value) => Some(Self { value }),
738 None => None
739 }
740 } else {
741 // We're dealing with fewer bits than the underlying type (e.g. u7).
742 // That means the addition can never overflow the underlying type
743 let sum = self.value().wrapping_add(rhs.value());
744 if sum > Self::MAX.value() { None } else { Some(Self { value: sum })}
745 }
746 }
747
748 /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
749 ///
750 /// # Examples
751 ///
752 /// Basic usage:
753 ///
754 #[doc = concat!(" ```", $doctest_attr)]
755 /// # use arbitrary_int::u14;
756 /// assert_eq!(u14::new(1).checked_sub(u14::new(1)), Some(u14::new(0)));
757 /// assert_eq!(u14::new(0).checked_sub(u14::new(1)), None);
758 /// ```
759 #[inline]
760 #[must_use = "this returns the result of the operation, without modifying the original"]
761 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
762 match self.value().checked_sub(rhs.value()) {
763 Some(value) => Some(Self { value }),
764 None => None
765 }
766 }
767
768 /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
769 ///
770 /// # Examples
771 ///
772 /// Basic usage:
773 ///
774 #[doc = concat!(" ```", $doctest_attr)]
775 /// # use arbitrary_int::prelude::*;
776 /// assert_eq!(u14::new(5).checked_mul(u14::new(1)), Some(u14::new(5)));
777 /// assert_eq!(u14::MAX.checked_mul(u14::new(2)), None);
778 /// ```
779 #[inline]
780 #[must_use = "this returns the result of the operation, without modifying the original"]
781 pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
782 let product = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
783 // We have half the bits (e.g. `u4 * u4`) of the base type, so we can't overflow the base type.
784 // `wrapping_mul` likely provides the best performance on all CPUs.
785 Some(self.value().wrapping_mul(rhs.value()))
786 } else {
787 // We have more than half the bits (e.g. u6 * u6)
788 self.value().checked_mul(rhs.value())
789 };
790
791 match product {
792 Some(value) if value <= Self::MAX.value() => Some(Self { value }),
793 _ => None
794 }
795 }
796
797 /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`.
798 ///
799 /// # Examples
800 ///
801 /// Basic usage:
802 ///
803 #[doc = concat!(" ```", $doctest_attr)]
804 /// # use arbitrary_int::u14;
805 /// assert_eq!(u14::new(128).checked_div(u14::new(2)), Some(u14::new(64)));
806 /// assert_eq!(u14::new(1).checked_div(u14::new(0)), None);
807 /// ```
808 #[inline]
809 #[must_use = "this returns the result of the operation, without modifying the original"]
810 pub const fn checked_div(self, rhs: Self) -> Option<Self> {
811 match self.value().checked_div(rhs.value()) {
812 Some(value) => Some(Self { value }),
813 None => None
814 }
815 }
816
817 /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger than
818 /// or equal to the number of bits in `self`.
819 ///
820 /// # Examples
821 ///
822 /// Basic usage:
823 ///
824 #[doc = concat!(" ```", $doctest_attr)]
825 /// # use arbitrary_int::u14;
826 /// assert_eq!(u14::new(0x1).checked_shl(4), Some(u14::new(0x10)));
827 /// assert_eq!(u14::new(0x10).checked_shl(129), None);
828 /// assert_eq!(u14::new(0x10).checked_shl(13), Some(u14::new(0)));
829 /// ```
830 #[inline]
831 #[must_use = "this returns the result of the operation, without modifying the original"]
832 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
833 if rhs >= (BITS as u32) {
834 None
835 } else {
836 Some(Self {
837 value: (self.value() << rhs) & Self::MASK,
838 })
839 }
840 }
841
842 /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than
843 /// or equal to the number of bits in `self`.
844 ///
845 /// # Examples
846 ///
847 /// Basic usage:
848 ///
849 #[doc = concat!(" ```", $doctest_attr)]
850 /// # use arbitrary_int::u14;
851 /// assert_eq!(u14::new(0x10).checked_shr(4), Some(u14::new(0x1)));
852 /// assert_eq!(u14::new(0x10).checked_shr(129), None);
853 /// ```
854 #[inline]
855 #[must_use = "this returns the result of the operation, without modifying the original"]
856 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
857 if rhs >= (BITS as u32) {
858 None
859 } else {
860 Some(Self {
861 value: self.value() >> rhs,
862 })
863 }
864 }
865
866 /// Calculates `self + rhs`.
867 ///
868 /// Returns a tuple of the addition along with a boolean indicating whether an arithmetic
869 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
870 ///
871 /// # Examples
872 ///
873 /// Basic usage:
874 ///
875 #[doc = concat!(" ```", $doctest_attr)]
876 /// # use arbitrary_int::prelude::*;
877 /// assert_eq!(u14::new(5).overflowing_add(u14::new(2)), (u14::new(7), false));
878 /// assert_eq!(u14::MAX.overflowing_add(u14::new(1)), (u14::new(0), true));
879 /// ```
880 #[inline]
881 #[must_use = "this returns the result of the operation, without modifying the original"]
882 pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
883 let (value, overflow) = if Self::UNUSED_BITS == 0 {
884 // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
885 // This is very unlikely to happen in practice, but checking allows us to use
886 // `wrapping_add` instead of `overflowing_add` in the common case, which is faster.
887 self.value().overflowing_add(rhs.value())
888 } else {
889 // We're dealing with fewer bits than the underlying type (e.g. u7).
890 // That means the addition can never overflow the underlying type
891 let sum = self.value().wrapping_add(rhs.value());
892 let masked = sum & Self::MASK;
893 (masked, masked != sum)
894 };
895
896 (Self { value }, overflow)
897 }
898
899 /// Calculates `self - rhs`.
900 ///
901 /// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic
902 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
903 ///
904 /// # Examples
905 ///
906 /// Basic usage:
907 ///
908 #[doc = concat!(" ```", $doctest_attr)]
909 /// # use arbitrary_int::prelude::*;
910 /// assert_eq!(u14::new(5).overflowing_sub(u14::new(2)), (u14::new(3), false));
911 /// assert_eq!(u14::new(0).overflowing_sub(u14::new(1)), (u14::MAX, true));
912 /// ```
913 #[inline]
914 #[must_use = "this returns the result of the operation, without modifying the original"]
915 pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
916 // For unsigned numbers, the only difference is when we reach 0 - which is the same
917 // no matter the data size. In the case of overflow we do have the mask the result though
918 let (value, overflow) = self.value().overflowing_sub(rhs.value());
919 (Self { value: value & Self::MASK }, overflow)
920 }
921
922 /// Calculates the multiplication of `self` and `rhs`.
923 ///
924 /// Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic
925 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
926 ///
927 /// # Examples
928 ///
929 /// Basic usage:
930 ///
931 #[doc = concat!(" ```", $doctest_attr)]
932 /// # use arbitrary_int::prelude::*;
933 /// assert_eq!(u14::new(5).overflowing_mul(u14::new(2)), (u14::new(10), false));
934 /// assert_eq!(u14::new(1_000).overflowing_mul(u14::new(1000)), (u14::new(576), true));
935 /// ```
936 #[inline]
937 #[must_use = "this returns the result of the operation, without modifying the original"]
938 pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
939 let (wrapping_product, overflow) = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
940 // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type.
941 // `wrapping_mul` likely provides the best performance on all CPUs.
942 (self.value().wrapping_mul(rhs.value()), false)
943 } else {
944 // We have more than half the bits (e.g. u6 * u6)
945 self.value().overflowing_mul(rhs.value())
946 };
947
948 let masked = wrapping_product & Self::MASK;
949 let overflow2 = masked != wrapping_product;
950 (Self { value: masked }, overflow || overflow2)
951 }
952
953 /// Calculates the divisor when `self` is divided by `rhs`.
954 ///
955 /// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic
956 /// overflow would occur. Note that for unsigned integers overflow never occurs, so the
957 /// second value is always false.
958 ///
959 /// # Panics
960 ///
961 /// This function will panic if `rhs` is `zero`.
962 ///
963 /// # Examples
964 ///
965 /// Basic usage:
966 ///
967 #[doc = concat!(" ```", $doctest_attr)]
968 /// # use arbitrary_int::prelude::*;
969 /// assert_eq!(u14::new(5).overflowing_div(u14::new(2)), (u14::new(2), false));
970 /// ```
971 #[inline]
972 #[must_use = "this returns the result of the operation, without modifying the original"]
973 pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
974 let value = self.value().wrapping_div(rhs.value());
975 (Self { value }, false)
976 }
977
978 /// Shifts `self` left by `rhs` bits.
979 ///
980 /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
981 /// the shift value was larger than or equal to the number of bits. If the shift value is too
982 /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
983 /// used to perform the shift.
984 ///
985 /// # Examples
986 ///
987 /// Basic usage:
988 ///
989 #[doc = concat!(" ```", $doctest_attr)]
990 /// # use arbitrary_int::prelude::*;
991 /// assert_eq!(u14::new(0x1).overflowing_shl(4), (u14::new(0x10), false));
992 /// assert_eq!(u14::new(0x1).overflowing_shl(132), (u14::new(0x40), true));
993 /// assert_eq!(u14::new(0x10).overflowing_shl(13), (u14::new(0), false));
994 /// ```
995 #[inline]
996 #[must_use = "this returns the result of the operation, without modifying the original"]
997 pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
998 let (shift, overflow) = if rhs >= (BITS as u32) {
999 (rhs % (BITS as u32), true)
1000 } else {
1001 (rhs, false)
1002 };
1003
1004 // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1005 let value = self.value().wrapping_shl(shift);
1006 (Self { value }, overflow)
1007 }
1008
1009 /// Shifts `self` right by `rhs` bits.
1010 ///
1011 /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
1012 /// the shift value was larger than or equal to the number of bits. If the shift value is too
1013 /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
1014 /// used to perform the shift.
1015 ///
1016 /// # Examples
1017 ///
1018 /// Basic usage:
1019 ///
1020 #[doc = concat!(" ```", $doctest_attr)]
1021 /// # use arbitrary_int::prelude::*;
1022 /// assert_eq!(u14::new(0x10).overflowing_shr(4), (u14::new(0x1), false));
1023 /// assert_eq!(u14::new(0x10).overflowing_shr(113), (u14::new(0x8), true));
1024 /// ```
1025 #[inline]
1026 #[must_use = "this returns the result of the operation, without modifying the original"]
1027 pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
1028 let (shift, overflow) = if rhs >= (BITS as u32) {
1029 (rhs % (BITS as u32), true)
1030 } else {
1031 (rhs, false)
1032 };
1033
1034 // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1035 let value = self.value().wrapping_shr(shift);
1036 (Self { value }, overflow)
1037 }
1038
1039 /// Reverses the order of bits in the integer. The least significant bit becomes the most
1040 /// significant bit, second least-significant bit becomes second most-significant bit, etc.
1041 ///
1042 /// # Examples
1043 ///
1044 /// Basic usage:
1045 ///
1046 #[doc = concat!(" ```", $doctest_attr)]
1047 /// # use arbitrary_int::prelude::*;
1048 /// assert_eq!(u6::new(0b10_1010).reverse_bits(), u6::new(0b01_0101));
1049 /// assert_eq!(u6::new(0), u6::new(0).reverse_bits());
1050 /// ```
1051 #[inline]
1052 #[must_use = "this returns the result of the operation, without modifying the original"]
1053 pub const fn reverse_bits(self) -> Self {
1054 Self { value: self.value().reverse_bits() >> Self::UNUSED_BITS }
1055 }
1056
1057 /// Returns the number of ones in the binary representation of `self`.
1058 ///
1059 /// # Examples
1060 ///
1061 /// Basic usage:
1062 ///
1063 #[doc = concat!(" ```", $doctest_attr)]
1064 /// # use arbitrary_int::prelude::*;
1065 /// let n = u7::new(0b100_1100);
1066 /// assert_eq!(n.count_ones(), 3);
1067 ///
1068 /// let max = u7::MAX;
1069 /// assert_eq!(max.count_ones(), 7);
1070 ///
1071 /// let zero = u7::new(0);
1072 /// assert_eq!(zero.count_ones(), 0);
1073 /// ```
1074 #[inline]
1075 pub const fn count_ones(self) -> u32 {
1076 // The upper bits are zero, so we can ignore them
1077 self.value().count_ones()
1078 }
1079
1080 /// Returns the number of zeros in the binary representation of `self`.
1081 ///
1082 /// # Examples
1083 ///
1084 /// Basic usage:
1085 ///
1086 #[doc = concat!(" ```", $doctest_attr)]
1087 /// # use arbitrary_int::prelude::*;
1088 /// let zero = u7::new(0);
1089 /// assert_eq!(zero.count_zeros(), 7);
1090 ///
1091 /// let max = u7::MAX;
1092 /// assert_eq!(max.count_zeros(), 0);
1093 /// ```
1094 #[inline]
1095 pub const fn count_zeros(self) -> u32 {
1096 // The upper bits are zero, so we can have to subtract them from the result.
1097 // We can avoid a bounds check in debug builds with `wrapping_sub` since this cannot overflow.
1098 self.value().count_zeros().wrapping_sub(Self::UNUSED_BITS as u32)
1099 }
1100
1101 /// Returns the number of leading ones in the binary representation of `self`.
1102 ///
1103 /// # Examples
1104 ///
1105 /// Basic usage:
1106 ///
1107 #[doc = concat!(" ```", $doctest_attr)]
1108 /// # use arbitrary_int::prelude::*;
1109 /// let n = !(u7::MAX >> 2);
1110 /// assert_eq!(n.leading_ones(), 2);
1111 ///
1112 /// let zero = u7::new(0);
1113 /// assert_eq!(zero.leading_ones(), 0);
1114 ///
1115 /// let max = u7::MAX;
1116 /// assert_eq!(max.leading_ones(), 7);
1117 /// ```
1118 #[inline]
1119 pub const fn leading_ones(self) -> u32 {
1120 (self.value() << Self::UNUSED_BITS).leading_ones()
1121 }
1122
1123 /// Returns the number of leading zeros in the binary representation of `self`.
1124 ///
1125 /// # Examples
1126 ///
1127 /// Basic usage:
1128 ///
1129 #[doc = concat!(" ```", $doctest_attr)]
1130 /// # use arbitrary_int::prelude::*;
1131 /// let n = u7::MAX >> 2;
1132 /// assert_eq!(n.leading_zeros(), 2);
1133 ///
1134 /// let zero = u7::new(0);
1135 /// assert_eq!(zero.leading_zeros(), 7);
1136 ///
1137 /// let max = u7::MAX;
1138 /// assert_eq!(max.leading_zeros(), 0);
1139 /// ```
1140 #[inline]
1141 pub const fn leading_zeros(self) -> u32 {
1142 if Self::UNUSED_BITS == 0 {
1143 self.value().leading_zeros()
1144 } else {
1145 // Prevent an all-zero value reporting the underlying type's entire bit width by setting
1146 // the first unused bit to one, causing `leading_zeros()` to ignore the unused bits.
1147 let first_unused_bit_set = const { 1 << (Self::UNUSED_BITS - 1) };
1148 ((self.value() << Self::UNUSED_BITS) | first_unused_bit_set).leading_zeros()
1149 }
1150 }
1151
1152 /// Returns the number of trailing ones in the binary representation of `self`.
1153 ///
1154 /// # Examples
1155 ///
1156 /// Basic usage:
1157 ///
1158 #[doc = concat!(" ```", $doctest_attr)]
1159 /// # use arbitrary_int::prelude::*;
1160 /// let n = u7::new(0b1010111);
1161 /// assert_eq!(n.trailing_ones(), 3);
1162 ///
1163 /// let zero = u7::new(0);
1164 /// assert_eq!(zero.trailing_ones(), 0);
1165 ///
1166 /// let max = u7::MAX;
1167 /// assert_eq!(max.trailing_ones(), 7);
1168 /// ```
1169 #[inline]
1170 pub const fn trailing_ones(self) -> u32 {
1171 self.value().trailing_ones()
1172 }
1173
1174 /// Returns the number of trailing zeros in the binary representation of `self`.
1175 ///
1176 /// # Examples
1177 ///
1178 /// Basic usage:
1179 ///
1180 #[doc = concat!(" ```", $doctest_attr)]
1181 /// # use arbitrary_int::prelude::*;
1182 /// let n = u7::new(0b010_1000);
1183 /// assert_eq!(n.trailing_zeros(), 3);
1184 ///
1185 /// let zero = u7::new(0);
1186 /// assert_eq!(zero.trailing_zeros(), 7);
1187 ///
1188 /// let max = u7::MAX;
1189 /// assert_eq!(max.trailing_zeros(), 0);
1190 /// ```
1191 #[inline]
1192 pub const fn trailing_zeros(self) -> u32 {
1193 // Prevent an all-zeros value reporting the underlying type's entire bit width by setting
1194 // all the unused bits.
1195 (self.value() | !Self::MASK).trailing_zeros()
1196 }
1197
1198 /// Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits
1199 /// to the end of the resulting integer.
1200 ///
1201 /// Please note this isn’t the same operation as the `<<` shifting operator!
1202 ///
1203 /// # Examples
1204 ///
1205 /// Basic usage:
1206 ///
1207 #[doc = concat!(" ```", $doctest_attr)]
1208 /// # use arbitrary_int::prelude::*;
1209 /// let n = u6::new(0b10_1010);
1210 /// let m = u6::new(0b01_0101);
1211 ///
1212 /// assert_eq!(n.rotate_left(1), m);
1213 /// ```
1214 #[inline]
1215 #[must_use = "this returns the result of the operation, without modifying the original"]
1216 pub const fn rotate_left(self, n: u32) -> Self {
1217 let b = BITS as u32;
1218 let n = if n >= b { n % b } else { n };
1219
1220 let moved_bits = (self.value() << n) & Self::MASK;
1221 let truncated_bits = self.value() >> (b - n);
1222 Self { value: moved_bits | truncated_bits }
1223 }
1224
1225 /// Shifts the bits to the right by a specified amount, `n`, wrapping the truncated bits
1226 /// to the beginning of the resulting integer.
1227 ///
1228 /// Please note this isn’t the same operation as the `>>` shifting operator!
1229 ///
1230 /// # Examples
1231 ///
1232 /// Basic usage:
1233 ///
1234 #[doc = concat!(" ```", $doctest_attr)]
1235 /// # use arbitrary_int::prelude::*;
1236 /// let n = u6::new(0b10_1010);
1237 /// let m = u6::new(0b01_0101);
1238 ///
1239 /// assert_eq!(n.rotate_right(1), m);
1240 /// ```
1241 #[inline]
1242 #[must_use = "this returns the result of the operation, without modifying the original"]
1243 pub const fn rotate_right(self, n: u32) -> Self {
1244 let b = BITS as u32;
1245 let n = if n >= b { n % b } else { n };
1246
1247 let moved_bits = self.value() >> n;
1248 let truncated_bits = (self.value() << (b - n)) & Self::MASK;
1249 Self { value: moved_bits | truncated_bits }
1250 }
1251 }
1252 )+
1253 };
1254}
1255
1256// Because the methods within this macro are effectively copy-pasted for each underlying integer type,
1257// each documentation test gets executed five times (once for each underlying type), even though the
1258// tests themselves aren't specific to said underlying type. This severely slows down `cargo test`,
1259// so we ignore them for all but one (arbitrary) underlying type.
1260uint_impl!(
1261 (u8, doctest = "rust"),
1262 (u16, doctest = "ignore"),
1263 (u32, doctest = "ignore"),
1264 (u64, doctest = "ignore"),
1265 (u128, doctest = "ignore")
1266);
1267
1268// Arithmetic implementations
1269impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Add for UInt<T, BITS>
1270where
1271 Self: UnsignedInteger,
1272{
1273 type Output = UInt<T, BITS>;
1274
1275 fn add(self, rhs: Self) -> Self::Output {
1276 let sum = self.value + rhs.value;
1277 #[cfg(debug_assertions)]
1278 if (sum & !Self::MASK) != T::ZERO {
1279 panic!("attempt to add with overflow");
1280 }
1281 Self {
1282 value: sum & Self::MASK,
1283 }
1284 }
1285}
1286
1287impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> AddAssign for UInt<T, BITS>
1288where
1289 Self: UnsignedInteger,
1290{
1291 fn add_assign(&mut self, rhs: Self) {
1292 self.value += rhs.value;
1293 #[cfg(debug_assertions)]
1294 if (self.value & !Self::MASK) != T::ZERO {
1295 panic!("attempt to add with overflow");
1296 }
1297 self.value &= Self::MASK;
1298 }
1299}
1300
1301impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Sub for UInt<T, BITS>
1302where
1303 Self: Integer,
1304{
1305 type Output = UInt<T, BITS>;
1306
1307 fn sub(self, rhs: Self) -> Self::Output {
1308 // No need for extra overflow checking as the regular minus operator already handles it for us
1309 Self {
1310 value: (self.value - rhs.value) & Self::MASK,
1311 }
1312 }
1313}
1314
1315impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> SubAssign for UInt<T, BITS>
1316where
1317 Self: Integer,
1318{
1319 fn sub_assign(&mut self, rhs: Self) {
1320 // No need for extra overflow checking as the regular minus operator already handles it for us
1321 self.value -= rhs.value;
1322 self.value &= Self::MASK;
1323 }
1324}
1325
1326impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Mul for UInt<T, BITS>
1327where
1328 Self: Integer,
1329{
1330 type Output = UInt<T, BITS>;
1331
1332 fn mul(self, rhs: Self) -> Self::Output {
1333 // In debug builds, this will perform two bounds checks: Initial multiplication, followed by
1334 // our bounds check. As wrapping_mul isn't available as a trait bound (in regular Rust), this
1335 // is unavoidable
1336 let product = self.value * rhs.value;
1337 #[cfg(debug_assertions)]
1338 if (product & !Self::MASK) != T::ZERO {
1339 panic!("attempt to multiply with overflow");
1340 }
1341 Self {
1342 value: product & Self::MASK,
1343 }
1344 }
1345}
1346
1347impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> MulAssign for UInt<T, BITS>
1348where
1349 Self: Integer,
1350{
1351 fn mul_assign(&mut self, rhs: Self) {
1352 self.value *= rhs.value;
1353 #[cfg(debug_assertions)]
1354 if (self.value & !Self::MASK) != T::ZERO {
1355 panic!("attempt to multiply with overflow");
1356 }
1357 self.value &= Self::MASK;
1358 }
1359}
1360
1361impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Div for UInt<T, BITS> {
1362 type Output = UInt<T, BITS>;
1363
1364 fn div(self, rhs: Self) -> Self::Output {
1365 // Integer division can only make the value smaller. And as the result is same type as
1366 // Self, there's no need to range-check or mask
1367 Self {
1368 value: self.value / rhs.value,
1369 }
1370 }
1371}
1372
1373impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> DivAssign for UInt<T, BITS> {
1374 fn div_assign(&mut self, rhs: Self) {
1375 self.value /= rhs.value;
1376 }
1377}
1378
1379impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitAnd for UInt<T, BITS> {
1380 type Output = UInt<T, BITS>;
1381
1382 fn bitand(self, rhs: Self) -> Self::Output {
1383 Self {
1384 value: self.value & rhs.value,
1385 }
1386 }
1387}
1388
1389impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitAndAssign for UInt<T, BITS> {
1390 fn bitand_assign(&mut self, rhs: Self) {
1391 self.value &= rhs.value;
1392 }
1393}
1394
1395impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitOr for UInt<T, BITS> {
1396 type Output = UInt<T, BITS>;
1397
1398 fn bitor(self, rhs: Self) -> Self::Output {
1399 Self {
1400 value: self.value | rhs.value,
1401 }
1402 }
1403}
1404
1405impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitOrAssign for UInt<T, BITS> {
1406 fn bitor_assign(&mut self, rhs: Self) {
1407 self.value |= rhs.value;
1408 }
1409}
1410
1411impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitXor for UInt<T, BITS> {
1412 type Output = UInt<T, BITS>;
1413
1414 fn bitxor(self, rhs: Self) -> Self::Output {
1415 Self {
1416 value: self.value ^ rhs.value,
1417 }
1418 }
1419}
1420
1421impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitXorAssign for UInt<T, BITS> {
1422 fn bitxor_assign(&mut self, rhs: Self) {
1423 self.value ^= rhs.value;
1424 }
1425}
1426
1427impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Not for UInt<T, BITS>
1428where
1429 Self: Integer,
1430{
1431 type Output = UInt<T, BITS>;
1432
1433 fn not(self) -> Self::Output {
1434 Self {
1435 value: self.value ^ Self::MASK,
1436 }
1437 }
1438}
1439
1440impl<
1441 T: BuiltinInteger + UnsignedInteger + Shl<TSHIFTBITS, Output = T>,
1442 TSHIFTBITS: TryInto<usize> + Copy,
1443 const BITS: usize,
1444 > Shl<TSHIFTBITS> for UInt<T, BITS>
1445where
1446 Self: Integer,
1447{
1448 type Output = UInt<T, BITS>;
1449
1450 fn shl(self, rhs: TSHIFTBITS) -> Self::Output {
1451 // With debug assertions, the << and >> operators throw an exception if the shift amount
1452 // is larger than the number of bits (in which case the result would always be 0)
1453 #[cfg(debug_assertions)]
1454 if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1455 panic!("attempt to shift left with overflow")
1456 }
1457
1458 Self {
1459 value: (self.value << rhs) & Self::MASK,
1460 }
1461 }
1462}
1463
1464impl<
1465 T: BuiltinInteger + UnsignedInteger + ShlAssign<TSHIFTBITS>,
1466 TSHIFTBITS: TryInto<usize> + Copy,
1467 const BITS: usize,
1468 > ShlAssign<TSHIFTBITS> for UInt<T, BITS>
1469where
1470 Self: Integer,
1471{
1472 fn shl_assign(&mut self, rhs: TSHIFTBITS) {
1473 // With debug assertions, the << and >> operators throw an exception if the shift amount
1474 // is larger than the number of bits (in which case the result would always be 0)
1475 #[cfg(debug_assertions)]
1476 if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1477 panic!("attempt to shift left with overflow")
1478 }
1479 self.value <<= rhs;
1480 self.value &= Self::MASK;
1481 }
1482}
1483
1484impl<
1485 T: BuiltinInteger + UnsignedInteger + Shr<TSHIFTBITS, Output = T>,
1486 TSHIFTBITS: TryInto<usize> + Copy,
1487 const BITS: usize,
1488 > Shr<TSHIFTBITS> for UInt<T, BITS>
1489{
1490 type Output = UInt<T, BITS>;
1491
1492 fn shr(self, rhs: TSHIFTBITS) -> Self::Output {
1493 // With debug assertions, the << and >> operators throw an exception if the shift amount
1494 // is larger than the number of bits (in which case the result would always be 0)
1495 #[cfg(debug_assertions)]
1496 if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1497 panic!("attempt to shift left with overflow")
1498 }
1499 Self {
1500 value: self.value >> rhs,
1501 }
1502 }
1503}
1504
1505impl<
1506 T: BuiltinInteger + UnsignedInteger + ShrAssign<TSHIFTBITS>,
1507 TSHIFTBITS: TryInto<usize> + Copy,
1508 const BITS: usize,
1509 > ShrAssign<TSHIFTBITS> for UInt<T, BITS>
1510{
1511 fn shr_assign(&mut self, rhs: TSHIFTBITS) {
1512 // With debug assertions, the << and >> operators throw an exception if the shift amount
1513 // is larger than the number of bits (in which case the result would always be 0)
1514 #[cfg(debug_assertions)]
1515 if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1516 panic!("attempt to shift left with overflow")
1517 }
1518 self.value >>= rhs;
1519 }
1520}
1521
1522impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Display for UInt<T, BITS> {
1523 #[inline]
1524 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1525 Display::fmt(&self.value, f)
1526 }
1527}
1528
1529impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Debug for UInt<T, BITS> {
1530 #[inline]
1531 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1532 Debug::fmt(&self.value, f)
1533 }
1534}
1535
1536impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> LowerHex for UInt<T, BITS> {
1537 #[inline]
1538 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1539 LowerHex::fmt(&self.value, f)
1540 }
1541}
1542
1543impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> UpperHex for UInt<T, BITS> {
1544 #[inline]
1545 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1546 UpperHex::fmt(&self.value, f)
1547 }
1548}
1549
1550impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Octal for UInt<T, BITS> {
1551 #[inline]
1552 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1553 Octal::fmt(&self.value, f)
1554 }
1555}
1556
1557impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Binary for UInt<T, BITS> {
1558 #[inline]
1559 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1560 Binary::fmt(&self.value, f)
1561 }
1562}
1563
1564#[cfg(feature = "defmt")]
1565impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> defmt::Format for UInt<T, BITS>
1566where
1567 T: defmt::Format,
1568{
1569 #[inline]
1570 fn format(&self, f: defmt::Formatter) {
1571 self.value.format(f)
1572 }
1573}
1574
1575impl_borsh!(UInt, "u", UnsignedInteger);
1576
1577#[cfg(feature = "serde")]
1578impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> serde::Serialize for UInt<T, BITS>
1579where
1580 T: serde::Serialize,
1581{
1582 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1583 self.value.serialize(serializer)
1584 }
1585}
1586
1587// Serde's invalid_value error (https://rust-lang.github.io/hashbrown/serde/de/trait.Error.html#method.invalid_value)
1588// takes an Unexpected (https://rust-lang.github.io/hashbrown/serde/de/enum.Unexpected.html) which only accepts a 64 bit
1589// unsigned integer. This is a problem for us because we want to support 128 bit unsigned integers. To work around this
1590// we define our own error type using the UInt's underlying type which implements Display and then use
1591// serde::de::Error::custom to create an error with our custom type.
1592#[cfg(feature = "serde")]
1593struct InvalidUIntValueError<T: UnsignedInteger> {
1594 value: T::UnderlyingType,
1595}
1596
1597#[cfg(feature = "serde")]
1598impl<T: UnsignedInteger> Display for InvalidUIntValueError<T> {
1599 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1600 write!(
1601 f,
1602 "invalid value: integer `{}`, expected a value between `0` and `{}`",
1603 self.value,
1604 T::MAX.value()
1605 )
1606 }
1607}
1608
1609#[cfg(feature = "serde")]
1610impl<'de, T: BuiltinInteger + UnsignedInteger, const BITS: usize> serde::Deserialize<'de>
1611 for UInt<T, BITS>
1612where
1613 Self: UnsignedInteger<UnderlyingType = T>,
1614 T: serde::Deserialize<'de>,
1615{
1616 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1617 let value = T::deserialize(deserializer)?;
1618
1619 if value <= Self::MAX.value {
1620 Ok(Self { value })
1621 } else {
1622 let err = InvalidUIntValueError::<Self> { value };
1623 Err(serde::de::Error::custom(err))
1624 }
1625 }
1626}
1627
1628// Implement `core::iter::Sum` and `core::iter::Product`.
1629impl_sum_product!(UInt, 1_u8, UnsignedInteger);
1630
1631// Implement support for the `num-traits` crate, if the feature is enabled.
1632impl_num_traits!(UInt, UnsignedInteger, u8, |value| value & Self::MASK);
1633
1634// Implement `core::iter::Step` (if the `step_trait` feature is enabled).
1635impl_step!(UInt, UnsignedInteger);
1636
1637// Implement byte operations for UInt's with a bit width aligned to a byte boundary.
1638
1639// Support for the `schemars` crate, if the feature is enabled.
1640impl_schemars!(UInt, "uint", UnsignedInteger);
1641
1642bytes_operation_impl!(UInt<u32, 24>, u32);
1643bytes_operation_impl!(UInt<u64, 24>, u64);
1644bytes_operation_impl!(UInt<u128, 24>, u128);
1645bytes_operation_impl!(UInt<u64, 40>, u64);
1646bytes_operation_impl!(UInt<u128, 40>, u128);
1647bytes_operation_impl!(UInt<u64, 48>, u64);
1648bytes_operation_impl!(UInt<u128, 48>, u128);
1649bytes_operation_impl!(UInt<u64, 56>, u64);
1650bytes_operation_impl!(UInt<u128, 56>, u128);
1651bytes_operation_impl!(UInt<u128, 72>, u128);
1652bytes_operation_impl!(UInt<u128, 80>, u128);
1653bytes_operation_impl!(UInt<u128, 88>, u128);
1654bytes_operation_impl!(UInt<u128, 96>, u128);
1655bytes_operation_impl!(UInt<u128, 104>, u128);
1656bytes_operation_impl!(UInt<u128, 112>, u128);
1657bytes_operation_impl!(UInt<u128, 120>, u128);
1658
1659// Conversions
1660from_arbitrary_int_impl!(UInt(u8), [u16, u32, u64, u128]);
1661from_arbitrary_int_impl!(UInt(u16), [u8, u32, u64, u128]);
1662from_arbitrary_int_impl!(UInt(u32), [u8, u16, u64, u128]);
1663from_arbitrary_int_impl!(UInt(u64), [u8, u16, u32, u128]);
1664from_arbitrary_int_impl!(UInt(u128), [u8, u32, u64, u16]);
1665
1666from_native_impl!(UInt(u8), [u8, u16, u32, u64, u128]);
1667from_native_impl!(UInt(u16), [u8, u16, u32, u64, u128]);
1668from_native_impl!(UInt(u32), [u8, u16, u32, u64, u128]);
1669from_native_impl!(UInt(u64), [u8, u16, u32, u64, u128]);
1670from_native_impl!(UInt(u128), [u8, u16, u32, u64, u128]);
1671
1672pub use aliases::*;
1673
1674#[allow(non_camel_case_types)]
1675#[rustfmt::skip]
1676pub(crate) mod aliases {
1677 use crate::common::type_alias;
1678
1679 type_alias!(UInt(u8), (u1, 1), (u2, 2), (u3, 3), (u4, 4), (u5, 5), (u6, 6), (u7, 7));
1680 type_alias!(UInt(u16), (u9, 9), (u10, 10), (u11, 11), (u12, 12), (u13, 13), (u14, 14), (u15, 15));
1681 type_alias!(UInt(u32), (u17, 17), (u18, 18), (u19, 19), (u20, 20), (u21, 21), (u22, 22), (u23, 23), (u24, 24), (u25, 25), (u26, 26), (u27, 27), (u28, 28), (u29, 29), (u30, 30), (u31, 31));
1682 type_alias!(UInt(u64), (u33, 33), (u34, 34), (u35, 35), (u36, 36), (u37, 37), (u38, 38), (u39, 39), (u40, 40), (u41, 41), (u42, 42), (u43, 43), (u44, 44), (u45, 45), (u46, 46), (u47, 47), (u48, 48), (u49, 49), (u50, 50), (u51, 51), (u52, 52), (u53, 53), (u54, 54), (u55, 55), (u56, 56), (u57, 57), (u58, 58), (u59, 59), (u60, 60), (u61, 61), (u62, 62), (u63, 63));
1683 type_alias!(UInt(u128), (u65, 65), (u66, 66), (u67, 67), (u68, 68), (u69, 69), (u70, 70), (u71, 71), (u72, 72), (u73, 73), (u74, 74), (u75, 75), (u76, 76), (u77, 77), (u78, 78), (u79, 79), (u80, 80), (u81, 81), (u82, 82), (u83, 83), (u84, 84), (u85, 85), (u86, 86), (u87, 87), (u88, 88), (u89, 89), (u90, 90), (u91, 91), (u92, 92), (u93, 93), (u94, 94), (u95, 95), (u96, 96), (u97, 97), (u98, 98), (u99, 99), (u100, 100), (u101, 101), (u102, 102), (u103, 103), (u104, 104), (u105, 105), (u106, 106), (u107, 107), (u108, 108), (u109, 109), (u110, 110), (u111, 111), (u112, 112), (u113, 113), (u114, 114), (u115, 115), (u116, 116), (u117, 117), (u118, 118), (u119, 119), (u120, 120), (u121, 121), (u122, 122), (u123, 123), (u124, 124), (u125, 125), (u126, 126), (u127, 127));
1684}
1685
1686macro_rules! boolu1 {
1687 ($($const_keyword:ident)?) => {
1688 impl $($const_keyword)? From<bool> for u1 {
1689 #[inline]
1690 fn from(value: bool) -> Self {
1691 u1::new(value as u8)
1692 }
1693 }
1694
1695 impl $($const_keyword)? From<u1> for bool {
1696 #[inline]
1697 fn from(value: u1) -> Self {
1698 match value.value() {
1699 0 => false,
1700 1 => true,
1701 _ => unreachable!(), // TODO: unreachable!() is not const yet
1702 }
1703 }
1704 }
1705 };
1706}
1707
1708#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
1709boolu1!();
1710
1711#[cfg(feature = "const_convert_and_const_trait_impl")]
1712boolu1!(const);