Skip to main content

arbitrary_int/
traits.rs

1use crate::TryNewError;
2use core::fmt::{Binary, Debug, Display, LowerHex, Octal, UpperHex};
3use core::ops::{
4    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
5    Mul, MulAssign, Neg, Not, Sub, SubAssign,
6};
7
8pub(crate) mod sealed {
9    /// Ensures that outside users can not implement the traits provided by this crate.
10    pub trait Sealed {}
11}
12
13/// Trait that is only implemented for `u8`, `u16`, `u32`, `u64`, `u128` and their signed
14/// counterparts `i8`, `i16`, `i32`, `i64`, `i128`.
15pub trait BuiltinInteger: sealed::Sealed {}
16
17/// The base trait for integer numbers, either built-in (u8, i8, u16, i16, u32, i32, u64, i64,
18/// u128, i128) or arbitrary-int (u1, i1, u7, i7 etc.).
19pub trait Integer:
20    Sized
21    + Copy
22    + Clone
23    + PartialOrd
24    + Ord
25    + PartialEq
26    + Eq
27    + Debug
28    + Display
29    + LowerHex
30    + UpperHex
31    + Octal
32    + Binary
33    + sealed::Sealed
34    + Add<Self, Output = Self>
35    + AddAssign<Self>
36    + Sub<Self, Output = Self>
37    + SubAssign<Self>
38    + Div<Self, Output = Self>
39    + DivAssign<Self>
40    + Mul<Self, Output = Self>
41    + MulAssign<Self>
42    + Not<Output = Self>
43    + BitAnd<Self, Output = Self>
44    + BitAndAssign<Self>
45    + BitOr<Self, Output = Self>
46    + BitOrAssign<Self>
47    + BitXor<Self, Output = Self>
48    + BitXorAssign<Self>
49{
50    type UnderlyingType: Integer
51        + BuiltinInteger
52        + Debug
53        + TryFrom<u8>
54        + TryFrom<u16>
55        + TryFrom<u32>
56        + TryFrom<u64>
57        + TryFrom<u128>;
58
59    /// An equivalent type with the same number of bits but unsigned. If
60    /// the type is already unsigned, this is the same type.
61    /// - i4::UnsignedInteger == u4
62    /// - u60::SignedInteger == u60
63    type UnsignedInteger: UnsignedInteger;
64
65    /// An equivalent type with the same number of bits but signed. If
66    /// the type is already signed, this is the same type.
67    /// - i4::UnsignedInteger == i4
68    /// - u60::SignedInteger == i60
69    type SignedInteger: SignedInteger;
70
71    /// Number of bits that can fit in this type
72    const BITS: usize;
73
74    /// The number 0
75    const ZERO: Self;
76
77    /// Minimum value that can be represented by this type
78    const MIN: Self;
79
80    /// Maximum value that can be represented by this type
81    const MAX: Self;
82
83    /// Creates a number from the given value, throwing an error if the value is too large.
84    /// This constructor is useful when creating a value from a literal.
85    fn new(value: Self::UnderlyingType) -> Self;
86
87    /// Creates a number from the given value, return None if the value is too large
88    fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError>;
89
90    fn value(self) -> Self::UnderlyingType;
91
92    /// Creates a number from the given value, throwing an error if the value is too large.
93    /// This constructor is useful when the value is convertible to T. Use [`Self::new`] for literals.
94    fn from_<T: Integer>(value: T) -> Self;
95
96    /// Creates an instance from the given `value`. Unlike the various `new...` functions, this
97    /// will never fail as the value is masked to the result size.
98    fn masked_new<T: Integer>(value: T) -> Self;
99
100    fn as_u8(self) -> u8;
101
102    fn as_u16(self) -> u16;
103
104    fn as_u32(self) -> u32;
105
106    fn as_u64(self) -> u64;
107
108    fn as_u128(self) -> u128;
109
110    fn as_usize(self) -> usize;
111
112    fn as_i8(self) -> i8;
113
114    fn as_i16(self) -> i16;
115
116    fn as_i32(self) -> i32;
117
118    fn as_i64(self) -> i64;
119
120    fn as_i128(self) -> i128;
121
122    fn as_isize(self) -> isize;
123
124    /// Converts the number to its unsigned equivalent. For types that have fewer bits
125    /// than the underlying type, this involves a zero extension. Types that are
126    /// already unsigned will return themselves.
127    fn to_unsigned(self) -> Self::UnsignedInteger;
128
129    /// Converts the number from its unsigned equivalent. For types that have fewer bits
130    /// than the underlying type, this involves a sign extension, if this type is a signed type.
131    /// Types that are already unsigned will return themselves.
132    fn from_unsigned(value: Self::UnsignedInteger) -> Self;
133
134    #[inline]
135    fn as_<T: Integer>(self) -> T {
136        T::masked_new(self)
137    }
138}
139
140/// The base trait for all signed numbers, either built-in (i8, i16, i32, i64, i128) or
141/// arbitrary-int (i1, i7 etc.).
142pub trait SignedInteger: Integer + Neg<Output = Self> {}
143
144/// The base trait for all unsigned numbers, either built-in (u8, u16, u32, u64, u128) or
145/// arbitrary-int (u1, u7 etc.).
146pub trait UnsignedInteger: Integer {}