common_traits/
upcastable.rs

1/// `UpcastableInto : UpcastableFrom = Into : From`, It's easier to use to
2/// specify bounds on generic variables
3pub trait UpcastableInto<W>: Sized {
4    /// Call `W::upcast_from(self)`
5    fn upcast(self) -> W;
6}
7
8/// Trait for primitive integers, the expected behaviour for unsigned integers
9/// is to zero extend the value, while for signed integers it will sign-extend
10/// it to the possibly bigger UnsignedInt size.
11pub trait UpcastableFrom<W>: Sized {
12    /// Extend the current UnsignedInt to a possibly bigger size.
13    fn upcast_from(value: W) -> Self;
14}
15
16/// UpcastableFrom implies UpcastableInto
17impl<T, U> UpcastableInto<U> for T
18where
19    U: UpcastableFrom<T>,
20{
21    #[inline(always)]
22    fn upcast(self) -> U {
23        U::upcast_from(self)
24    }
25}
26
27/// Riflexivity
28impl<T> UpcastableFrom<T> for T {
29    #[inline(always)]
30    fn upcast_from(value: T) -> Self {
31        value
32    }
33}
34
35macro_rules! impl_upcasts {
36    ($base_type:ty, $($ty:ty,)*) => {$(
37impl UpcastableFrom<$base_type> for $ty {
38    #[inline(always)]
39    fn upcast_from(value: $base_type) -> Self {
40        value as $ty
41    }
42}
43    )*
44    impl_upcasts!($($ty,)*);
45};
46    () => {};
47}
48
49impl_upcasts!(u8, u16, u32, u64, u128,);
50impl_upcasts!(i8, i16, i32, i64, i128,);
51
52#[cfg(any(
53    target_pointer_width = "16",
54    target_pointer_width = "32",
55    target_pointer_width = "64",
56))]
57impl UpcastableFrom<i8> for isize {
58    #[inline(always)]
59    fn upcast_from(value: i8) -> Self {
60        value as isize
61    }
62}
63
64#[cfg(any(
65    target_pointer_width = "16",
66    target_pointer_width = "32",
67    target_pointer_width = "64",
68))]
69impl UpcastableFrom<i16> for isize {
70    #[inline(always)]
71    fn upcast_from(value: i16) -> Self {
72        value as isize
73    }
74}
75
76#[cfg(target_pointer_width = "16")]
77impl UpcastableFrom<isize> for i16 {
78    #[inline(always)]
79    fn upcast_from(value: isize) -> Self {
80        value as i16
81    }
82}
83
84#[cfg(any(target_pointer_width = "32", target_pointer_width = "64",))]
85impl UpcastableFrom<i32> for isize {
86    #[inline(always)]
87    fn upcast_from(value: i32) -> Self {
88        value as isize
89    }
90}
91
92#[cfg(any(target_pointer_width = "16", target_pointer_width = "32",))]
93impl UpcastableFrom<isize> for i32 {
94    #[inline(always)]
95    fn upcast_from(value: isize) -> Self {
96        value as i32
97    }
98}
99
100#[cfg(target_pointer_width = "64")]
101impl UpcastableFrom<i64> for isize {
102    #[inline(always)]
103    fn upcast_from(value: i64) -> Self {
104        value as isize
105    }
106}
107
108#[cfg(any(
109    target_pointer_width = "16",
110    target_pointer_width = "32",
111    target_pointer_width = "64",
112))]
113impl UpcastableFrom<isize> for i64 {
114    #[inline(always)]
115    fn upcast_from(value: isize) -> Self {
116        value as i64
117    }
118}
119
120#[cfg(any(
121    target_pointer_width = "16",
122    target_pointer_width = "32",
123    target_pointer_width = "64",
124))]
125impl UpcastableFrom<isize> for i128 {
126    #[inline(always)]
127    fn upcast_from(value: isize) -> Self {
128        value as i128
129    }
130}
131
132#[cfg(any(
133    target_pointer_width = "16",
134    target_pointer_width = "32",
135    target_pointer_width = "64",
136))]
137impl UpcastableFrom<u8> for usize {
138    #[inline(always)]
139    fn upcast_from(value: u8) -> Self {
140        value as usize
141    }
142}
143
144#[cfg(any(
145    target_pointer_width = "16",
146    target_pointer_width = "32",
147    target_pointer_width = "64",
148))]
149impl UpcastableFrom<u16> for usize {
150    #[inline(always)]
151    fn upcast_from(value: u16) -> Self {
152        value as usize
153    }
154}
155
156#[cfg(target_pointer_width = "16")]
157impl UpcastableFrom<usize> for u16 {
158    #[inline(always)]
159    fn upcast_from(value: usize) -> Self {
160        value as u16
161    }
162}
163
164#[cfg(any(target_pointer_width = "32", target_pointer_width = "64",))]
165impl UpcastableFrom<u32> for usize {
166    #[inline(always)]
167    fn upcast_from(value: u32) -> Self {
168        value as usize
169    }
170}
171
172#[cfg(any(target_pointer_width = "16", target_pointer_width = "32",))]
173impl UpcastableFrom<usize> for u32 {
174    #[inline(always)]
175    fn upcast_from(value: usize) -> Self {
176        value as u32
177    }
178}
179
180#[cfg(target_pointer_width = "64")]
181impl UpcastableFrom<u64> for usize {
182    #[inline(always)]
183    fn upcast_from(value: u64) -> Self {
184        value as usize
185    }
186}
187
188#[cfg(any(
189    target_pointer_width = "16",
190    target_pointer_width = "32",
191    target_pointer_width = "64",
192))]
193impl UpcastableFrom<usize> for u64 {
194    #[inline(always)]
195    fn upcast_from(value: usize) -> Self {
196        value as u64
197    }
198}
199
200#[cfg(any(
201    target_pointer_width = "16",
202    target_pointer_width = "32",
203    target_pointer_width = "64",
204))]
205impl UpcastableFrom<usize> for u128 {
206    #[inline(always)]
207    fn upcast_from(value: usize) -> Self {
208        value as u128
209    }
210}
211
212impl UpcastableFrom<f32> for f64 {
213    #[inline(always)]
214    fn upcast_from(value: f32) -> Self {
215        value as f64
216    }
217}
218
219#[cfg(feature = "half")]
220mod half_impl {
221    use super::*;
222    impl UpcastableFrom<half::f16> for f32 {
223        #[inline(always)]
224        fn upcast_from(value: half::f16) -> Self {
225            value.to_f32()
226        }
227    }
228    impl UpcastableFrom<half::bf16> for f32 {
229        #[inline(always)]
230        fn upcast_from(value: half::bf16) -> Self {
231            value.to_f32()
232        }
233    }
234    impl UpcastableFrom<half::f16> for f64 {
235        #[inline(always)]
236        fn upcast_from(value: half::f16) -> Self {
237            value.to_f64()
238        }
239    }
240    impl UpcastableFrom<half::bf16> for f64 {
241        #[inline(always)]
242        fn upcast_from(value: half::bf16) -> Self {
243            value.to_f64()
244        }
245    }
246}