common_traits/
downcastable.rs

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