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