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