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 {}