1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
pub unsafe trait Transmute<T: Sized>: Sized {}
pub unsafe trait TryTransmute<T: Sized>: Sized {
fn can_transmute(&self) -> bool;
}
unsafe impl<T: Sized> Transmute<T> for T {}
unsafe impl<T: Sized> TryTransmute<T> for T {
#[inline]
fn can_transmute(&self) -> bool {
true
}
}
macro_rules! unsafe_impl_transmute {
($A:ty => $B:ty, $($rest:tt)*) => {
unsafe impl Transmute<$B> for $A {}
unsafe_impl_transmute!($($rest)*);
};
($A:ty => $B:ty where $can_transmute:expr, $($rest:tt)*) => {
unsafe impl TryTransmute<$B> for $A {
#[inline]
fn can_transmute(&self) -> bool {
$can_transmute(self)
}
}
unsafe_impl_transmute!($($rest)*);
};
() => {}
}
use std::num::*;
unsafe_impl_transmute! {
u8 => i8 where |&val| val < (std::i8::MAX as u8),
i8 => u8 where |&val| val >= 0,
NonZeroU8 => u8,
u8 => Option<NonZeroU8>,
NonZeroU8 => Option<NonZeroU8>,
Option<NonZeroU8> => NonZeroU8 where Option::is_some,
u16 => i16 where |&val| val < (std::i16::MAX as u16),
i16 => u16 where |&val| val >= 0,
NonZeroU16 => u16,
u16 => Option<NonZeroU16>,
NonZeroU16 => Option<NonZeroU16>,
Option<NonZeroU16> => NonZeroU16 where Option::is_some,
u32 => i32 where |&val| val < (std::i32::MAX as u32),
i32 => u32 where |&val| val >= 0,
NonZeroU32 => u32,
u32 => Option<NonZeroU32>,
NonZeroU32 => Option<NonZeroU32>,
Option<NonZeroU32> => NonZeroU32 where Option::is_some,
u64 => i64 where |&val| val < (std::i64::MAX as u64),
i64 => u64 where |&val| val >= 0,
NonZeroU64 => u64,
u64 => Option<NonZeroU64>,
NonZeroU64 => Option<NonZeroU64>,
Option<NonZeroU64> => NonZeroU64 where Option::is_some,
u128 => i128 where |&val| val < (std::i128::MAX as u128),
i128 => u128 where |&val| val >= 0,
NonZeroU128 => u128,
u128 => Option<NonZeroU128>,
NonZeroU128 => Option<NonZeroU128>,
Option<NonZeroU128> => NonZeroU128 where Option::is_some,
usize => isize where |&val| val < (std::isize::MAX as usize),
isize => usize where |&val| val >= 0,
NonZeroUsize => usize,
usize => Option<NonZeroUsize>,
NonZeroUsize => Option<NonZeroUsize>,
Option<NonZeroUsize> => NonZeroUsize where Option::is_some,
}