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