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