arbitrary_int/signed.rs
1use crate::{
2 common::{
3 bytes_operation_impl, from_arbitrary_int_impl, from_native_impl, impl_bin_proto,
4 impl_extract, impl_num_traits, impl_schemars, impl_step, impl_sum_product,
5 },
6 traits::{sealed::Sealed, BuiltinInteger, Integer, SignedInteger},
7 TryNewError,
8};
9use core::fmt::{Binary, Debug, Display, Formatter, LowerHex, Octal, UpperHex};
10use core::ops::{
11 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
12 Mul, MulAssign, Neg, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
13};
14
15macro_rules! impl_signed_integer_native {
16 ($(($type:ident, $unsigned_type:ident)),+) => {
17 $(
18 impl Sealed for $type {}
19
20 impl SignedInteger for $type {}
21
22 impl BuiltinInteger for $type {}
23
24 impl Integer for $type {
25 type UnderlyingType = $type;
26 type UnsignedInteger = $unsigned_type;
27 type SignedInteger = $type;
28
29 const BITS: usize = Self::BITS as usize;
30 const ZERO: Self = 0;
31 const MIN: Self = Self::MIN;
32 const MAX: Self = Self::MAX;
33 const IS_SIGNED: bool = true;
34
35 #[inline]
36 fn new(value: Self::UnderlyingType) -> Self { value }
37
38 #[inline]
39 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> { Ok(value) }
40
41 #[inline]
42 fn value(self) -> Self::UnderlyingType { self }
43
44 #[inline]
45 fn from_<T: Integer>(value: T) -> Self {
46 if T::IS_SIGNED {
47 if (Self::BITS as usize) < T::BITS {
48 assert!(value >= T::masked_new(Self::MIN) && value <= T::masked_new(Self::MAX));
49 }
50 } else {
51 if (Self::BITS as usize) <= T::BITS {
52 assert!(value <= T::masked_new(Self::MAX));
53 }
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_i8() as Self,
63 16 => value.as_i16() as Self,
64 32 => value.as_i32() as Self,
65 64 => value.as_i64() as Self,
66 128 => value.as_i128() 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 as Self::UnsignedInteger }
109
110 #[inline]
111 fn from_unsigned(value: Self::UnsignedInteger) -> Self { value as Self }
112 }
113 )+
114 };
115}
116
117impl_signed_integer_native!((i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128));
118
119/// A signed integer of arbitrary bit length.
120///
121/// # In-Memory Representation
122/// The specific in-memory representation that would be seen by calling [`core::mem::transmute`] is unspecified.
123/// but satisfies the following guarantees:
124/// - An `Int<T, BITS>` has the same size/alignment as `T`
125/// - An `Int` has no uninitialized bytes or padding (satisfies [`bytemuck::NoUninit`]).
126/// - If the value of a `Int<T, BITS>` is non-negative,
127/// then it will the same representation as `UInt<T, BITS>`
128///
129/// When `cfg(feature = "bytemuck")` is enabled, the appropriate traits are implemented
130/// based on the above guarantees.
131/// It is not possible to implement [`bytemuck::Contiguous`] because that would be
132/// incompatible with a zero-extended memory representation.
133///
134/// Since the underlying representation is unspecified, it may change in a patch version
135/// without being considered a breaking change.
136///
137/// [`bytemuck::NoUninit`]: https://docs.rs/bytemuck/1/bytemuck/trait.NoUninit.html
138/// [`bytemuck::Contiguous`]: https://docs.rs/bytemuck/1/bytemuck/trait.Contiguous.html
139#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
140#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
141#[cfg_attr(feature = "bytecheck", bytecheck(verify))]
142#[cfg_attr(
143 feature = "rkyv",
144 derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize),
145 rkyv(bytecheck(verify))
146)]
147#[repr(transparent)]
148pub struct Int<T: SignedInteger + BuiltinInteger, const BITS: usize> {
149 value: T,
150}
151
152impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Int<T, BITS> {
153 /// The number of bits in the underlying type that are not present in this type.
154 const UNUSED_BITS: usize = (core::mem::size_of::<T>() << 3) - Self::BITS;
155
156 pub const BITS: usize = BITS;
157
158 /// Returns the type as a fundamental data type.
159 ///
160 /// Note that if negative, the returned value may span more bits than [`BITS`](Self::BITS),
161 /// as it preserves the numeric value instead of the bitwise value:
162 ///
163 /// ```
164 /// # use arbitrary_int::i3;
165 /// let value: i8 = i3::new(-1).value();
166 /// assert_eq!(value, -1);
167 /// assert_eq!(value.count_ones(), 8);
168 /// ```
169 ///
170 /// If you need a value within the specified bit range, use [`Self::to_bits`].
171 #[cfg(not(feature = "hint"))]
172 #[inline]
173 pub const fn value(self) -> T {
174 self.value
175 }
176
177 /// Initializes a new value without checking the bounds
178 ///
179 /// # Safety
180 ///
181 /// Must only be called with a value bigger or equal to [`Self::MIN`] and less than or equal to [`Self::MAX`].
182 #[inline]
183 pub const unsafe fn new_unchecked(value: T) -> Self {
184 Self { value }
185 }
186}
187
188macro_rules! int_impl_num {
189 ($(($type:ident, $unsigned_type:ident)),+) => {
190 $(
191 impl<const BITS: usize> Sealed for Int<$type, BITS> {}
192
193 impl<const BITS: usize> SignedInteger for Int<$type, BITS> {}
194
195 impl<const BITS: usize> Integer for Int<$type, BITS> {
196 type UnderlyingType = $type;
197 type SignedInteger = Self;
198 type UnsignedInteger = crate::UInt<$unsigned_type, BITS>;
199
200 const BITS: usize = BITS;
201
202 const ZERO: Self = Self { value: 0 };
203
204 const MIN: Self = Self { value: -Self::MAX.value - 1 };
205
206 // The existence of MAX also serves as a bounds check: If NUM_BITS is > available bits,
207 // we will get a compiler error right here
208 const MAX: Self = Self {
209 // MAX is always positive so we don't have to worry about the sign
210 value: (<$type as Integer>::MAX >> (<$type as Integer>::BITS - Self::BITS)),
211 };
212
213 const IS_SIGNED: bool = true;
214
215 #[inline]
216 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> {
217 if value >= Self::MIN.value && value <= Self::MAX.value {
218 Ok(Self { value })
219 } else {
220 Err(TryNewError{})
221 }
222 }
223
224 #[inline]
225 fn new(value: $type) -> Self {
226 assert!(value >= Self::MIN.value && value <= Self::MAX.value);
227
228 Self { value }
229 }
230
231 #[inline]
232 fn from_<T: Integer>(value: T) -> Self {
233 if T::IS_SIGNED {
234 if Self::BITS < T::BITS {
235 assert!(value >= Self::MIN.value.as_() && value <= Self::MAX.value.as_());
236 }
237 } else {
238 if Self::BITS <= T::BITS {
239 assert!(value <= Self::MAX.value.as_());
240 }
241 }
242 Self { value: Self::UnderlyingType::masked_new(value) }
243 }
244
245 fn masked_new<T: Integer>(value: T) -> Self {
246 // If the source type is wider, we need to mask and sign-extend. If the source
247 // type is the same width but unsigned, we also need to sign-extend!
248 if Self::BITS < T::BITS || (Self::BITS == T::BITS && !T::IS_SIGNED) {
249 let value = (value.as_::<Self::UnderlyingType>() << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
250 Self { value: Self::UnderlyingType::masked_new(value) }
251 } else {
252 Self { value: Self::UnderlyingType::masked_new(value) }
253 }
254 }
255
256 fn as_u8(self) -> u8 {
257 self.value() as _
258 }
259
260 fn as_u16(self) -> u16 {
261 self.value() as _
262 }
263
264 fn as_u32(self) -> u32 {
265 self.value() as _
266 }
267
268 fn as_u64(self) -> u64 {
269 self.value() as _
270 }
271
272 fn as_u128(self) -> u128 {
273 self.value() as _
274 }
275
276 fn as_usize(self) -> usize {
277 self.value() as _
278 }
279
280 fn as_i8(self) -> i8 {
281 self.value() as _
282 }
283
284 fn as_i16(self) -> i16 {
285 self.value() as _
286 }
287
288 fn as_i32(self) -> i32 {
289 self.value() as _
290 }
291
292 fn as_i64(self) -> i64 {
293 self.value() as _
294 }
295
296 fn as_i128(self) -> i128 {
297 self.value() as _
298 }
299
300 fn as_isize(self) -> isize {
301 self.value() as _
302 }
303
304 #[inline]
305 fn to_unsigned(self) -> Self::UnsignedInteger { Self::UnsignedInteger::masked_new(self.value as $unsigned_type) }
306
307 #[inline]
308 fn from_unsigned(value: Self::UnsignedInteger) -> Self {
309 Self::masked_new(value.value() as $type)
310 }
311
312
313 #[inline]
314 fn value(self) -> $type {
315 #[cfg(feature = "hint")]
316 unsafe {
317 core::hint::assert_unchecked(self.value >= Self::MIN.value);
318 core::hint::assert_unchecked(self.value <= Self::MAX.value);
319 }
320
321 self.value
322 }
323 }
324 )+
325 };
326}
327
328int_impl_num!((i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128));
329
330macro_rules! int_impl {
331 ($(($type:ident, $unsigned_type:ident, doctest = $doctest_attr:literal)),+) => {
332 $(
333 impl<const BITS: usize> Int<$type, BITS> {
334 pub const MASK: $type = (Self::MAX.value << 1) | 1;
335
336 /// Creates an instance. Panics if the given value is outside of the valid range
337 #[inline]
338 pub const fn new(value: $type) -> Self {
339 assert!(value >= Self::MIN.value && value <= Self::MAX.value);
340
341 Self { value }
342 }
343
344 /// Creates an instance. Panics if the given value is outside of the valid range
345 #[inline]
346 pub const fn from_i8(value: i8) -> Self {
347 if Self::BITS < 8 {
348 assert!(value >= Self::MIN.value as i8 && value <= Self::MAX.value as i8);
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_i16(value: i16) -> Self {
356 if Self::BITS < 16 {
357 assert!(value >= Self::MIN.value as i16 && value <= Self::MAX.value as i16);
358 }
359 Self { value: value as $type }
360 }
361
362 /// Creates an instance. Panics if the given value is outside of the valid range
363 #[inline]
364 pub const fn from_i32(value: i32) -> Self {
365 if Self::BITS < 32 {
366 assert!(value >= Self::MIN.value as i32 && value <= Self::MAX.value as i32);
367 }
368 Self { value: value as $type }
369 }
370
371 /// Creates an instance. Panics if the given value is outside of the valid range
372 #[inline]
373 pub const fn from_i64(value: i64) -> Self {
374 if Self::BITS < 64 {
375 assert!(value >= Self::MIN.value as i64 && value <= Self::MAX.value as i64);
376 }
377 Self { value: value as $type }
378 }
379
380 /// Creates an instance. Panics if the given value is outside of the valid range
381 #[inline]
382 pub const fn from_i128(value: i128) -> Self {
383 if Self::BITS < 128 {
384 assert!(value >= Self::MIN.value as i128 && value <= Self::MAX.value as i128);
385 }
386 Self { value: value as $type }
387 }
388
389 /// Creates an instance or an error if the given value is outside of the valid range
390 #[inline]
391 pub const fn try_new(value: $type) -> Result<Self, TryNewError> {
392 if value >= Self::MIN.value && value <= Self::MAX.value {
393 Ok(Self { value })
394 } else {
395 Err(TryNewError {})
396 }
397 }
398
399 /// Returns the bitwise representation of the value.
400 ///
401 /// As the bit width is limited to [`BITS`](Self::BITS) the numeric value may differ from [`value`](Self::value).
402 ///
403 #[doc = concat!(" ```", $doctest_attr)]
404 /// # use arbitrary_int::i3;
405 /// let value = i3::new(-1);
406 /// assert_eq!(value.to_bits(), 0b111); // 7
407 /// assert_eq!(value.value(), -1);
408 /// ```
409 ///
410 /// To convert from the bitwise representation back to an instance, use [`from_bits`](Self::from_bits).
411 #[inline]
412 #[must_use = "this returns the result of the operation, without modifying the original"]
413 pub const fn to_bits(self) -> $unsigned_type {
414 (self.value() & Self::MASK) as $unsigned_type
415 }
416
417 /// Convert the bitwise representation from [`to_bits`](Self::to_bits) to an instance.
418 ///
419 #[doc = concat!(" ```", $doctest_attr)]
420 /// # use arbitrary_int::i3;
421 /// let value = i3::from_bits(0b111);
422 /// assert_eq!(value.value(), -1);
423 /// assert_eq!(value.to_bits(), 0b111);
424 /// ```
425 ///
426 /// If you want to convert a numeric value to an instance instead, use [`new`](Self::new).
427 ///
428 /// # Panics
429 ///
430 /// Panics if the given value exceeds the bit width specified by [`BITS`](Self::BITS).
431 #[inline]
432 pub const fn from_bits(value: $unsigned_type) -> Self {
433 assert!(value & (!Self::MASK as $unsigned_type) == 0);
434
435 // First do a logical left shift to put the sign bit at the underlying type's MSB (copying the sign),
436 // then an arithmetic right shift to sign-extend the value into its original position.
437 Self { value: ((value << Self::UNUSED_BITS) as $type) >> Self::UNUSED_BITS }
438 }
439
440 /// Tries to convert the bitwise representation from [`to_bits`](Self::to_bits) to an instance.
441 ///
442 #[doc = concat!(" ```", $doctest_attr)]
443 /// # use arbitrary_int::i3;
444 /// i3::try_from_bits(0b1111).expect_err("value is > 3 bits");
445 /// let value = i3::try_from_bits(0b111).expect("value is <= 3 bits");
446 /// assert_eq!(value.value(), -1);
447 /// assert_eq!(value.to_bits(), 0b111);
448 /// ```
449 ///
450 /// If you want to convert a numeric value to an instance instead, use [`try_new`](Self::try_new).
451 ///
452 /// # Errors
453 ///
454 /// Returns an error if the given value exceeds the bit width specified by [`BITS`](Self::BITS).
455 #[inline]
456 pub const fn try_from_bits(value: $unsigned_type) -> Result<Self, TryNewError> {
457 if value & (!Self::MASK as $unsigned_type) == 0 {
458 // First do a logical left shift to put the sign bit at the underlying type's MSB (copying the sign),
459 // then an arithmetic right shift to sign-extend the value into its original position.
460 Ok(Self { value: ((value << Self::UNUSED_BITS) as $type) >> Self::UNUSED_BITS })
461 } else {
462 Err(TryNewError {})
463 }
464 }
465
466 /// Converts the bitwise representation from [`to_bits`](Self::to_bits) to an instance,
467 /// without checking the bounds.
468 ///
469 /// # Safety
470 ///
471 /// The given value must not exceed the bit width specified by [`Self::BITS`].
472 #[inline]
473 pub const unsafe fn from_bits_unchecked(value: $unsigned_type) -> Self {
474 // First do a logical left shift to put the sign bit at the underlying type's MSB (copying the sign),
475 // then an arithmetic right shift to sign-extend the value into its original position.
476 Self { value: ((value << Self::UNUSED_BITS) as $type) >> Self::UNUSED_BITS }
477 }
478
479 /// Returns the type as a fundamental data type.
480 ///
481 /// Note that if negative, the returned value may span more bits than [`BITS`](Self::BITS)
482 /// as it preserves the numeric value instead of the bitwise value:
483 ///
484 #[doc = concat!(" ```", $doctest_attr)]
485 /// # use arbitrary_int::i3;
486 /// let value: i8 = i3::new(-1).value();
487 /// assert_eq!(value, -1);
488 /// assert_eq!(value.count_ones(), 8);
489 /// ```
490 ///
491 /// If you need a value within the specified bit range, use [`to_bits`](Self::to_bits).
492 #[cfg(feature = "hint")]
493 #[inline]
494 pub const fn value(self) -> $type {
495 // The hint feature requires the type to be const-comparable,
496 // which isn't possible in the generic version above. So we have
497 // an entirely different function if this feature is enabled.
498 // It only works for primitive types, which should be ok in practice
499 // (but is technically an API change)
500 unsafe {
501 core::hint::assert_unchecked(self.value >= Self::MIN.value);
502 core::hint::assert_unchecked(self.value <= Self::MAX.value);
503 }
504 self.value
505 }
506
507 // Generate the `extract_{i,u}{8,16,32,64,128}` functions.
508 impl_extract!(
509 $type,
510 "from_bits(value >> start_bit)",
511 |value| (value << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
512
513 (8, (i8, extract_i8), (u8, extract_u8)),
514 (16, (i16, extract_i16), (u16, extract_u16)),
515 (32, (i32, extract_i32), (u32, extract_u32)),
516 (64, (i64, extract_i64), (u64, extract_u64)),
517 (128, (i128, extract_i128), (u128, extract_u128))
518 );
519
520 /// Returns an [`Int`] with a wider bit depth but with the same base data type
521 #[inline]
522 #[must_use = "this returns the result of the operation, without modifying the original"]
523 pub const fn widen<const BITS_RESULT: usize>(self) -> Int<$type, BITS_RESULT> {
524 const { assert!(BITS < BITS_RESULT, "Can not call widen() with the given bit widths") };
525
526 // Query MAX of the result to ensure we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
527 let _ = Int::<$type, BITS_RESULT>::MAX;
528 Int::<$type, BITS_RESULT> { value: self.value }
529 }
530
531 /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
532 /// boundary of the type.
533 ///
534 /// # Examples
535 ///
536 /// Basic usage:
537 ///
538 #[doc = concat!(" ```", $doctest_attr)]
539 /// # use arbitrary_int::prelude::*;
540 /// assert_eq!(i14::new(100).wrapping_add(i14::new(27)), i14::new(127));
541 /// assert_eq!(i14::MAX.wrapping_add(i14::new(2)), i14::MIN + i14::new(1));
542 /// ```
543 #[inline]
544 #[must_use = "this returns the result of the operation, without modifying the original"]
545 pub const fn wrapping_add(self, rhs: Self) -> Self {
546 let sum = self.value().wrapping_add(rhs.value());
547 Self {
548 value: (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
549 }
550 }
551
552 /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
553 /// boundary of the type.
554 ///
555 /// # Examples
556 ///
557 /// Basic usage:
558 ///
559 #[doc = concat!(" ```", $doctest_attr)]
560 /// # use arbitrary_int::prelude::*;
561 /// assert_eq!(i14::new(0).wrapping_sub(i14::new(127)), i14::new(-127));
562 /// assert_eq!(i14::new(-2).wrapping_sub(i14::MAX), i14::MAX);
563 /// ```
564 #[inline]
565 #[must_use = "this returns the result of the operation, without modifying the original"]
566 pub const fn wrapping_sub(self, rhs: Self) -> Self {
567 let sum = self.value().wrapping_sub(rhs.value());
568 Self {
569 value: (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
570 }
571 }
572
573 /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at the
574 /// boundary of the type.
575 ///
576 /// # Examples
577 ///
578 /// Basic usage:
579 ///
580 #[doc = concat!(" ```", $doctest_attr)]
581 /// # use arbitrary_int::prelude::*;
582 /// assert_eq!(i14::new(10).wrapping_mul(i14::new(12)), i14::new(120));
583 /// assert_eq!(i14::new(12).wrapping_mul(i14::new(1024)), i14::new(-4096));
584 /// ```
585 #[inline]
586 #[must_use = "this returns the result of the operation, without modifying the original"]
587 pub const fn wrapping_mul(self, rhs: Self) -> Self {
588 let sum = self.value().wrapping_mul(rhs.value());
589 Self {
590 value: (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
591 }
592 }
593
594 /// Wrapping (modular) division. Computes `self / rhs`, wrapping around at the
595 /// boundary of the type.
596 ///
597 /// The only case where such wrapping can occur is when one divides `MIN / -1` on a
598 /// signed type (where `MIN` is the negative minimal value for the type); this is
599 /// equivalent to `-MIN`, a positive value that is too large to represent in the type.
600 /// In such a case, this function returns `MIN` itself.
601 ///
602 /// # Panics
603 ///
604 /// This function will panic if `rhs` is zero.
605 ///
606 /// # Examples
607 ///
608 /// Basic usage:
609 ///
610 #[doc = concat!(" ```", $doctest_attr)]
611 /// # use arbitrary_int::prelude::*;
612 /// assert_eq!(i14::new(100).wrapping_div(i14::new(10)), i14::new(10));
613 /// assert_eq!(i14::MIN.wrapping_div(i14::new(-1)), i14::MIN);
614 /// ```
615 #[inline]
616 #[must_use = "this returns the result of the operation, without modifying the original"]
617 pub const fn wrapping_div(self, rhs: Self) -> Self {
618 let sum = self.value().wrapping_div(rhs.value());
619 Self {
620 // Unlike the unsigned implementation we do need to account for overflow here,
621 // `Self::MIN / -1` is equal to `Self::MAX + 1`.
622 value: (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
623 }
624 }
625
626 /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary of the type.
627 ///
628 /// The only case where such wrapping can occur is when one negates `MIN` on a signed type
629 /// (where `MIN` is the negative minimal value for the type); this is a positive value that is
630 /// too large to represent in the type. In such a case, this function returns `MIN` itself.
631 ///
632 /// # Examples
633 ///
634 /// Basic usage:
635 ///
636 #[doc = concat!(" ```", $doctest_attr)]
637 /// # use arbitrary_int::prelude::*;
638 /// assert_eq!(i14::new(100).wrapping_neg(), i14::new(-100));
639 /// assert_eq!(i14::new(-100).wrapping_neg(), i14::new(100));
640 /// assert_eq!(i14::MIN.wrapping_neg(), i14::MIN);
641 /// ```
642 #[inline]
643 #[must_use = "this returns the result of the operation, without modifying the original"]
644 pub const fn wrapping_neg(self) -> Self {
645 let value = (self.value().wrapping_neg() << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
646 Self { value }
647 }
648
649 /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask removes any
650 /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
651 ///
652 /// Note that this is not the same as a rotate-left; the RHS of a wrapping shift-left is
653 /// restricted to the range of the type, rather than the bits shifted out of the LHS being
654 /// returned to the other end.
655 /// A [`rotate_left`](Self::rotate_left) function exists as well, which may be what you
656 /// want instead.
657 ///
658 /// # Examples
659 ///
660 /// Basic usage:
661 ///
662 #[doc = concat!(" ```", $doctest_attr)]
663 /// # use arbitrary_int::prelude::*;
664 /// assert_eq!(i14::new(-1).wrapping_shl(7), i14::new(-128));
665 /// assert_eq!(i14::new(-1).wrapping_shl(128), i14::new(-4));
666 /// ```
667 #[inline]
668 #[must_use = "this returns the result of the operation, without modifying the original"]
669 pub const fn wrapping_shl(self, rhs: u32) -> Self {
670 // modulo is expensive on some platforms, so only do it when necessary
671 let shift_amount = Self::UNUSED_BITS as u32 + (if rhs >= BITS as u32 {
672 rhs % (BITS as u32)
673 } else {
674 rhs
675 });
676
677 Self {
678 // We could use wrapping_shl here to make Debug builds slightly smaller;
679 // the downside would be that on weird CPUs that don't do wrapping_shl by
680 // default release builds would get slightly worse. Using << should give
681 // good release performance everywere
682 value: (self.value() << shift_amount) >> Self::UNUSED_BITS,
683 }
684 }
685
686 /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any
687 /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
688 ///
689 /// Note that this is not the same as a rotate-right; the RHS of a wrapping shift-right is
690 /// restricted to the range of the type, rather than the bits shifted out of the LHS being
691 /// returned to the other end.
692 /// A [`rotate_right`](Self::rotate_right) function exists as well, which may be what you
693 /// want instead.
694 ///
695 /// # Examples
696 ///
697 /// Basic usage:
698 ///
699 #[doc = concat!(" ```", $doctest_attr)]
700 /// # use arbitrary_int::prelude::*;
701 /// assert_eq!(i14::new(-128).wrapping_shr(7), i14::new(-1));
702 /// assert_eq!(i14::new(-128).wrapping_shr(60), i14::new(-8));
703 /// ```
704 #[inline]
705 #[must_use = "this returns the result of the operation, without modifying the original"]
706 pub const fn wrapping_shr(self, rhs: u32) -> Self {
707 // modulo is expensive on some platforms, so only do it when necessary
708 let shift_amount = if rhs >= (BITS as u32) {
709 rhs % (BITS as u32)
710 } else {
711 rhs
712 };
713
714 Self {
715 value: (self.value() >> shift_amount),
716 }
717 }
718
719 /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
720 /// bounds instead of overflowing.
721 ///
722 /// # Examples
723 ///
724 /// Basic usage:
725 ///
726 #[doc = concat!(" ```", $doctest_attr)]
727 /// # use arbitrary_int::prelude::*;
728 /// assert_eq!(i14::new(100).saturating_add(i14::new(1)), i14::new(101));
729 /// assert_eq!(i14::MAX.saturating_add(i14::new(100)), i14::MAX);
730 /// assert_eq!(i14::MIN.saturating_add(i14::new(-1)), i14::MIN);
731 /// ```
732 #[inline]
733 #[must_use = "this returns the result of the operation, without modifying the original"]
734 pub const fn saturating_add(self, rhs: Self) -> Self {
735 if Self::UNUSED_BITS == 0 {
736 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
737 // This is very unlikely to happen in practice, but checking allows us to use
738 // `wrapping_add` instead of `saturating_add` in the common case, which is faster.
739 let value = self.value().saturating_add(rhs.value());
740 Self { value }
741 } else {
742 // We're dealing with fewer bits than the underlying type (e.g. i7).
743 // That means the addition can never overflow the underlying type.
744 let value = self.value().wrapping_add(rhs.value());
745 if value > Self::MAX.value {
746 Self::MAX
747 } else if value < Self::MIN.value {
748 Self::MIN
749 } else {
750 Self { value }
751 }
752 }
753 }
754
755 /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric
756 /// bounds instead of overflowing.
757 ///
758 /// # Examples
759 ///
760 /// Basic usage:
761 ///
762 #[doc = concat!(" ```", $doctest_attr)]
763 /// # use arbitrary_int::prelude::*;
764 /// assert_eq!(i14::new(100).saturating_sub(i14::new(127)), i14::new(-27));
765 /// assert_eq!(i14::MIN.saturating_sub(i14::new(100)), i14::MIN);
766 /// assert_eq!(i14::MAX.saturating_sub(i14::new(-1)), i14::MAX);
767 /// ```
768 #[inline]
769 #[must_use = "this returns the result of the operation, without modifying the original"]
770 pub const fn saturating_sub(self, rhs: Self) -> Self {
771 if Self::UNUSED_BITS == 0 {
772 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
773 // This is very unlikely to happen in practice, but checking allows us to use
774 // `wrapping_sub` instead of `saturating_sub` in the common case, which is faster.
775 let value = self.value().saturating_sub(rhs.value());
776 Self { value }
777 } else {
778 // We're dealing with fewer bits than the underlying type (e.g. i7).
779 // That means the subtraction can never overflow the underlying type.
780 let value = self.value().wrapping_sub(rhs.value());
781 if value > Self::MAX.value {
782 Self::MAX
783 } else if value < Self::MIN.value {
784 Self::MIN
785 } else {
786 Self { value }
787 }
788 }
789 }
790
791 /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric
792 /// bounds instead of overflowing.
793 ///
794 /// # Examples
795 ///
796 /// Basic usage:
797 ///
798 #[doc = concat!(" ```", $doctest_attr)]
799 /// # use arbitrary_int::prelude::*;
800 /// assert_eq!(i14::new(10).saturating_mul(i14::new(12)), i14::new(120));
801 /// assert_eq!(i14::MAX.saturating_mul(i14::new(10)), i14::MAX);
802 /// assert_eq!(i14::MIN.saturating_mul(i14::new(10)), i14::MIN);
803 /// ```
804 #[inline]
805 #[must_use = "this returns the result of the operation, without modifying the original"]
806 pub const fn saturating_mul(self, rhs: Self) -> Self {
807 let value = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
808 // We have half the bits (e.g. i4 * i4) of the base type, so we can't overflow the base type
809 // `wrapping_mul` likely provides the best performance on all cpus
810 self.value().wrapping_mul(rhs.value())
811 } else {
812 // We have more than half the bits (e.g. i6 * i6)
813 self.value().saturating_mul(rhs.value())
814 };
815
816 if value > Self::MAX.value {
817 Self::MAX
818 } else if value < Self::MIN.value {
819 Self::MIN
820 } else {
821 Self { value }
822 }
823 }
824
825 /// Saturating integer division. Computes `self / rhs`, saturating at the numeric
826 /// bounds instead of overflowing.
827 ///
828 /// # Panics
829 ///
830 /// This function will panic if rhs is zero.
831 ///
832 /// # Examples
833 ///
834 /// Basic usage:
835 ///
836 #[doc = concat!(" ```", $doctest_attr)]
837 /// # use arbitrary_int::prelude::*;
838 /// assert_eq!(i14::new(5).saturating_div(i14::new(2)), i14::new(2));
839 /// assert_eq!(i14::MAX.saturating_div(i14::new(-1)), i14::MIN + i14::new(1));
840 /// assert_eq!(i14::MIN.saturating_div(i14::new(-1)), i14::MAX);
841 /// ```
842 #[inline]
843 #[must_use = "this returns the result of the operation, without modifying the original"]
844 pub const fn saturating_div(self, rhs: Self) -> Self {
845 // As `Self::MIN / -1` is equal to `Self::MAX + 1` we always need to check for overflow.
846 let value = self.value().saturating_div(rhs.value());
847
848 if value > Self::MAX.value {
849 Self::MAX
850 } else if value < Self::MIN.value {
851 Self::MIN
852 } else {
853 Self { value }
854 }
855 }
856
857 /// Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
858 /// instead of overflowing.
859 ///
860 /// # Examples
861 ///
862 /// Basic usage:
863 ///
864 #[doc = concat!(" ```", $doctest_attr)]
865 /// # use arbitrary_int::prelude::*;
866 /// assert_eq!(i14::new(100).saturating_neg(), i14::new(-100));
867 /// assert_eq!(i14::new(-100).saturating_neg(), i14::new(100));
868 /// assert_eq!(i14::MIN.saturating_neg(), i14::MAX);
869 /// assert_eq!(i14::MAX.saturating_neg(), i14::MIN + i14::new(1));
870 /// ```
871 #[inline]
872 #[must_use = "this returns the result of the operation, without modifying the original"]
873 pub const fn saturating_neg(self) -> Self {
874 if self.value() == Self::MIN.value() {
875 Self::MAX
876 } else {
877 // It is not possible for this to wrap as we've already checked for `MIN`.
878 let value = self.value().wrapping_neg();
879 Self { value }
880 }
881 }
882
883 /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the numeric
884 /// bounds instead of overflowing.
885 ///
886 /// # Examples
887 ///
888 /// Basic usage:
889 ///
890 #[doc = concat!(" ```", $doctest_attr)]
891 /// # use arbitrary_int::prelude::*;
892 /// assert_eq!(i14::new(-4).saturating_pow(3), i14::new(-64));
893 /// assert_eq!(i14::MIN.saturating_pow(2), i14::MAX);
894 /// assert_eq!(i14::MIN.saturating_pow(3), i14::MIN);
895 /// ```
896 #[inline]
897 #[must_use = "this returns the result of the operation, without modifying the original"]
898 pub const fn saturating_pow(self, exp: u32) -> Self {
899 // It might be possible to handwrite this to be slightly faster as both
900 // `saturating_pow` has to do a bounds-check and then we do second one.
901 let value = self.value().saturating_pow(exp);
902
903 if value > Self::MAX.value {
904 Self::MAX
905 } else if value < Self::MIN.value {
906 Self::MIN
907 } else {
908 Self { value }
909 }
910 }
911
912 /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
913 ///
914 /// # Examples
915 ///
916 /// Basic usage:
917 ///
918 #[doc = concat!(" ```", $doctest_attr)]
919 /// # use arbitrary_int::prelude::*;
920 /// assert_eq!((i14::MAX - i14::new(2)).checked_add(i14::new(1)), Some(i14::MAX - i14::new(1)));
921 /// assert_eq!((i14::MAX - i14::new(2)).checked_add(i14::new(3)), None);
922 /// ```
923 #[inline]
924 #[must_use = "this returns the result of the operation, without modifying the original"]
925 pub const fn checked_add(self, rhs: Self) -> Option<Self> {
926 if Self::UNUSED_BITS == 0 {
927 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
928 // This is very unlikely to happen in practice, but checking allows us to use
929 // `wrapping_add` instead of `checked_add` in the common case, which is faster.
930 match self.value().checked_add(rhs.value()) {
931 Some(value) => Some(Self { value }),
932 None => None
933 }
934 } else {
935 // We're dealing with fewer bits than the underlying type (e.g. i7).
936 // That means the addition can never overflow the underlying type
937 let value = self.value().wrapping_add(rhs.value());
938 if value < Self::MIN.value() || value > Self::MAX.value() {
939 None
940 } else {
941 Some(Self { value })
942 }
943 }
944 }
945
946 /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
947 ///
948 /// # Examples
949 ///
950 /// Basic usage:
951 ///
952 #[doc = concat!(" ```", $doctest_attr)]
953 /// # use arbitrary_int::prelude::*;
954 /// assert_eq!((i14::MIN + i14::new(2)).checked_sub(i14::new(1)), Some(i14::MIN + i14::new(1)));
955 /// assert_eq!((i14::MIN + i14::new(2)).checked_sub(i14::new(3)), None);
956 /// ```
957 #[inline]
958 #[must_use = "this returns the result of the operation, without modifying the original"]
959 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
960 if Self::UNUSED_BITS == 0 {
961 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
962 // This is very unlikely to happen in practice, but checking allows us to use
963 // `wrapping_sub` instead of `checked_sub` in the common case, which is faster.
964 match self.value().checked_sub(rhs.value()) {
965 Some(value) => Some(Self { value }),
966 None => None
967 }
968 } else {
969 // We're dealing with fewer bits than the underlying type (e.g. i7).
970 // That means the subtraction can never overflow the underlying type
971 let value = self.value().wrapping_sub(rhs.value());
972 if value < Self::MIN.value() || value > Self::MAX.value() {
973 None
974 } else {
975 Some(Self { value })
976 }
977 }
978 }
979
980 /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
981 ///
982 /// # Examples
983 ///
984 /// Basic usage:
985 ///
986 #[doc = concat!(" ```", $doctest_attr)]
987 /// # use arbitrary_int::prelude::*;
988 /// assert_eq!(i14::MAX.checked_mul(i14::new(1)), Some(i14::MAX));
989 /// assert_eq!(i14::MAX.checked_mul(i14::new(2)), None);
990 /// ```
991 #[inline]
992 #[must_use = "this returns the result of the operation, without modifying the original"]
993 pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
994 let product = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
995 // We have half the bits (e.g. `i4 * i4`) of the base type, so we can't overflow the base type.
996 // `wrapping_mul` likely provides the best performance on all CPUs.
997 Some(self.value().wrapping_mul(rhs.value()))
998 } else {
999 // We have more than half the bits (e.g. u6 * u6)
1000 self.value().checked_mul(rhs.value())
1001 };
1002
1003 match product {
1004 Some(value) if value >= Self::MIN.value() && value <= Self::MAX.value() => {
1005 Some(Self { value })
1006 }
1007 _ => None
1008 }
1009 }
1010
1011 /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
1012 /// or the division results in overflow.
1013 ///
1014 /// # Examples
1015 ///
1016 /// Basic usage:
1017 ///
1018 #[doc = concat!(" ```", $doctest_attr)]
1019 /// # use arbitrary_int::prelude::*;
1020 /// assert_eq!((i14::MIN + i14::new(1)).checked_div(i14::new(-1)), Some(i14::new(8191)));
1021 /// assert_eq!(i14::MIN.checked_div(i14::new(-1)), None);
1022 /// assert_eq!((i14::new(1)).checked_div(i14::new(0)), None);
1023 /// ```
1024 #[inline]
1025 #[must_use = "this returns the result of the operation, without modifying the original"]
1026 pub const fn checked_div(self, rhs: Self) -> Option<Self> {
1027 // `checked_div` from the underlying type already catches division by zero,
1028 // and the only way this can overflow is with `MIN / -1` (which equals `MAX + 1`).
1029 // Because of this we only need to check if the value is larger than `MAX`.
1030 match self.value().checked_div(rhs.value()) {
1031 Some(value) if value <= Self::MAX.value() => Some(Self { value }),
1032 _ => None
1033 }
1034 }
1035
1036 /// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
1037 ///
1038 /// # Examples
1039 ///
1040 /// Basic usage:
1041 ///
1042 #[doc = concat!(" ```", $doctest_attr)]
1043 /// # use arbitrary_int::prelude::*;
1044 /// assert_eq!(i14::new(5).checked_neg(), Some(i14::new(-5)));
1045 /// assert_eq!(i14::MIN.checked_neg(), None);
1046 /// ```
1047 pub const fn checked_neg(self) -> Option<Self> {
1048 if self.value() == Self::MIN.value() {
1049 None
1050 } else {
1051 // It is not possible for this to wrap as we've already checked for `MIN`.
1052 let value = self.value().wrapping_neg();
1053 Some(Self { value })
1054 }
1055 }
1056
1057 /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger than or
1058 /// equal to the number of bits in `self`.
1059 ///
1060 /// # Examples
1061 ///
1062 /// Basic usage:
1063 ///
1064 #[doc = concat!(" ```", $doctest_attr)]
1065 /// # use arbitrary_int::i14;
1066 /// assert_eq!(i14::new(0x1).checked_shl(4), Some(i14::new(0x10)));
1067 /// assert_eq!(i14::new(0x1).checked_shl(129), None);
1068 /// assert_eq!(i14::new(0x10).checked_shl(13), Some(i14::new(0)));
1069 /// ```
1070 #[inline]
1071 #[must_use = "this returns the result of the operation, without modifying the original"]
1072 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
1073 if rhs >= (BITS as u32) {
1074 None
1075 } else {
1076 let value = ((self.value() << rhs) << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1077 Some(Self { value })
1078 }
1079 }
1080
1081 /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than
1082 /// or equal to the number of bits in `self`.
1083 ///
1084 /// # Examples
1085 ///
1086 /// Basic usage:
1087 ///
1088 #[doc = concat!(" ```", $doctest_attr)]
1089 /// # use arbitrary_int::i14;
1090 /// assert_eq!(i14::new(0x10).checked_shr(4), Some(i14::new(0x1)));
1091 /// assert_eq!(i14::new(0x10).checked_shr(129), None);
1092 /// ```
1093 #[inline]
1094 #[must_use = "this returns the result of the operation, without modifying the original"]
1095 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
1096 if rhs >= (BITS as u32) {
1097 None
1098 } else {
1099 let value = ((self.value() >> rhs) << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1100 Some(Self { value })
1101 }
1102 }
1103
1104 /// Calculates `self + rhs`.
1105 ///
1106 /// Returns a tuple of the addition along with a boolean indicating whether an arithmetic
1107 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
1108 ///
1109 /// # Examples
1110 ///
1111 /// Basic usage:
1112 ///
1113 #[doc = concat!(" ```", $doctest_attr)]
1114 /// # use arbitrary_int::prelude::*;
1115 /// assert_eq!(i14::new(5).overflowing_add(i14::new(2)), (i14::new(7), false));
1116 /// assert_eq!(i14::MAX.overflowing_add(i14::new(1)), (i14::MIN, true));
1117 /// ```
1118 #[inline]
1119 #[must_use = "this returns the result of the operation, without modifying the original"]
1120 pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
1121 let (value, overflow) = if Self::UNUSED_BITS == 0 {
1122 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
1123 // This is very unlikely to happen in practice, but checking allows us to use
1124 // `wrapping_add` instead of `overflowing_add` in the common case, which is faster.
1125 self.value().overflowing_add(rhs.value())
1126 } else {
1127 // We're dealing with fewer bits than the underlying type (e.g. i7).
1128 // That means the addition can never overflow the underlying type.
1129 let sum = self.value().wrapping_add(rhs.value());
1130 let value = (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1131 (value, value != sum)
1132 };
1133
1134 (Self { value }, overflow)
1135 }
1136
1137 /// Calculates `self - rhs`.
1138 ///
1139 /// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic
1140 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
1141 ///
1142 /// # Examples
1143 ///
1144 /// Basic usage:
1145 ///
1146 #[doc = concat!(" ```", $doctest_attr)]
1147 /// # use arbitrary_int::prelude::*;
1148 /// assert_eq!(i14::new(5).overflowing_sub(i14::new(2)), (i14::new(3), false));
1149 /// assert_eq!(i14::MIN.overflowing_sub(i14::new(1)), (i14::MAX, true));
1150 /// ```
1151 #[inline]
1152 #[must_use = "this returns the result of the operation, without modifying the original"]
1153 pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
1154 let (value, overflow) = if Self::UNUSED_BITS == 0 {
1155 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
1156 // This is very unlikely to happen in practice, but checking allows us to use
1157 // `wrapping_sub` instead of `overflowing_sub` in the common case, which is faster.
1158 self.value().overflowing_sub(rhs.value())
1159 } else {
1160 // We're dealing with fewer bits than the underlying type (e.g. i7).
1161 // That means the subtraction can never overflow the underlying type
1162 let sum = self.value().wrapping_sub(rhs.value());
1163 let value = (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1164 (value, value != sum)
1165 };
1166
1167 (Self { value }, overflow)
1168 }
1169
1170 /// Calculates the multiplication of `self` and `rhs`.
1171 ///
1172 /// Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic
1173 /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
1174 ///
1175 /// # Examples
1176 ///
1177 /// Basic usage:
1178 ///
1179 #[doc = concat!(" ```", $doctest_attr)]
1180 /// # use arbitrary_int::prelude::*;
1181 /// assert_eq!(i14::new(5).overflowing_mul(i14::new(2)), (i14::new(10), false));
1182 /// assert_eq!(i14::new(1_000).overflowing_mul(i14::new(10)), (i14::new(-6384), true));
1183 /// ```
1184 #[inline]
1185 #[must_use = "this returns the result of the operation, without modifying the original"]
1186 pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
1187 let (wrapping_product, overflow) = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
1188 // We have half the bits (e.g. i4 * i4) of the base type, so we can't overflow the base type.
1189 // `wrapping_mul` likely provides the best performance on all CPUs.
1190 (self.value().wrapping_mul(rhs.value()), false)
1191 } else {
1192 // We have more than half the bits (e.g. i6 * i6)
1193 self.value().overflowing_mul(rhs.value())
1194 };
1195
1196 let value = (wrapping_product << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1197 let overflow2 = value != wrapping_product;
1198 (Self { value }, overflow || overflow2)
1199 }
1200
1201 /// Calculates the divisor when `self` is divided by `rhs`.
1202 ///
1203 /// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic
1204 /// overflow would occur. If an overflow would occur then self is returned.
1205 ///
1206 /// # Panics
1207 ///
1208 /// This function will panic if `rhs` is zero.
1209 ///
1210 /// # Examples
1211 ///
1212 /// Basic usage:
1213 ///
1214 #[doc = concat!(" ```", $doctest_attr)]
1215 /// # use arbitrary_int::prelude::*;
1216 /// assert_eq!(i14::new(5).overflowing_div(i14::new(2)), (i14::new(2), false));
1217 /// assert_eq!(i14::MIN.overflowing_div(i14::new(-1)), (i14::MIN, true));
1218 /// ```
1219 #[inline]
1220 #[must_use = "this returns the result of the operation, without modifying the original"]
1221 pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
1222 let (value, overflow) = if Self::UNUSED_BITS == 0 {
1223 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
1224 // This is very unlikely to happen in practice, but checking allows us to use
1225 // `wrapping_div` instead of `overflowing_div` in the common case, which is faster.
1226 self.value().overflowing_div(rhs.value())
1227 } else {
1228 // We're dealing with fewer bits than the underlying type (e.g. i7).
1229 // That means the division can never overflow the underlying type.
1230 let quotient = self.value().wrapping_div(rhs.value());
1231 let value = (quotient << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1232 (value, value != quotient)
1233 };
1234
1235 (Self { value }, overflow)
1236 }
1237
1238 /// Negates `self`, overflowing if this is equal to the minimum value.
1239 ///
1240 /// Returns a tuple of the negated version of self along with a boolean indicating whether an
1241 /// overflow happened. If `self` is the minimum value (e.g., `i14::MIN` for values of type `i14`),
1242 /// then the minimum value will be returned again and `true` will be returned for an overflow happening.
1243 ///
1244 /// # Examples
1245 ///
1246 /// Basic usage:
1247 ///
1248 #[doc = concat!(" ```", $doctest_attr)]
1249 /// # use arbitrary_int::prelude::*;
1250 /// assert_eq!(i14::new(2).overflowing_neg(), (i14::new(-2), false));
1251 /// assert_eq!(i14::MIN.overflowing_neg(), (i14::MIN, true));
1252 /// ```
1253 #[inline]
1254 #[must_use = "this returns the result of the operation, without modifying the original"]
1255 pub const fn overflowing_neg(self) -> (Self, bool) {
1256 let (value, overflow) = if Self::UNUSED_BITS == 0 {
1257 // We are something like a Int::<i8; 8>, we can fallback to the base implementation.
1258 // This is very unlikely to happen in practice, but checking allows us to use
1259 // `wrapping_neg` instead of `overflowing_neg` in the common case, which is faster.
1260 self.value().overflowing_neg()
1261 } else {
1262 // We're dealing with fewer bits than the underlying type (e.g. i7).
1263 // That means the negation can never overflow the underlying type.
1264 let negated = self.value().wrapping_neg();
1265 let value = (negated << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1266 (value, value != negated)
1267 };
1268
1269 (Self { value }, overflow)
1270 }
1271
1272 /// Shifts `self` left by `rhs` bits.
1273 ///
1274 /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
1275 /// the shift value was larger than or equal to the number of bits. If the shift value is too
1276 /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
1277 /// used to perform the shift.
1278 ///
1279 /// # Examples
1280 ///
1281 /// Basic usage:
1282 ///
1283 #[doc = concat!(" ```", $doctest_attr)]
1284 /// # use arbitrary_int::prelude::*;
1285 /// assert_eq!(i14::new(0x1).overflowing_shl(4), (i14::new(0x10), false));
1286 /// assert_eq!(i14::new(0x1).overflowing_shl(15), (i14::new(0x2), true));
1287 /// assert_eq!(i14::new(0x10).overflowing_shl(13), (i14::new(0), false));
1288 /// ```
1289 #[inline]
1290 #[must_use = "this returns the result of the operation, without modifying the original"]
1291 pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
1292 let (shift, overflow) = if rhs >= (BITS as u32) {
1293 (rhs % (BITS as u32), true)
1294 } else {
1295 (rhs, false)
1296 };
1297
1298 // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1299 let value = (self.value().wrapping_shl(shift) << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1300 (Self { value }, overflow)
1301 }
1302
1303 /// Shifts `self` right by `rhs` bits.
1304 ///
1305 /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
1306 /// the shift value was larger than or equal to the number of bits. If the shift value is too
1307 /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
1308 /// used to perform the shift.
1309 ///
1310 /// # Examples
1311 ///
1312 /// Basic usage:
1313 ///
1314 #[doc = concat!(" ```", $doctest_attr)]
1315 /// # use arbitrary_int::prelude::*;
1316 /// assert_eq!(i14::new(0x10).overflowing_shr(4), (i14::new(0x1), false));
1317 /// assert_eq!(i14::new(0x10).overflowing_shr(15), (i14::new(0x8), true));
1318 /// ```
1319 #[inline]
1320 #[must_use = "this returns the result of the operation, without modifying the original"]
1321 pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
1322 let (shift, overflow) = if rhs >= (BITS as u32) {
1323 (rhs % (BITS as u32), true)
1324 } else {
1325 (rhs, false)
1326 };
1327
1328 // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1329 let value = (self.value().wrapping_shr(shift) << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1330 (Self { value }, overflow)
1331 }
1332
1333 /// Returns `true` if `self` is positive and `false` if the number is zero or negative.
1334 ///
1335 /// # Examples
1336 ///
1337 /// Basic usage:
1338 ///
1339 #[doc = concat!(" ```", $doctest_attr)]
1340 /// # use arbitrary_int::prelude::*;
1341 /// assert!(i14::new(10).is_positive());
1342 /// assert!(!i14::new(-10).is_positive());
1343 /// ```
1344 #[inline]
1345 #[must_use]
1346 pub const fn is_positive(self) -> bool {
1347 self.value() > 0
1348 }
1349
1350 /// Returns `true` if `self` is negative and `false` if the number is zero or positive.
1351 ///
1352 /// # Examples
1353 ///
1354 /// Basic usage:
1355 ///
1356 #[doc = concat!(" ```", $doctest_attr)]
1357 /// # use arbitrary_int::prelude::*;
1358 /// assert!(i14::new(-10).is_negative());
1359 /// assert!(!i14::new(10).is_negative());
1360 /// ```
1361 #[inline]
1362 #[must_use]
1363 pub const fn is_negative(self) -> bool {
1364 self.value() < 0
1365 }
1366
1367 /// Reverses the order of bits in the integer. The least significant bit becomes the most
1368 /// significant bit, second least-significant bit becomes second most-significant bit, etc.
1369 ///
1370 /// # Examples
1371 ///
1372 /// Basic usage:
1373 ///
1374 #[doc = concat!(" ```", $doctest_attr)]
1375 /// # use arbitrary_int::prelude::*;
1376 /// assert_eq!(i6::from_bits(0b10_1010).reverse_bits(), i6::from_bits(0b01_0101));
1377 /// assert_eq!(i6::new(0), i6::new(0).reverse_bits());
1378 /// ```
1379 #[inline]
1380 #[must_use = "this returns the result of the operation, without modifying the original"]
1381 pub const fn reverse_bits(self) -> Self {
1382 let value = self.value().reverse_bits() >> Self::UNUSED_BITS;
1383 Self { value }
1384 }
1385
1386 /// Returns the number of ones in the binary representation of `self`.
1387 ///
1388 /// # Examples
1389 ///
1390 /// Basic usage:
1391 ///
1392 #[doc = concat!(" ```", $doctest_attr)]
1393 /// # use arbitrary_int::prelude::*;
1394 /// let n = i6::from_bits(0b00_1000);
1395 /// assert_eq!(n.count_ones(), 1);
1396 /// ```
1397 #[inline]
1398 pub const fn count_ones(self) -> u32 {
1399 // Due to sign-extension the unused bits may be either all ones or zeros, so we need to mask them off.
1400 (self.value() & Self::MASK).count_ones()
1401 }
1402
1403 /// Returns the number of zeros in the binary representation of `self`.
1404 ///
1405 /// # Examples
1406 ///
1407 /// Basic usage:
1408 ///
1409 #[doc = concat!(" ```", $doctest_attr)]
1410 /// # use arbitrary_int::prelude::*;
1411 /// assert_eq!(i6::MAX.count_zeros(), 1);
1412 /// ```
1413 #[inline]
1414 pub const fn count_zeros(self) -> u32 {
1415 // Due to sign-extension the unused bits may be either all ones or zeros, so we need to mask them off.
1416 // Afterwards the unused bits are all zero, so we can subtract them from the result.
1417 // We can avoid a bounds check in debug builds with `wrapping_sub` since this cannot overflow.
1418 (self.value() & Self::MASK).count_zeros().wrapping_sub(Self::UNUSED_BITS as u32)
1419 }
1420
1421 /// Returns the number of leading ones in the binary representation of `self`.
1422 ///
1423 /// # Examples
1424 ///
1425 /// Basic usage:
1426 ///
1427 #[doc = concat!(" ```", $doctest_attr)]
1428 /// # use arbitrary_int::prelude::*;
1429 /// let n = i6::new(-1);
1430 /// assert_eq!(n.leading_ones(), 6);
1431 /// ```
1432 #[inline]
1433 pub const fn leading_ones(self) -> u32 {
1434 (self.value() << Self::UNUSED_BITS).leading_ones()
1435 }
1436
1437 /// Returns the number of leading zeros in the binary representation of `self`.
1438 ///
1439 /// # Examples
1440 ///
1441 /// Basic usage:
1442 ///
1443 #[doc = concat!(" ```", $doctest_attr)]
1444 /// # use arbitrary_int::prelude::*;
1445 /// let n = i6::new(-1);
1446 /// assert_eq!(n.leading_zeros(), 0);
1447 /// ```
1448 #[inline]
1449 pub const fn leading_zeros(self) -> u32 {
1450 if Self::UNUSED_BITS == 0 {
1451 self.value().leading_zeros()
1452 } else {
1453 // Prevent an all-zero value reporting the underlying type's entire bit width by setting
1454 // the first unused bit to one, causing `leading_zeros()` to ignore all unused bits.
1455 let first_unused_bit_set = const { 1 << (Self::UNUSED_BITS - 1) };
1456 ((self.value() << Self::UNUSED_BITS) | first_unused_bit_set).leading_zeros()
1457 }
1458 }
1459
1460 /// Returns the number of trailing ones in the binary representation of `self`.
1461 ///
1462 /// # Examples
1463 ///
1464 /// Basic usage:
1465 ///
1466 #[doc = concat!(" ```", $doctest_attr)]
1467 /// # use arbitrary_int::prelude::*;
1468 /// let n = i6::new(3);
1469 /// assert_eq!(n.trailing_ones(), 2);
1470 /// ```
1471 #[inline]
1472 pub const fn trailing_ones(self) -> u32 {
1473 // Prevent an all-ones value reporting the underlying type's entire bit width by masking
1474 // off all the unused bits.
1475 (self.value() & Self::MASK).trailing_ones()
1476 }
1477
1478 /// Returns the number of trailing zeros in the binary representation of `self`.
1479 ///
1480 /// # Examples
1481 ///
1482 /// Basic usage:
1483 ///
1484 #[doc = concat!(" ```", $doctest_attr)]
1485 /// # use arbitrary_int::prelude::*;
1486 /// let n = i6::new(-4);
1487 /// assert_eq!(n.trailing_zeros(), 2);
1488 /// ```
1489 #[inline]
1490 pub const fn trailing_zeros(self) -> u32 {
1491 // Prevent an all-ones value reporting the underlying type's entire bit width by setting
1492 // all the unused bits.
1493 (self.value() | !Self::MASK).trailing_zeros()
1494 }
1495
1496 /// Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits
1497 /// to the end of the resulting integer.
1498 ///
1499 /// Please note this isn’t the same operation as the `<<` shifting operator!
1500 ///
1501 /// # Examples
1502 ///
1503 /// Basic usage:
1504 ///
1505 #[doc = concat!(" ```", $doctest_attr)]
1506 /// # use arbitrary_int::prelude::*;
1507 /// let n = i6::from_bits(0b10_1010);
1508 /// let m = i6::from_bits(0b01_0101);
1509 ///
1510 /// assert_eq!(n.rotate_left(1), m);
1511 /// ```
1512 #[inline]
1513 #[must_use = "this returns the result of the operation, without modifying the original"]
1514 pub const fn rotate_left(self, n: u32) -> Self {
1515 let b = BITS as u32;
1516 let n = if n >= b { n % b } else { n };
1517
1518 // Temporarily switch to an unsigned type to prevent sign-extension with `>>`.
1519 let moved_bits = ((self.value() << n) & Self::MASK) as $unsigned_type;
1520 let truncated_bits = ((self.value() & Self::MASK) as $unsigned_type) >> (b - n);
1521 let value = (((moved_bits | truncated_bits) << Self::UNUSED_BITS) as $type) >> Self::UNUSED_BITS;
1522 Self { value }
1523 }
1524
1525 /// Shifts the bits to the right by a specified amount, `n`, wrapping the truncated bits
1526 /// to the beginning of the resulting integer.
1527 ///
1528 /// Please note this isn’t the same operation as the `>>` shifting operator!
1529 ///
1530 /// # Examples
1531 ///
1532 /// Basic usage:
1533 ///
1534 #[doc = concat!(" ```", $doctest_attr)]
1535 /// # use arbitrary_int::prelude::*;
1536 /// let n = i6::from_bits(0b10_1010);
1537 /// let m = i6::from_bits(0b01_0101);
1538 ///
1539 /// assert_eq!(n.rotate_right(1), m);
1540 /// ```
1541 #[inline]
1542 #[must_use = "this returns the result of the operation, without modifying the original"]
1543 pub const fn rotate_right(self, n: u32) -> Self {
1544 let b = BITS as u32;
1545 let n = if n >= b { n % b } else { n };
1546
1547 // Temporarily switch to an unsigned type to prevent sign-extension with `>>`.
1548 let moved_bits = (self.value() & Self::MASK) as $unsigned_type >> n;
1549 let truncated_bits = ((self.value() << (b - n)) & Self::MASK) as $unsigned_type;
1550 let value = (((moved_bits | truncated_bits) << Self::UNUSED_BITS) as $type) >> Self::UNUSED_BITS;
1551 Self { value }
1552 }
1553 }
1554 )+
1555 };
1556}
1557
1558#[cfg(feature = "bytecheck")]
1559unsafe impl<
1560 T: SignedInteger + BuiltinInteger + Copy,
1561 const BITS: usize,
1562 C: bytecheck::rancor::Fallible + ?Sized,
1563 > bytecheck::Verify<C> for Int<T, BITS>
1564where
1565 C::Error: bytecheck::rancor::Source,
1566 Self: Integer,
1567{
1568 fn verify(&self, _context: &mut C) -> Result<(), C::Error> {
1569 if self.value > Self::MAX.value || self.value < Self::MIN.value {
1570 bytecheck::rancor::fail!(TryNewError);
1571 }
1572 Ok(())
1573 }
1574}
1575
1576#[cfg(feature = "rkyv")]
1577unsafe impl<
1578 T: SignedInteger + BuiltinInteger + rkyv::Archive,
1579 const BITS: usize,
1580 C: rkyv::bytecheck::rancor::Fallible + ?Sized,
1581 > rkyv::bytecheck::Verify<C> for ArchivedInt<T, BITS>
1582where
1583 C::Error: rkyv::bytecheck::rancor::Source,
1584 Int<T, BITS>: Integer,
1585 T: From<T::Archived>,
1586 T::Archived: Copy,
1587{
1588 fn verify(&self, _context: &mut C) -> Result<(), C::Error> {
1589 let native: T = self.value.into();
1590 if native > Int::<T, BITS>::MAX.value || native < Int::<T, BITS>::MIN.value {
1591 rkyv::bytecheck::rancor::fail!(TryNewError);
1592 }
1593 Ok(())
1594 }
1595}
1596
1597// Because the methods within this macro are effectively copy-pasted for each underlying integer type,
1598// each documentation test gets executed five times (once for each underlying type), even though the
1599// tests themselves aren't specific to said underlying type. This severely slows down `cargo test`,
1600// so we ignore them for all but one (arbitrary) underlying type.
1601int_impl!(
1602 (i8, u8, doctest = "rust"),
1603 (i16, u16, doctest = "ignore"),
1604 (i32, u32, doctest = "ignore"),
1605 (i64, u64, doctest = "ignore"),
1606 (i128, u128, doctest = "ignore")
1607);
1608
1609// Arithmetic operator implementations
1610impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Add for Int<T, BITS>
1611where
1612 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1613{
1614 type Output = Self;
1615
1616 fn add(self, rhs: Self) -> Self::Output {
1617 let sum = self.value + rhs.value;
1618 let value = (sum << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1619 debug_assert!(sum == value, "attempted to add with overflow");
1620 Self { value }
1621 }
1622}
1623
1624impl<T: SignedInteger + BuiltinInteger, const BITS: usize> AddAssign for Int<T, BITS>
1625where
1626 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1627{
1628 fn add_assign(&mut self, rhs: Self) {
1629 // Delegate to the Add implementation above.
1630 *self = *self + rhs;
1631 }
1632}
1633
1634impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Sub for Int<T, BITS>
1635where
1636 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1637{
1638 type Output = Self;
1639
1640 fn sub(self, rhs: Self) -> Self::Output {
1641 let difference = self.value - rhs.value;
1642 let value = (difference << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1643 debug_assert!(difference == value, "attempted to subtract with overflow");
1644 Self { value }
1645 }
1646}
1647
1648impl<T: SignedInteger + BuiltinInteger, const BITS: usize> SubAssign for Int<T, BITS>
1649where
1650 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1651{
1652 fn sub_assign(&mut self, rhs: Self) {
1653 // Delegate to the Sub implementation above.
1654 *self = *self - rhs;
1655 }
1656}
1657
1658impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Mul for Int<T, BITS>
1659where
1660 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1661{
1662 type Output = Self;
1663
1664 fn mul(self, rhs: Self) -> Self::Output {
1665 let product = self.value * rhs.value;
1666 let value = (product << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1667 debug_assert!(product == value, "attempted to multiply with overflow");
1668 Self { value }
1669 }
1670}
1671
1672impl<T: SignedInteger + BuiltinInteger, const BITS: usize> MulAssign for Int<T, BITS>
1673where
1674 Self: Integer,
1675{
1676 fn mul_assign(&mut self, rhs: Self) {
1677 // Delegate to the Mul implementation above.
1678 *self = *self * rhs;
1679 }
1680}
1681
1682impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Div for Int<T, BITS>
1683where
1684 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1685{
1686 type Output = Self;
1687
1688 fn div(self, rhs: Self) -> Self::Output {
1689 // Unlike the unsigned implementation we do need to account for overflow here,
1690 // `Self::MIN / -1` is equal to `Self::MAX + 1` and should therefore panic.
1691 let quotient = self.value / rhs.value;
1692 let value = (quotient << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1693 debug_assert!(quotient == value, "attempted to divide with overflow");
1694 Self { value }
1695 }
1696}
1697
1698impl<T: SignedInteger + BuiltinInteger, const BITS: usize> DivAssign for Int<T, BITS>
1699where
1700 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1701{
1702 fn div_assign(&mut self, rhs: Self) {
1703 // Delegate to the Div implementation above.
1704 *self = *self / rhs;
1705 }
1706}
1707
1708impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Neg for Int<T, BITS>
1709where
1710 Self: Integer<UnderlyingType = T>,
1711 T: Shl<usize, Output = T> + Shr<usize, Output = T>,
1712{
1713 type Output = Self;
1714
1715 #[inline]
1716 fn neg(self) -> Self::Output {
1717 let negated = -self.value();
1718 let value = (negated << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1719 debug_assert!(negated == value, "attempt to negate with overflow");
1720 Self { value }
1721 }
1722}
1723
1724// Bitwise operator implementations
1725impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitAnd for Int<T, BITS> {
1726 type Output = Self;
1727
1728 fn bitand(self, rhs: Self) -> Self::Output {
1729 let value = self.value & rhs.value;
1730 Self { value }
1731 }
1732}
1733
1734impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitAndAssign for Int<T, BITS> {
1735 fn bitand_assign(&mut self, rhs: Self) {
1736 self.value &= rhs.value;
1737 }
1738}
1739
1740impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitOr for Int<T, BITS> {
1741 type Output = Self;
1742
1743 fn bitor(self, rhs: Self) -> Self::Output {
1744 let value = self.value | rhs.value;
1745 Self { value }
1746 }
1747}
1748
1749impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitOrAssign for Int<T, BITS> {
1750 fn bitor_assign(&mut self, rhs: Self) {
1751 self.value |= rhs.value;
1752 }
1753}
1754
1755impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitXor for Int<T, BITS> {
1756 type Output = Self;
1757
1758 fn bitxor(self, rhs: Self) -> Self::Output {
1759 let value = self.value ^ rhs.value;
1760 Self { value }
1761 }
1762}
1763
1764impl<T: SignedInteger + BuiltinInteger, const BITS: usize> BitXorAssign for Int<T, BITS> {
1765 fn bitxor_assign(&mut self, rhs: Self) {
1766 self.value ^= rhs.value;
1767 }
1768}
1769
1770impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Not for Int<T, BITS> {
1771 type Output = Self;
1772
1773 fn not(self) -> Self::Output {
1774 let value = !self.value;
1775 Self { value }
1776 }
1777}
1778
1779impl<T: SignedInteger + BuiltinInteger, TSHIFTBITS, const BITS: usize> Shl<TSHIFTBITS>
1780 for Int<T, BITS>
1781where
1782 T: Shl<TSHIFTBITS, Output = T> + Shl<usize, Output = T> + Shr<usize, Output = T>,
1783 TSHIFTBITS: TryInto<usize> + Copy,
1784{
1785 type Output = Self;
1786
1787 fn shl(self, rhs: TSHIFTBITS) -> Self::Output {
1788 // With debug assertions, the << and >> operators throw an exception if the shift amount
1789 // is larger than the number of bits (in which case the result would always be 0)
1790 debug_assert!(
1791 rhs.try_into().unwrap_or(usize::MAX) < BITS,
1792 "attempted to shift left with overflow"
1793 );
1794
1795 // Shift left twice to avoid needing an unnecessarily strict `TSHIFTBITS: Add<Self::UNUSED_BITS>` bound.
1796 // This should be optimised to a single shift.
1797 let value = ((self.value << rhs) << Self::UNUSED_BITS) >> Self::UNUSED_BITS;
1798 Self { value }
1799 }
1800}
1801
1802impl<T: SignedInteger + BuiltinInteger, TSHIFTBITS, const BITS: usize> ShlAssign<TSHIFTBITS>
1803 for Int<T, BITS>
1804where
1805 Self: Integer,
1806 T: Shl<TSHIFTBITS, Output = T> + Shl<usize, Output = T> + Shr<usize, Output = T>,
1807 TSHIFTBITS: TryInto<usize> + Copy,
1808{
1809 fn shl_assign(&mut self, rhs: TSHIFTBITS) {
1810 // Delegate to the Shl implementation above.
1811 *self = *self << rhs;
1812 }
1813}
1814
1815impl<T: SignedInteger + BuiltinInteger, TSHIFTBITS, const BITS: usize> Shr<TSHIFTBITS>
1816 for Int<T, BITS>
1817where
1818 Self: Integer,
1819 T: Shr<TSHIFTBITS, Output = T> + Shl<usize, Output = T> + Shr<usize, Output = T>,
1820 TSHIFTBITS: TryInto<usize> + Copy,
1821{
1822 type Output = Self;
1823
1824 fn shr(self, rhs: TSHIFTBITS) -> Self::Output {
1825 // With debug assertions, the << and >> operators throw an exception if the shift amount
1826 // is larger than the number of bits (in which case the result would always be 0)
1827 debug_assert!(
1828 rhs.try_into().unwrap_or(usize::MAX) < BITS,
1829 "attempted to shift right with overflow"
1830 );
1831
1832 Self {
1833 // Our unused bits can only ever all be 1 or 0, depending on the sign.
1834 // As right shifts on primitive types perform sign-extension anyways we don't need to do any extra work here.
1835 value: self.value >> rhs,
1836 }
1837 }
1838}
1839
1840impl<T: SignedInteger + BuiltinInteger, TSHIFTBITS, const BITS: usize> ShrAssign<TSHIFTBITS>
1841 for Int<T, BITS>
1842where
1843 Self: Integer,
1844 T: Shr<TSHIFTBITS, Output = T> + Shl<usize, Output = T> + Shr<usize, Output = T>,
1845 TSHIFTBITS: TryInto<usize> + Copy,
1846{
1847 fn shr_assign(&mut self, rhs: TSHIFTBITS) {
1848 // Delegate to the Shr implementation above.
1849 *self = *self >> rhs;
1850 }
1851}
1852
1853// Delegated trait implementations
1854impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Display for Int<T, BITS> {
1855 #[inline]
1856 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1857 Display::fmt(&self.value, f)
1858 }
1859}
1860
1861impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Debug for Int<T, BITS> {
1862 #[inline]
1863 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1864 Debug::fmt(&self.value, f)
1865 }
1866}
1867
1868impl<T: SignedInteger + BuiltinInteger, const BITS: usize> LowerHex for Int<T, BITS> {
1869 #[inline]
1870 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1871 LowerHex::fmt(&self.value, f)
1872 }
1873}
1874
1875impl<T: SignedInteger + BuiltinInteger, const BITS: usize> UpperHex for Int<T, BITS> {
1876 #[inline]
1877 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1878 UpperHex::fmt(&self.value, f)
1879 }
1880}
1881
1882impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Octal for Int<T, BITS> {
1883 #[inline]
1884 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1885 Octal::fmt(&self.value, f)
1886 }
1887}
1888
1889impl<T: SignedInteger + BuiltinInteger, const BITS: usize> Binary for Int<T, BITS> {
1890 #[inline]
1891 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1892 Binary::fmt(&self.value, f)
1893 }
1894}
1895
1896impl_bytemuck_basic!(Int, SignedInteger {
1897 /// A [`Int`] initialized to zero has a zero value.
1898 impl Zeroable for ... {}
1899 /// A [`Int`] has no uninitialized bytes or padding.
1900 impl NoUninit for ... {}
1901 /// It is possible to check whether an in-memory representation of an [`Int`] is valid,
1902 /// although the specific meaning of that representation is not specified.
1903 impl CheckedBitPattern for ... {}
1904});
1905
1906#[cfg(feature = "defmt")]
1907impl<T: SignedInteger + BuiltinInteger, const BITS: usize> defmt::Format for Int<T, BITS>
1908where
1909 T: defmt::Format,
1910{
1911 #[inline]
1912 fn format(&self, f: defmt::Formatter) {
1913 self.value.format(f)
1914 }
1915}
1916
1917impl_borsh!(Int, "i", SignedInteger);
1918
1919impl_bin_proto!(Int, SignedInteger);
1920
1921// Serde's invalid_value error (https://rust-lang.github.io/hashbrown/serde/de/trait.Error.html#method.invalid_value)
1922// takes an Unexpected (https://rust-lang.github.io/hashbrown/serde/de/enum.Unexpected.html) which only accepts a 64 bit
1923// integer. This is a problem for us because we want to support 128 bit integers. To work around this we define our own
1924// error type using the Int's underlying type which implements Display and then use serde::de::Error::custom to create
1925// an error with our custom type.
1926#[cfg(feature = "serde")]
1927struct InvalidIntValueError<T: SignedInteger> {
1928 value: T::UnderlyingType,
1929}
1930
1931#[cfg(feature = "serde")]
1932impl<T: SignedInteger> Display for InvalidIntValueError<T> {
1933 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1934 write!(
1935 f,
1936 "invalid value: integer `{}`, expected a value between `{}` and `{}`",
1937 self.value,
1938 T::MIN.value(),
1939 T::MAX.value()
1940 )
1941 }
1942}
1943
1944#[cfg(feature = "serde")]
1945impl<T: SignedInteger + BuiltinInteger, const BITS: usize> serde::Serialize for Int<T, BITS>
1946where
1947 T: serde::Serialize,
1948{
1949 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1950 self.value.serialize(serializer)
1951 }
1952}
1953
1954#[cfg(feature = "serde")]
1955impl<'de, T: SignedInteger + BuiltinInteger, const BITS: usize> serde::Deserialize<'de>
1956 for Int<T, BITS>
1957where
1958 Self: SignedInteger<UnderlyingType = T>,
1959 T: serde::Deserialize<'de>,
1960{
1961 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1962 let value = T::deserialize(deserializer)?;
1963
1964 if value >= Self::MIN.value && value <= Self::MAX.value {
1965 Ok(Self { value })
1966 } else {
1967 let err = InvalidIntValueError::<Self> { value };
1968 Err(serde::de::Error::custom(err))
1969 }
1970 }
1971}
1972
1973// Implement `core::iter::Sum` and `core::iter::Product`.
1974impl_sum_product!(Int, 1_i8, SignedInteger);
1975
1976// Implement `core::iter::Step` (if the `step_trait` feature is enabled).
1977impl_step!(Int, SignedInteger);
1978
1979// Implement support for the `num-traits` crate, if the feature is enabled.
1980impl_num_traits!(Int, SignedInteger, i8, |value| (
1981 (value << Self::UNUSED_BITS) >> Self::UNUSED_BITS,
1982 value.clamp(Self::MIN.value(), Self::MAX.value())
1983));
1984
1985// Support for the `schemars` crate, if the feature is enabled.
1986impl_schemars!(Int, "int", SignedInteger);
1987
1988// Implement byte operations for Int's with a bit width aligned to a byte boundary.
1989bytes_operation_impl!(Int<i32, 24>, i32);
1990bytes_operation_impl!(Int<i64, 24>, i64);
1991bytes_operation_impl!(Int<i128, 24>, i128);
1992bytes_operation_impl!(Int<i64, 40>, i64);
1993bytes_operation_impl!(Int<i128, 40>, i128);
1994bytes_operation_impl!(Int<i64, 48>, i64);
1995bytes_operation_impl!(Int<i128, 48>, i128);
1996bytes_operation_impl!(Int<i64, 56>, i64);
1997bytes_operation_impl!(Int<i128, 56>, i128);
1998bytes_operation_impl!(Int<i128, 72>, i128);
1999bytes_operation_impl!(Int<i128, 80>, i128);
2000bytes_operation_impl!(Int<i128, 88>, i128);
2001bytes_operation_impl!(Int<i128, 96>, i128);
2002bytes_operation_impl!(Int<i128, 104>, i128);
2003bytes_operation_impl!(Int<i128, 112>, i128);
2004bytes_operation_impl!(Int<i128, 120>, i128);
2005
2006// Conversions
2007from_arbitrary_int_impl!(Int(i8), [i16, i32, i64, i128]);
2008from_arbitrary_int_impl!(Int(i16), [i8, i32, i64, i128]);
2009from_arbitrary_int_impl!(Int(i32), [i8, i16, i64, i128]);
2010from_arbitrary_int_impl!(Int(i64), [i8, i16, i32, i128]);
2011from_arbitrary_int_impl!(Int(i128), [i8, i32, i64, i16]);
2012
2013from_native_impl!(Int(i8), [i8, i16, i32, i64, i128]);
2014from_native_impl!(Int(i16), [i8, i16, i32, i64, i128]);
2015from_native_impl!(Int(i32), [i8, i16, i32, i64, i128]);
2016from_native_impl!(Int(i64), [i8, i16, i32, i64, i128]);
2017from_native_impl!(Int(i128), [i8, i16, i32, i64, i128]);
2018
2019use crate::common::{impl_borsh, impl_bytemuck_basic};
2020pub use aliases::*;
2021
2022#[allow(non_camel_case_types)]
2023#[rustfmt::skip]
2024pub(crate) mod aliases {
2025 use crate::common::type_alias;
2026
2027 type_alias!(Int(i8), (i1, 1), (i2, 2), (i3, 3), (i4, 4), (i5, 5), (i6, 6), (i7, 7));
2028 type_alias!(Int(i16), (i9, 9), (i10, 10), (i11, 11), (i12, 12), (i13, 13), (i14, 14), (i15, 15));
2029 type_alias!(Int(i32), (i17, 17), (i18, 18), (i19, 19), (i20, 20), (i21, 21), (i22, 22), (i23, 23), (i24, 24), (i25, 25), (i26, 26), (i27, 27), (i28, 28), (i29, 29), (i30, 30), (i31, 31));
2030 type_alias!(Int(i64), (i33, 33), (i34, 34), (i35, 35), (i36, 36), (i37, 37), (i38, 38), (i39, 39), (i40, 40), (i41, 41), (i42, 42), (i43, 43), (i44, 44), (i45, 45), (i46, 46), (i47, 47), (i48, 48), (i49, 49), (i50, 50), (i51, 51), (i52, 52), (i53, 53), (i54, 54), (i55, 55), (i56, 56), (i57, 57), (i58, 58), (i59, 59), (i60, 60), (i61, 61), (i62, 62), (i63, 63));
2031 type_alias!(Int(i128), (i65, 65), (i66, 66), (i67, 67), (i68, 68), (i69, 69), (i70, 70), (i71, 71), (i72, 72), (i73, 73), (i74, 74), (i75, 75), (i76, 76), (i77, 77), (i78, 78), (i79, 79), (i80, 80), (i81, 81), (i82, 82), (i83, 83), (i84, 84), (i85, 85), (i86, 86), (i87, 87), (i88, 88), (i89, 89), (i90, 90), (i91, 91), (i92, 92), (i93, 93), (i94, 94), (i95, 95), (i96, 96), (i97, 97), (i98, 98), (i99, 99), (i100, 100), (i101, 101), (i102, 102), (i103, 103), (i104, 104), (i105, 105), (i106, 106), (i107, 107), (i108, 108), (i109, 109), (i110, 110), (i111, 111), (i112, 112), (i113, 113), (i114, 114), (i115, 115), (i116, 116), (i117, 117), (i118, 118), (i119, 119), (i120, 120), (i121, 121), (i122, 122), (i123, 123), (i124, 124), (i125, 125), (i126, 126), (i127, 127));
2032}