1use core::mem::size_of;
6use core::num::Wrapping;
7
8pub trait ToPrimitive {
10 #[inline]
12 fn to_isize(&self) -> Option<isize> {
13 self.to_i64().as_ref().and_then(ToPrimitive::to_isize)
14 }
15
16 #[inline]
18 fn to_i8(&self) -> Option<i8> {
19 self.to_i64().as_ref().and_then(ToPrimitive::to_i8)
20 }
21
22 #[inline]
24 fn to_i16(&self) -> Option<i16> {
25 self.to_i64().as_ref().and_then(ToPrimitive::to_i16)
26 }
27
28 #[inline]
30 fn to_i32(&self) -> Option<i32> {
31 self.to_i64().as_ref().and_then(ToPrimitive::to_i32)
32 }
33
34 fn to_i64(&self) -> Option<i64>;
36
37 #[inline]
39 fn to_usize(&self) -> Option<usize> {
40 self.to_u64().as_ref().and_then(ToPrimitive::to_usize)
41 }
42
43 #[inline]
45 fn to_u8(&self) -> Option<u8> {
46 self.to_u64().as_ref().and_then(ToPrimitive::to_u8)
47 }
48
49 #[inline]
51 fn to_u16(&self) -> Option<u16> {
52 self.to_u64().as_ref().and_then(ToPrimitive::to_u16)
53 }
54
55 #[inline]
57 fn to_u32(&self) -> Option<u32> {
58 self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
59 }
60
61 fn to_u64(&self) -> Option<u64>;
63}
64
65macro_rules! impl_to_primitive_int_to_int {
66 ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
67 #[inline]
68 $(#[$cfg])*
69 fn $method(&self) -> Option<$DstT> {
70 let min = $DstT::MIN as $SrcT;
71 let max = $DstT::MAX as $SrcT;
72 if size_of::<$SrcT>() <= size_of::<$DstT>() || (min <= *self && *self <= max) {
73 Some(*self as $DstT)
74 } else {
75 None
76 }
77 }
78 )*}
79}
80
81macro_rules! impl_to_primitive_int_to_uint {
82 ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
83 #[inline]
84 $(#[$cfg])*
85 fn $method(&self) -> Option<$DstT> {
86 let max = $DstT::MAX as $SrcT;
87 if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
88 Some(*self as $DstT)
89 } else {
90 None
91 }
92 }
93 )*}
94}
95
96macro_rules! impl_to_primitive_int {
97 ($T:ident) => {
98 impl ToPrimitive for $T {
99 impl_to_primitive_int_to_int! { $T:
100 fn to_isize -> isize;
101 fn to_i8 -> i8;
102 fn to_i16 -> i16;
103 fn to_i32 -> i32;
104 fn to_i64 -> i64;
105 }
106
107 impl_to_primitive_int_to_uint! { $T:
108 fn to_usize -> usize;
109 fn to_u8 -> u8;
110 fn to_u16 -> u16;
111 fn to_u32 -> u32;
112 fn to_u64 -> u64;
113 }
114 }
115 };
116}
117
118impl_to_primitive_int!(isize);
119impl_to_primitive_int!(i8);
120impl_to_primitive_int!(i16);
121impl_to_primitive_int!(i32);
122impl_to_primitive_int!(i64);
123
124macro_rules! impl_to_primitive_uint_to_int {
125 ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
126 #[inline]
127 $(#[$cfg])*
128 fn $method(&self) -> Option<$DstT> {
129 let max = $DstT::MAX as $SrcT;
130 if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
131 Some(*self as $DstT)
132 } else {
133 None
134 }
135 }
136 )*}
137}
138
139macro_rules! impl_to_primitive_uint_to_uint {
140 ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
141 #[inline]
142 $(#[$cfg])*
143 fn $method(&self) -> Option<$DstT> {
144 let max = $DstT::MAX as $SrcT;
145 if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
146 Some(*self as $DstT)
147 } else {
148 None
149 }
150 }
151 )*}
152}
153
154macro_rules! impl_to_primitive_uint {
155 ($T:ident) => {
156 impl ToPrimitive for $T {
157 impl_to_primitive_uint_to_int! { $T:
158 fn to_isize -> isize;
159 fn to_i8 -> i8;
160 fn to_i16 -> i16;
161 fn to_i32 -> i32;
162 fn to_i64 -> i64;
163 }
164
165 impl_to_primitive_uint_to_uint! { $T:
166 fn to_usize -> usize;
167 fn to_u8 -> u8;
168 fn to_u16 -> u16;
169 fn to_u32 -> u32;
170 fn to_u64 -> u64;
171 }
172 }
173 };
174}
175
176impl_to_primitive_uint!(usize);
177impl_to_primitive_uint!(u8);
178impl_to_primitive_uint!(u16);
179impl_to_primitive_uint!(u32);
180impl_to_primitive_uint!(u64);
181
182pub trait FromPrimitive: Sized {
184 #[inline]
187 fn from_isize(n: isize) -> Option<Self> {
188 n.to_i64().and_then(FromPrimitive::from_i64)
189 }
190
191 #[inline]
194 fn from_i8(n: i8) -> Option<Self> {
195 FromPrimitive::from_i64(From::from(n))
196 }
197
198 #[inline]
201 fn from_i16(n: i16) -> Option<Self> {
202 FromPrimitive::from_i64(From::from(n))
203 }
204
205 #[inline]
208 fn from_i32(n: i32) -> Option<Self> {
209 FromPrimitive::from_i64(From::from(n))
210 }
211
212 fn from_i64(n: i64) -> Option<Self>;
215
216 #[inline]
219 fn from_usize(n: usize) -> Option<Self> {
220 n.to_u64().and_then(FromPrimitive::from_u64)
221 }
222
223 #[inline]
226 fn from_u8(n: u8) -> Option<Self> {
227 FromPrimitive::from_u64(From::from(n))
228 }
229
230 #[inline]
233 fn from_u16(n: u16) -> Option<Self> {
234 FromPrimitive::from_u64(From::from(n))
235 }
236
237 #[inline]
240 fn from_u32(n: u32) -> Option<Self> {
241 FromPrimitive::from_u64(From::from(n))
242 }
243
244 fn from_u64(n: u64) -> Option<Self>;
247}
248
249macro_rules! impl_from_primitive {
250 ($T:ty, $to_ty:ident) => {
251 #[allow(deprecated)]
252 impl FromPrimitive for $T {
253 #[inline]
254 fn from_isize(n: isize) -> Option<$T> {
255 n.$to_ty()
256 }
257 #[inline]
258 fn from_i8(n: i8) -> Option<$T> {
259 n.$to_ty()
260 }
261 #[inline]
262 fn from_i16(n: i16) -> Option<$T> {
263 n.$to_ty()
264 }
265 #[inline]
266 fn from_i32(n: i32) -> Option<$T> {
267 n.$to_ty()
268 }
269 #[inline]
270 fn from_i64(n: i64) -> Option<$T> {
271 n.$to_ty()
272 }
273
274 #[inline]
275 fn from_usize(n: usize) -> Option<$T> {
276 n.$to_ty()
277 }
278 #[inline]
279 fn from_u8(n: u8) -> Option<$T> {
280 n.$to_ty()
281 }
282 #[inline]
283 fn from_u16(n: u16) -> Option<$T> {
284 n.$to_ty()
285 }
286 #[inline]
287 fn from_u32(n: u32) -> Option<$T> {
288 n.$to_ty()
289 }
290 #[inline]
291 fn from_u64(n: u64) -> Option<$T> {
292 n.$to_ty()
293 }
294 }
295 };
296}
297
298impl_from_primitive!(isize, to_isize);
299impl_from_primitive!(i8, to_i8);
300impl_from_primitive!(i16, to_i16);
301impl_from_primitive!(i32, to_i32);
302impl_from_primitive!(i64, to_i64);
303impl_from_primitive!(usize, to_usize);
304impl_from_primitive!(u8, to_u8);
305impl_from_primitive!(u16, to_u16);
306impl_from_primitive!(u32, to_u32);
307impl_from_primitive!(u64, to_u64);
308
309macro_rules! impl_to_primitive_wrapping {
310 ($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
311 #[inline]
312 $(#[$cfg])*
313 fn $method(&self) -> Option<$i> {
314 (self.0).$method()
315 }
316 )*}
317}
318
319impl<T: ToPrimitive> ToPrimitive for Wrapping<T> {
320 impl_to_primitive_wrapping! {
321 fn to_isize -> isize;
322 fn to_i8 -> i8;
323 fn to_i16 -> i16;
324 fn to_i32 -> i32;
325 fn to_i64 -> i64;
326
327 fn to_usize -> usize;
328 fn to_u8 -> u8;
329 fn to_u16 -> u16;
330 fn to_u32 -> u32;
331 fn to_u64 -> u64;
332 }
333}
334
335macro_rules! impl_from_primitive_wrapping {
336 ($( $(#[$cfg:meta])* fn $method:ident ( $i:ident ); )*) => {$(
337 #[inline]
338 $(#[$cfg])*
339 fn $method(n: $i) -> Option<Self> {
340 T::$method(n).map(Wrapping)
341 }
342 )*}
343}
344
345impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
346 impl_from_primitive_wrapping! {
347 fn from_isize(isize);
348 fn from_i8(i8);
349 fn from_i16(i16);
350 fn from_i32(i32);
351 fn from_i64(i64);
352 fn from_usize(usize);
353 fn from_u8(u8);
354 fn from_u16(u16);
355 fn from_u32(u32);
356 fn from_u64(u64);
357 }
358}