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 const IS_SIGNED: bool;
84
85 /// Creates a number from the given value, throwing an error if the value is too large.
86 /// This constructor is useful when creating a value from a literal.
87 fn new(value: Self::UnderlyingType) -> Self;
88
89 /// Creates a number from the given value, return None if the value is too large
90 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError>;
91
92 fn value(self) -> Self::UnderlyingType;
93
94 /// Creates a number from the given value, throwing an error if the value is too large.
95 /// This constructor is useful when the value is convertible to T. Use [`Self::new`] for literals.
96 fn from_<T: Integer>(value: T) -> Self;
97
98 /// Creates an instance from the given `value`. Unlike the various `new...` functions, this
99 /// will never fail as the value is masked to the result size.
100 ///
101 /// If the source value is a signed integer and the target has more bits, the value is
102 /// sign-extended. For example, `u5::masked_new(i4::new(-1)) == u5::new(0b1_1111)`.
103 fn masked_new<T: Integer>(value: T) -> Self;
104
105 fn as_u8(self) -> u8;
106
107 fn as_u16(self) -> u16;
108
109 fn as_u32(self) -> u32;
110
111 fn as_u64(self) -> u64;
112
113 fn as_u128(self) -> u128;
114
115 fn as_usize(self) -> usize;
116
117 fn as_i8(self) -> i8;
118
119 fn as_i16(self) -> i16;
120
121 fn as_i32(self) -> i32;
122
123 fn as_i64(self) -> i64;
124
125 fn as_i128(self) -> i128;
126
127 fn as_isize(self) -> isize;
128
129 /// Converts the number to its unsigned equivalent. For types that have fewer bits
130 /// than the underlying type, this involves a zero extension. Types that are
131 /// already unsigned will return themselves.
132 fn to_unsigned(self) -> Self::UnsignedInteger;
133
134 /// Converts the number from its unsigned equivalent. For types that have fewer bits
135 /// than the underlying type, this involves a sign extension, if this type is a signed type.
136 /// Types that are already unsigned will return themselves.
137 fn from_unsigned(value: Self::UnsignedInteger) -> Self;
138
139 #[inline]
140 fn as_<T: Integer>(self) -> T {
141 T::masked_new(self)
142 }
143}
144
145/// The base trait for all signed numbers, either built-in (i8, i16, i32, i64, i128) or
146/// arbitrary-int (i1, i7 etc.).
147pub trait SignedInteger: Integer + Neg<Output = Self> {}
148
149/// The base trait for all unsigned numbers, either built-in (u8, u16, u32, u64, u128) or
150/// arbitrary-int (u1, u7 etc.).
151pub trait UnsignedInteger: Integer {}