1use crate::{
11 iif, isize_down, isize_up, paste, usize_down, usize_up, Cast,
12 NumError::Overflow,
13 NumResult as Result,
14 Sign::{Negative, Positive},
15};
16
17pub trait PrimitiveCast {
24 fn checked_cast_to_u8(self) -> Result<u8>;
28 fn checked_cast_to_u16(self) -> Result<u16>;
30 fn checked_cast_to_u32(self) -> Result<u32>;
32 fn checked_cast_to_u64(self) -> Result<u64>;
34 fn checked_cast_to_u128(self) -> Result<u128>;
36 fn checked_cast_to_usize(self) -> Result<usize>;
38 fn checked_cast_to_usize_up(self) -> Result<usize_up>;
40 fn checked_cast_to_usize_down(self) -> Result<usize_down>;
42
43 fn checked_cast_to_i8(self) -> Result<i8>;
45 fn checked_cast_to_i16(self) -> Result<i16>;
47 fn checked_cast_to_i32(self) -> Result<i32>;
49 fn checked_cast_to_i64(self) -> Result<i64>;
51 fn checked_cast_to_i128(self) -> Result<i128>;
53 fn checked_cast_to_isize(self) -> Result<isize>;
55 fn checked_cast_to_isize_up(self) -> Result<isize_up>;
57 fn checked_cast_to_isize_down(self) -> Result<isize_down>;
59
60 #[must_use]
64 fn saturating_cast_to_u8(self) -> u8;
65 #[must_use]
67 fn saturating_cast_to_u16(self) -> u16;
68 #[must_use]
70 fn saturating_cast_to_u32(self) -> u32;
71 #[must_use]
73 fn saturating_cast_to_u64(self) -> u64;
74 #[must_use]
76 fn saturating_cast_to_u128(self) -> u128;
77 #[must_use]
79 fn saturating_cast_to_usize(self) -> usize;
80 #[must_use]
82 fn saturating_cast_to_usize_up(self) -> usize_up;
83 #[must_use]
85 fn saturating_cast_to_usize_down(self) -> usize_down;
86
87 #[must_use]
89 fn saturating_cast_to_i8(self) -> i8;
90 #[must_use]
92 fn saturating_cast_to_i16(self) -> i16;
93 #[must_use]
95 fn saturating_cast_to_i32(self) -> i32;
96 #[must_use]
98 fn saturating_cast_to_i64(self) -> i64;
99 #[must_use]
101 fn saturating_cast_to_i128(self) -> i128;
102 #[must_use]
104 fn saturating_cast_to_isize(self) -> isize;
105 #[must_use]
107 fn saturating_cast_to_isize_up(self) -> isize_up;
108 #[must_use]
110 fn saturating_cast_to_isize_down(self) -> isize_down;
111
112 #[must_use]
116 fn wrapping_cast_to_u8(self) -> u8;
117 #[must_use]
119 fn wrapping_cast_to_u16(self) -> u16;
120 #[must_use]
122 fn wrapping_cast_to_u32(self) -> u32;
123 #[must_use]
125 fn wrapping_cast_to_u64(self) -> u64;
126 #[must_use]
128 fn wrapping_cast_to_u128(self) -> u128;
129 #[must_use]
131 fn wrapping_cast_to_usize(self) -> usize;
132 #[must_use]
134 fn wrapping_cast_to_usize_up(self) -> usize_up;
135 #[must_use]
137 fn wrapping_cast_to_usize_down(self) -> usize_down;
138
139 #[must_use]
141 fn wrapping_cast_to_i8(self) -> i8;
142 #[must_use]
144 fn wrapping_cast_to_i16(self) -> i16;
145 #[must_use]
147 fn wrapping_cast_to_i32(self) -> i32;
148 #[must_use]
150 fn wrapping_cast_to_i64(self) -> i64;
151 #[must_use]
153 fn wrapping_cast_to_i128(self) -> i128;
154 #[must_use]
156 fn wrapping_cast_to_isize(self) -> isize;
157 #[must_use]
159 fn wrapping_cast_to_isize_up(self) -> isize_up;
160 #[must_use]
162 fn wrapping_cast_to_isize_down(self) -> isize_down;
163}
164
165macro_rules! impl_cast_methods {
167 ($($t:ty),+) => { $( impl_cast_methods![@$t]; )+ };
168 (@$t:ty) => { paste! {
169 impl PrimitiveCast for $t {
170 fn checked_cast_to_u8(self) -> Result<u8> { [<checked_cast_ $t _to_u8>](self) }
171 fn checked_cast_to_u16(self) -> Result<u16> { [<checked_cast_ $t _to_u16>](self) }
172 fn checked_cast_to_u32(self) -> Result<u32> { [<checked_cast_ $t _to_u32>](self) }
173 fn checked_cast_to_u64(self) -> Result<u64> { [<checked_cast_ $t _to_u64>](self) }
174 fn checked_cast_to_u128(self) -> Result<u128> { [<checked_cast_ $t _to_u128>](self) }
175 fn checked_cast_to_usize(self) -> Result<usize> { [<checked_cast_ $t _to_usize>](self) }
176 fn checked_cast_to_usize_up(self) -> Result<usize_up> {
177 [<checked_cast_ $t _to_usize_up>](self) }
178 fn checked_cast_to_usize_down(self) -> Result<usize_down> {
179 [<checked_cast_ $t _to_usize_down>](self) }
180
181 fn checked_cast_to_i8(self) -> Result<i8> { [<checked_cast_ $t _to_i8>](self) }
182 fn checked_cast_to_i16(self) -> Result<i16> { [<checked_cast_ $t _to_i16>](self) }
183 fn checked_cast_to_i32(self) -> Result<i32> { [<checked_cast_ $t _to_i32>](self) }
184 fn checked_cast_to_i64(self) -> Result<i64> { [<checked_cast_ $t _to_i64>](self) }
185 fn checked_cast_to_i128(self) -> Result<i128> { [<checked_cast_ $t _to_i128>](self) }
186 fn checked_cast_to_isize(self) -> Result<isize> { [<checked_cast_ $t _to_isize>](self) }
187 fn checked_cast_to_isize_up(self) -> Result<isize_up> {
188 [<checked_cast_ $t _to_isize_up>](self) }
189 fn checked_cast_to_isize_down(self) -> Result<isize_down> {
190 [<checked_cast_ $t _to_isize_down>](self) }
191
192 fn saturating_cast_to_u8(self) -> u8 { [<saturating_cast_ $t _to_u8>](self) }
193 fn saturating_cast_to_u16(self) -> u16 { [<saturating_cast_ $t _to_u16>](self) }
194 fn saturating_cast_to_u32(self) -> u32 { [<saturating_cast_ $t _to_u32>](self) }
195 fn saturating_cast_to_u64(self) -> u64 { [<saturating_cast_ $t _to_u64>](self) }
196 fn saturating_cast_to_u128(self) -> u128 { [<saturating_cast_ $t _to_u128>](self) }
197 fn saturating_cast_to_usize(self) -> usize { [<saturating_cast_ $t _to_usize>](self) }
198 fn saturating_cast_to_usize_up(self) -> usize_up {
199 [<saturating_cast_ $t _to_usize_up>](self) }
200 fn saturating_cast_to_usize_down(self) -> usize_down {
201 [<saturating_cast_ $t _to_usize_down>](self) }
202
203 fn saturating_cast_to_i8(self) -> i8 { [<saturating_cast_ $t _to_i8>](self) }
204 fn saturating_cast_to_i16(self) -> i16 { [<saturating_cast_ $t _to_i16>](self) }
205 fn saturating_cast_to_i32(self) -> i32 { [<saturating_cast_ $t _to_i32>](self) }
206 fn saturating_cast_to_i64(self) -> i64 { [<saturating_cast_ $t _to_i64>](self) }
207 fn saturating_cast_to_i128(self) -> i128 { [<saturating_cast_ $t _to_i128>](self) }
208 fn saturating_cast_to_isize(self) -> isize { [<saturating_cast_ $t _to_isize>](self) }
209 fn saturating_cast_to_isize_up(self) -> isize_up {
210 [<saturating_cast_ $t _to_isize_up>](self) }
211 fn saturating_cast_to_isize_down(self) -> isize_down {
212 [<saturating_cast_ $t _to_isize_down>](self) }
213
214 fn wrapping_cast_to_u8(self) -> u8 { [<wrapping_cast_ $t _to_u8>](self) }
215 fn wrapping_cast_to_u16(self) -> u16 { [<wrapping_cast_ $t _to_u16>](self) }
216 fn wrapping_cast_to_u32(self) -> u32 { [<wrapping_cast_ $t _to_u32>](self) }
217 fn wrapping_cast_to_u64(self) -> u64 { [<wrapping_cast_ $t _to_u64>](self) }
218 fn wrapping_cast_to_u128(self) -> u128 { [<wrapping_cast_ $t _to_u128>](self) }
219 fn wrapping_cast_to_usize(self) -> usize { [<wrapping_cast_ $t _to_usize>](self) }
220 fn wrapping_cast_to_usize_up(self) -> usize_up {
221 [<wrapping_cast_ $t _to_usize_up>](self) }
222 fn wrapping_cast_to_usize_down(self) -> usize_down {
223 [<wrapping_cast_ $t _to_usize_down>](self) }
224
225 fn wrapping_cast_to_i8(self) -> i8 { [<wrapping_cast_ $t _to_i8>](self) }
226 fn wrapping_cast_to_i16(self) -> i16 { [<wrapping_cast_ $t _to_i16>](self) }
227 fn wrapping_cast_to_i32(self) -> i32 { [<wrapping_cast_ $t _to_i32>](self) }
228 fn wrapping_cast_to_i64(self) -> i64 { [<wrapping_cast_ $t _to_i64>](self) }
229 fn wrapping_cast_to_i128(self) -> i128 { [<wrapping_cast_ $t _to_i128>](self) }
230 fn wrapping_cast_to_isize(self) -> isize { [<wrapping_cast_ $t _to_isize>](self) }
231 fn wrapping_cast_to_isize_up(self) -> isize_up {
232 [<wrapping_cast_ $t _to_isize_up>](self) }
233 fn wrapping_cast_to_isize_down(self) -> isize_down {
234 [<wrapping_cast_ $t _to_isize_down>](self) }
235 }
236
237 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "cast")))]
242 impl Cast<$t> {
243 #[doc = "Casts from `" $t "` to `u8` with range check."]
246 pub const fn checked_cast_to_u8(self) -> Result<u8> {
247 [<checked_cast_ $t _to_u8>](self.0)
248 }
249 #[doc = "Casts from `" $t "` to `u16` with range check."]
250 pub const fn checked_cast_to_u16(self) -> Result<u16> {
251 [<checked_cast_ $t _to_u16>](self.0)
252 }
253 #[doc = "Casts from `" $t "` to `u32` with range check."]
254 pub const fn checked_cast_to_u32(self) -> Result<u32> {
255 [<checked_cast_ $t _to_u32>](self.0)
256 }
257 #[doc = "Casts from `" $t "` to `u64` with range check."]
258 pub const fn checked_cast_to_u64(self) -> Result<u64> {
259 [<checked_cast_ $t _to_u64>](self.0)
260 }
261 #[doc = "Casts from `" $t "` to `u128` with range check."]
262 pub const fn checked_cast_to_u128(self) -> Result<u128> {
263 [<checked_cast_ $t _to_u128>](self.0)
264 }
265 #[doc = "Casts from `" $t "` to `usize` with range check."]
266 pub const fn checked_cast_to_usize(self) -> Result<usize> {
267 [<checked_cast_ $t _to_usize>](self.0)
268 }
269 #[doc = "Casts from `" $t "` to `usize_up` with range check."]
270 pub const fn checked_cast_to_usize_up(self) -> Result<usize_up> {
271 [<checked_cast_ $t _to_usize_up>](self.0)
272 }
273 #[doc = "Casts from `" $t "` to `usize_down` with range check."]
274 pub const fn checked_cast_to_usize_down(self) -> Result<usize_down> {
275 [<checked_cast_ $t _to_usize_down>](self.0)
276 }
277
278 #[doc = "Casts from `" $t "` to `i8` with range check."]
279 pub const fn checked_cast_to_i8(self) -> Result<i8> {
280 [<checked_cast_ $t _to_i8>](self.0)
281 }
282 #[doc = "Casts from `" $t "` to `i16` with range check."]
283 pub const fn checked_cast_to_i16(self) -> Result<i16> {
284 [<checked_cast_ $t _to_i16>](self.0)
285 }
286 #[doc = "Casts from `" $t "` to `i32` with range check."]
287 pub const fn checked_cast_to_i32(self) -> Result<i32> {
288 [<checked_cast_ $t _to_i32>](self.0)
289 }
290 #[doc = "Casts from `" $t "` to `i64` with range check."]
291 pub const fn checked_cast_to_i64(self) -> Result<i64> {
292 [<checked_cast_ $t _to_i64>](self.0)
293 }
294 #[doc = "Casts from `" $t "` to `i128` with range check."]
295 pub const fn checked_cast_to_i128(self) -> Result<i128> {
296 [<checked_cast_ $t _to_i128>](self.0)
297 }
298 #[doc = "Casts from `" $t "` to `isize` with range check."]
299 pub const fn checked_cast_to_isize(self) -> Result<isize> {
300 [<checked_cast_ $t _to_isize>](self.0)
301 }
302 #[doc = "Casts from `" $t "` to `isize_up` with range check."]
303 pub const fn checked_cast_to_isize_up(self) -> Result<isize_up> {
304 [<checked_cast_ $t _to_isize_up>](self.0)
305 }
306 #[doc = "Casts from `" $t "` to `isize_down` with range check."]
307 pub const fn checked_cast_to_isize_down(self) -> Result<isize_down> {
308 [<checked_cast_ $t _to_isize_down>](self.0)
309 }
310
311 #[doc = "Casts from `" $t "` to `u8` clamping at the numeric bounds."]
314 #[must_use]
315 pub const fn saturating_cast_to_u8(self) -> u8 {
316 [<saturating_cast_ $t _to_u8>](self.0)
317 }
318 #[doc = "Casts from `" $t "` to `u16` clamping at the numeric bounds."]
319 #[must_use]
320 pub const fn saturating_cast_to_u16(self) -> u16 {
321 [<saturating_cast_ $t _to_u16>](self.0)
322 }
323 #[doc = "Casts from `" $t "` to `u32` clamping at the numeric bounds."]
324 #[must_use]
325 pub const fn saturating_cast_to_u32(self) -> u32 {
326 [<saturating_cast_ $t _to_u32>](self.0)
327 }
328 #[doc = "Casts from `" $t "` to `u64` clamping at the numeric bounds."]
329 #[must_use]
330 pub const fn saturating_cast_to_u64(self) -> u64 {
331 [<saturating_cast_ $t _to_u64>](self.0)
332 }
333 #[doc = "Casts from `" $t "` to `u128` clamping at the numeric bounds."]
334 #[must_use]
335 pub const fn saturating_cast_to_u128(self) -> u128 {
336 [<saturating_cast_ $t _to_u128>](self.0)
337 }
338 #[doc = "Casts from `" $t "` to `usize` clamping at the numeric bounds."]
339 #[must_use]
340 pub const fn saturating_cast_to_usize(self) -> usize {
341 [<saturating_cast_ $t _to_usize>](self.0)
342 }
343 #[doc = "Casts from `" $t "` to `usize_up` clamping at the numeric bounds."]
344 #[must_use]
345 pub const fn saturating_cast_to_usize_up(self) -> usize_up {
346 [<saturating_cast_ $t _to_usize_up>](self.0)
347 }
348 #[doc = "Casts from `" $t "` to `usize_down` clamping at the numeric bounds."]
349 #[must_use]
350 pub const fn saturating_cast_to_usize_down(self) -> usize_down {
351 [<saturating_cast_ $t _to_usize_down>](self.0)
352 }
353
354 #[doc = "Casts from `" $t "` to `i8` clamping at the numeric bounds."]
355 #[must_use]
356 pub const fn saturating_cast_to_i8(self) -> i8 {
357 [<saturating_cast_ $t _to_i8>](self.0)
358 }
359 #[doc = "Casts from `" $t "` to `i16` clamping at the numeric bounds."]
360 #[must_use]
361 pub const fn saturating_cast_to_i16(self) -> i16 {
362 [<saturating_cast_ $t _to_i16>](self.0)
363 }
364 #[doc = "Casts from `" $t "` to `i32` clamping at the numeric bounds."]
365 #[must_use]
366 pub const fn saturating_cast_to_i32(self) -> i32 {
367 [<saturating_cast_ $t _to_i32>](self.0)
368 }
369 #[doc = "Casts from `" $t "` to `i64` clamping at the numeric bounds."]
370 #[must_use]
371 pub const fn saturating_cast_to_i64(self) -> i64 {
372 [<saturating_cast_ $t _to_i64>](self.0)
373 }
374 #[doc = "Casts from `" $t "` to `i128` clamping at the numeric bounds."]
375 #[must_use]
376 pub const fn saturating_cast_to_i128(self) -> i128 {
377 [<saturating_cast_ $t _to_i128>](self.0)
378 }
379 #[doc = "Casts from `" $t "` to `isize` clamping at the numeric bounds."]
380 #[must_use]
381 pub const fn saturating_cast_to_isize(self) -> isize {
382 [<saturating_cast_ $t _to_isize>](self.0)
383 }
384 #[doc = "Casts from `" $t "` to `isize_up` clamping at the numeric bounds."]
385 #[must_use]
386 pub const fn saturating_cast_to_isize_up(self) -> isize_up {
387 [<saturating_cast_ $t _to_isize_up>](self.0)
388 }
389 #[doc = "Casts from `" $t "` to `isize_down` clamping at the numeric bounds."]
390 #[must_use]
391 pub const fn saturating_cast_to_isize_down(self) -> isize_down {
392 [<saturating_cast_ $t _to_isize_down>](self.0)
393 }
394
395 #[doc = "Casts from `" $t "` to `u8` wrapping at the numeric bounds."]
398 #[must_use]
399 pub const fn wrapping_cast_to_u8(self) -> u8 {
400 [<wrapping_cast_ $t _to_u8>](self.0)
401 }
402 #[doc = "Casts from `" $t "` to `u16` wrapping at the numeric bounds."]
403 #[must_use]
404 pub const fn wrapping_cast_to_u16(self) -> u16 {
405 [<wrapping_cast_ $t _to_u16>](self.0)
406 }
407 #[doc = "Casts from `" $t "` to `u32` wrapping at the numeric bounds."]
408 #[must_use]
409 pub const fn wrapping_cast_to_u32(self) -> u32 {
410 [<wrapping_cast_ $t _to_u32>](self.0)
411 }
412 #[doc = "Casts from `" $t "` to `u64` wrapping at the numeric bounds."]
413 #[must_use]
414 pub const fn wrapping_cast_to_u64(self) -> u64 {
415 [<wrapping_cast_ $t _to_u64>](self.0)
416 }
417 #[doc = "Casts from `" $t "` to `u128` wrapping at the numeric bounds."]
418 #[must_use]
419 pub const fn wrapping_cast_to_u128(self) -> u128 {
420 [<wrapping_cast_ $t _to_u128>](self.0)
421 }
422 #[doc = "Casts from `" $t "` to `usize` wrapping at the numeric bounds."]
423 #[must_use]
424 pub const fn wrapping_cast_to_usize(self) -> usize {
425 [<wrapping_cast_ $t _to_usize>](self.0)
426 }
427 #[doc = "Casts from `" $t "` to `usize_up` wrapping at the numeric bounds."]
428 #[must_use]
429 pub const fn wrapping_cast_to_usize_up(self) -> usize_up {
430 [<wrapping_cast_ $t _to_usize_up>](self.0)
431 }
432 #[doc = "Casts from `" $t "` to `usize_down` wrapping at the numeric bounds."]
433 #[must_use]
434 pub const fn wrapping_cast_to_usize_down(self) -> usize_down {
435 [<wrapping_cast_ $t _to_usize_down>](self.0)
436 }
437
438 #[doc = "Casts from `" $t "` to `i8` wrapping at the numeric bounds."]
439 #[must_use]
440 pub const fn wrapping_cast_to_i8(self) -> i8 {
441 [<wrapping_cast_ $t _to_i8>](self.0)
442 }
443 #[doc = "Casts from `" $t "` to `i16` wrapping at the numeric bounds."]
444 #[must_use]
445 pub const fn wrapping_cast_to_i16(self) -> i16 {
446 [<wrapping_cast_ $t _to_i16>](self.0)
447 }
448 #[doc = "Casts from `" $t "` to `i32` wrapping at the numeric bounds."]
449 #[must_use]
450 pub const fn wrapping_cast_to_i32(self) -> i32 {
451 [<wrapping_cast_ $t _to_i32>](self.0)
452 }
453 #[doc = "Casts from `" $t "` to `i64` wrapping at the numeric bounds."]
454 #[must_use]
455 pub const fn wrapping_cast_to_i64(self) -> i64 {
456 [<wrapping_cast_ $t _to_i64>](self.0)
457 }
458 #[doc = "Casts from `" $t "` to `i128` wrapping at the numeric bounds."]
459 #[must_use]
460 pub const fn wrapping_cast_to_i128(self) -> i128 {
461 [<wrapping_cast_ $t _to_i128>](self.0)
462 }
463 #[doc = "Casts from `" $t "` to `isize` wrapping at the numeric bounds."]
464 #[must_use]
465 pub const fn wrapping_cast_to_isize(self) -> isize {
466 [<wrapping_cast_ $t _to_isize>](self.0)
467 }
468 #[doc = "Casts from `" $t "` to `isize_up` wrapping at the numeric bounds."]
469 #[must_use]
470 pub const fn wrapping_cast_to_isize_up(self) -> isize_up {
471 [<wrapping_cast_ $t _to_isize_up>](self.0)
472 }
473 #[doc = "Casts from `" $t "` to `isize_down` wrapping at the numeric bounds."]
474 #[must_use]
475 pub const fn wrapping_cast_to_isize_down(self) -> isize_down {
476 [<wrapping_cast_ $t _to_isize_down>](self.0)
477 }
478 }
479 }};
480}
481impl_cast_methods![u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize];
482
483macro_rules! impl_cast_fns {
489 () => {
490 impl_cast_fns![can_overunderflow
493 i16|u16:u8, i32|u32:u8, i64|u64:u8, i128|u128:u8,
495 i32|u32:u16, i64|u64:u16, i128|u128:u16,
496 i64|u64:u32, i128|u128:u32,
497 i128|u128:u64,
498 i16|u16:i8, i32|u32:i8, i64|u64:i8, i128|u128:i8,
500 i32|u32:i16, i64|u64:i16, i128|u128:i16,
501 i64|u64:i32, i128|u128:i32,
502 i128|u128:i64
503 ];
504 impl_cast_fns![can_overflow
505 u16:u8, u32:u8, u64:u8, u128:u8,
507 u32:u16, u64:u16, u128:u16,
508 u64:u32, u128:u32,
509 u128:u64,
510 u16:i8, u32:i8, u64:i8, u128:i8,
512 u32:i16, u64:i16, u128:i16,
513 u64:i32, u128:i32,
514 u128:i64,
515 u8:i8, u16:i16, u32:i32, u64:i64, u128:i128, usize:isize
517 ];
518 impl_cast_fns![can_underflow
519 i8:u16, i8:u32, i8:u64, i8:u128,
521 i16:u32, i16:u64, i16:u128,
522 i32:u64, i32:u128,
523 i64:u128,
524 i8:u8, i16:u16, i32:u32, i64:u64, i128:u128, isize:usize
526 ];
527 impl_cast_fns![cant_fail
528 u8:u16, u8:u32, u8:u64, u8:u128,
530 u16:u32, u16:u64, u16:u128,
531 u32:u64, u32:u128,
532 u64:u128,
533 u8:i16, u8:i32, u8:i64, u8:i128,
535 u16:i32, u16:i64, u16:i128,
536 u32:i64, u32:i128,
537 u64:i128,
538 i8:i16, i8:i32, i8:i64, i8:i128,
540 i16:i32, i16:i64, i16:i128,
541 i32:i64, i32:i128,
542 i64:i128,
543 u8:u8, u16:u16, u32:u32, u64:u64, u128:u128, usize:usize,
545 i8:i8, i16:i16, i32:i32, i64:i64, i128:i128, isize:isize
547 ];
548
549 #[cfg(target_pointer_width = "16")]
552 impl_cast_fns![can_overunderflow
553 isize|usize:u8,
555 i32|u32:usize, i64|u64:usize, i128|u128:usize,
556 isize|usize:i8,
558 i32|u32:isize, i64|u64:isize, i128|u128:isize
559 ];
560 #[cfg(target_pointer_width = "32")]
561 impl_cast_fns![can_overunderflow
562 isize|usize:u8, isize|usize:u16,
564 i64|u64:usize, i128|u128:usize,
565 isize|usize:i8, isize|usize:i16,
567 i64|u64:isize, i128|u128:isize
568 ];
569 #[cfg(target_pointer_width = "64")]
570 impl_cast_fns![can_overunderflow
571 isize|usize:u8, isize|usize:u16, isize|usize:u32,
573 i128|u128:usize,
574 isize|usize:i8, isize|usize:i16, isize|usize:i32,
576 i128|u128:isize
577 ];
578
579 #[cfg(target_pointer_width = "16")]
580 impl_cast_fns![can_overflow
581 usize:u8,
583 u32:usize, u64:usize, u128:usize,
584 usize:i8,
586 u32:isize, u64:isize, u128:isize,
587 u16:isize, usize:i16
589 ];
590 #[cfg(target_pointer_width = "32")]
591 impl_cast_fns![can_overflow
592 usize:u8, usize:u16,
594 u64:usize, u128:usize,
595 usize:i8, usize:i16,
597 u64:isize, u128:isize,
598 u32:isize, usize:i32
600 ];
601 #[cfg(target_pointer_width = "64")]
602 impl_cast_fns![can_overflow
603 usize:u8, usize:u16, usize:u32,
605 u128:usize,
606 usize:i8, usize:i16, usize:i32,
608 u128:isize,
609 u64:isize, usize:i64
611 ];
612
613 #[cfg(target_pointer_width = "16")]
614 impl_cast_fns![can_underflow
615 isize:u32, isize:u64, isize:u128,
617 i8:usize,
618 i16:usize, isize:u16
620 ];
621 #[cfg(target_pointer_width = "32")]
622 impl_cast_fns![can_underflow
623 isize:u64, isize:u128,
625 i8:usize, i16:usize,
626 i32:usize, isize:u32
628 ];
629 #[cfg(target_pointer_width = "64")]
630 impl_cast_fns![can_underflow
631 isize:u128,
633 i8:usize, i16:usize, i32:usize,
634 i64:usize, isize:u64
636 ];
637
638 #[cfg(target_pointer_width = "16")]
639 impl_cast_fns![cant_fail ptr:16
640 usize:u32, usize:u64, usize:u128,
642 u8:usize,
643 usize:i32, usize:i64, usize:i128,
645 u8:isize,
646 isize:i32, isize:i64, isize:i128,
648 i8:isize,
649 usize:u16, u16:usize,
651 isize:i16, i16:isize
653 ];
654 #[cfg(target_pointer_width = "32")]
655 impl_cast_fns![cant_fail ptr:32
656 usize:u64, usize:u128,
658 u8:usize, u16:usize,
659 usize:i64, usize:i128,
661 u8:isize, u16:isize,
662 isize:i64, isize:i128,
664 i8:isize, i16:isize,
665 usize:u32, u32:usize,
667 isize:i32, i32:isize
669 ];
670 #[cfg(target_pointer_width = "64")]
671 impl_cast_fns![cant_fail ptr:64
672 usize:u128,
674 u8:usize, u16:usize, u32:usize,
675 usize:i128,
677 u8:isize, u16:isize, u32:isize,
678 isize:i128,
680 i8:isize, i16:isize, i32:isize,
681 usize:u64, u64:usize,
683 isize:i64, i64:isize
685 ];
686 };
687 (can_overunderflow $( $f:ty | $fun:ty : $t:ty ),+) => {
688 $( impl_cast_fns![@can_overunderflow $f|$fun:$t]; )+
689 };
690 (@can_overunderflow $f:ty | $fun:ty : $t:ty) => { paste! {
691 const fn [<checked_cast_ $f _to_ $t>](p: $f) -> Result<$t> {
692 if p < <$t>::MIN as $f {
693 Err(Overflow(Some(Negative)))
694 } else if p > $t::MAX as $f {
695 Err(Overflow(Some(Positive)))
696 } else {
697 Ok(p as $t)
698 }
699 }
700 const fn [<saturating_cast_ $f _to_ $t>](p: $f) -> $t {
701 if p < <$t>::MIN as $f {
702 <$t>::MIN
703 } else if p > $t::MAX as $f {
704 <$t>::MAX
705 } else {
706 p as $t
707 }
708 }
709 const fn [<wrapping_cast_ $f _to_ $t>](p: $f) -> $t {
710 (p as $fun % (<$t>::MAX as $fun + 1)) as $t
711 }
712 }};
713 (can_overflow $( $f:ty:$t:ty ),+) => { $( impl_cast_fns![@can_overflow $f:$t]; )+ };
714 (@can_overflow $f:ty:$t:ty) => { paste! {
715 const fn [<checked_cast_ $f _to_ $t>](p: $f) -> Result<$t> {
716 iif![p > <$t>::MAX as $f; Err(Overflow(Some(Positive))); Ok(p as $t)]
717 }
718 const fn [<saturating_cast_ $f _to_ $t>](p: $f) -> $t {
719 iif![p > <$t>::MAX as $f; <$t>::MAX; p as $t]
720 }
721 const fn [<wrapping_cast_ $f _to_ $t>](p: $f) -> $t {
722 (p % (<$t>::MAX as $f + 1)) as $t
723 }
724 }};
725 (can_underflow $( $f:ty:$t:ty ),+) => { $( impl_cast_fns![@can_underflow $f:$t]; )+ };
726 (@can_underflow $f:ty:$t:ty) => { paste! {
727 const fn [<checked_cast_ $f _to_ $t>](p: $f) -> Result<$t> {
728 iif![p < 0; Err(Overflow(Some(Negative))); Ok(p as $t)]
729 }
730 const fn [<saturating_cast_ $f _to_ $t>](p: $f) -> $t {
731 iif![p < 0; 0; p as $t]
732 }
733 const fn [<wrapping_cast_ $f _to_ $t>](p: $f) -> $t {
734 p as $t
735 }
736 }};
737 (cant_fail $( $f:ty:$t:ty ),+) => { $( impl_cast_fns![@cant_fail $f:$t]; )+ };
738 (@cant_fail $f:ty:$t:ty) => { paste! {
739 const fn [<checked_cast_ $f _to_ $t>](p: $f) -> Result<$t> {
740 Ok(p as $t)
741 }
742 const fn [<saturating_cast_ $f _to_ $t>](p: $f) -> $t {
743 p as $t
744 }
745 const fn [<wrapping_cast_ $f _to_ $t>](p: $f) -> $t {
746 p as $t
747 }
748 }};
749 (cant_fail ptr:$ptr:literal $( $f:ty:$t:ty ),+) => {
750 $( impl_cast_fns![@cant_fail ptr:$ptr $f:$t]; )+
751 };
752 (@cant_fail ptr:$ptr:literal $f:ty:$t:ty) => { paste! {
753 const fn [<checked_cast_ $f _to_ $t>](p: $f) -> Result<$t> {
754 Ok(p as $t)
755 }
756 const fn [<saturating_cast_ $f _to_ $t>](p: $f) -> $t {
757 p as $t
758 }
759 const fn [<wrapping_cast_ $f _to_ $t>](p: $f) -> $t {
760 p as $t
761 }
762 }};
763}
764impl_cast_fns![];
765
766macro_rules! impl_cast_fns_alias {
772 () => {
773 #[cfg(target_pointer_width = "16")] impl_cast_fns_alias![@to isize_up|i32];
774 #[cfg(target_pointer_width = "16")] impl_cast_fns_alias![@to usize_up|u32];
775 #[cfg(target_pointer_width = "16")] impl_cast_fns_alias![@to isize_down|i8];
776 #[cfg(target_pointer_width = "16")] impl_cast_fns_alias![@to usize_down|u8];
777 #[cfg(target_pointer_width = "32")] impl_cast_fns_alias![@to isize_up|i64];
779 #[cfg(target_pointer_width = "32")] impl_cast_fns_alias![@to usize_up|u64];
780 #[cfg(target_pointer_width = "32")] impl_cast_fns_alias![@to isize_down|i16];
781 #[cfg(target_pointer_width = "32")] impl_cast_fns_alias![@to usize_down|u16];
782 #[cfg(target_pointer_width = "64")] impl_cast_fns_alias![@to isize_up|i128];
784 #[cfg(target_pointer_width = "64")] impl_cast_fns_alias![@to usize_up|u128];
785 #[cfg(target_pointer_width = "64")] impl_cast_fns_alias![@to isize_down|i32];
786 #[cfg(target_pointer_width = "64")] impl_cast_fns_alias![@to usize_down|u32];
787 };
788 (@to $a:ident|$t:ty) => {
789 impl_cast_fns_alias![@to $a|$t:
790 i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize];
791 };
792 (@to $a:ident|$t:ty : $($f:ty),+) => { $( impl_cast_fns_alias!(@impl $f, $a, $t);)+ };
793 (@impl $f:ty, $a:ty, $t:ty) => { paste! {
794 const fn [<checked_cast_ $f _to_ $a>](p: $f) -> Result<$a> {
795 [<checked_cast_ $f _to_ $t>](p)
796 }
797 const fn [<saturating_cast_ $f _to_ $a>](p: $f) -> $a {
798 [<saturating_cast_ $f _to_ $t>](p)
799 }
800 const fn [<wrapping_cast_ $f _to_ $a>](p: $f) -> $a {
801 [<wrapping_cast_ $f _to_ $t>](p)
802 }
803 }};
804}
805impl_cast_fns_alias![];