1use super::*;
9
10macro_rules! impl_via_from {
11 ($x:ty: $y:ty) => {
12 impl Conv<$x> for $y {
13 #[inline]
14 fn conv(x: $x) -> $y {
15 <$y>::from(x)
16 }
17 #[inline]
18 fn try_conv(x: $x) -> Result<Self> {
19 Ok(<$y>::from(x))
20 }
21 }
22 };
23 ($x:ty: $y:ty, $($yy:ty),+) => {
24 impl_via_from!($x: $y);
25 impl_via_from!($x: $($yy),+);
26 };
27}
28
29impl_via_from!(f32: f64);
30impl_via_from!(i8: f32, f64, i16, i32, i64, i128);
31impl_via_from!(i16: f32, f64, i32, i64, i128);
32impl_via_from!(i32: f64, i64, i128);
33impl_via_from!(i64: i128);
34impl_via_from!(u8: f32, f64, i16, i32, i64, i128);
35impl_via_from!(u8: u16, u32, u64, u128);
36impl_via_from!(u16: f32, f64, i32, i64, i128, u32, u64, u128);
37impl_via_from!(u32: f64, i64, i128, u64, u128);
38impl_via_from!(u64: i128, u128);
39
40impl<S, T: Conv<S> + Copy + Default, const N: usize> Conv<[S; N]> for [T; N] {
43 #[inline]
44 fn try_conv(ss: [S; N]) -> Result<Self> {
45 let mut tt = [T::default(); N];
46 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
47 *t = T::try_conv(s)?;
48 }
49 Ok(tt)
50 }
51 #[inline]
52 fn conv(ss: [S; N]) -> Self {
53 let mut tt = [T::default(); N];
54 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
55 *t = T::conv(s);
56 }
57 tt
58 }
59}
60
61#[cfg(any(feature = "std", feature = "libm"))]
62impl<S, T: ConvFloat<S> + Copy + Default, const N: usize> ConvFloat<[S; N]> for [T; N] {
63 #[inline]
64 fn try_conv_trunc(ss: [S; N]) -> Result<Self> {
65 let mut tt = [T::default(); N];
66 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
67 *t = T::try_conv_trunc(s)?;
68 }
69 Ok(tt)
70 }
71 #[inline]
72 fn try_conv_nearest(ss: [S; N]) -> Result<Self> {
73 let mut tt = [T::default(); N];
74 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
75 *t = T::try_conv_nearest(s)?;
76 }
77 Ok(tt)
78 }
79 #[inline]
80 fn try_conv_floor(ss: [S; N]) -> Result<Self> {
81 let mut tt = [T::default(); N];
82 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
83 *t = T::try_conv_floor(s)?;
84 }
85 Ok(tt)
86 }
87 #[inline]
88 fn try_conv_ceil(ss: [S; N]) -> Result<Self> {
89 let mut tt = [T::default(); N];
90 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
91 *t = T::try_conv_ceil(s)?;
92 }
93 Ok(tt)
94 }
95
96 #[inline]
97 fn conv_trunc(ss: [S; N]) -> Self {
98 let mut tt = [T::default(); N];
99 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
100 *t = T::conv_trunc(s);
101 }
102 tt
103 }
104 #[inline]
105 fn conv_nearest(ss: [S; N]) -> Self {
106 let mut tt = [T::default(); N];
107 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
108 *t = T::conv_nearest(s);
109 }
110 tt
111 }
112 #[inline]
113 fn conv_floor(ss: [S; N]) -> Self {
114 let mut tt = [T::default(); N];
115 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
116 *t = T::conv_floor(s);
117 }
118 tt
119 }
120 #[inline]
121 fn conv_ceil(ss: [S; N]) -> Self {
122 let mut tt = [T::default(); N];
123 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
124 *t = T::conv_ceil(s);
125 }
126 tt
127 }
128}
129
130impl Conv<()> for () {
131 #[inline]
132 fn try_conv(_: ()) -> Result<Self> {
133 Ok(())
134 }
135 #[inline]
136 fn conv(_: ()) -> Self {}
137}
138impl<S0, T0: Conv<S0>> Conv<(S0,)> for (T0,) {
139 #[inline]
140 fn try_conv(ss: (S0,)) -> Result<Self> {
141 Ok((ss.0.try_cast()?,))
142 }
143 #[inline]
144 fn conv(ss: (S0,)) -> Self {
145 (ss.0.cast(),)
146 }
147}
148impl<S0, S1, T0: Conv<S0>, T1: Conv<S1>> Conv<(S0, S1)> for (T0, T1) {
149 #[inline]
150 fn try_conv(ss: (S0, S1)) -> Result<Self> {
151 Ok((ss.0.try_cast()?, ss.1.try_cast()?))
152 }
153 #[inline]
154 fn conv(ss: (S0, S1)) -> Self {
155 (ss.0.cast(), ss.1.cast())
156 }
157}
158impl<S0, S1, S2, T0: Conv<S0>, T1: Conv<S1>, T2: Conv<S2>> Conv<(S0, S1, S2)> for (T0, T1, T2) {
159 #[inline]
160 fn try_conv(ss: (S0, S1, S2)) -> Result<Self> {
161 Ok((ss.0.try_cast()?, ss.1.try_cast()?, ss.2.try_cast()?))
162 }
163 #[inline]
164 fn conv(ss: (S0, S1, S2)) -> Self {
165 (ss.0.cast(), ss.1.cast(), ss.2.cast())
166 }
167}
168impl<S0, S1, S2, S3, T0: Conv<S0>, T1: Conv<S1>, T2: Conv<S2>, T3: Conv<S3>> Conv<(S0, S1, S2, S3)>
169 for (T0, T1, T2, T3)
170{
171 #[inline]
172 fn try_conv(ss: (S0, S1, S2, S3)) -> Result<Self> {
173 Ok((
174 ss.0.try_cast()?,
175 ss.1.try_cast()?,
176 ss.2.try_cast()?,
177 ss.3.try_cast()?,
178 ))
179 }
180 #[inline]
181 fn conv(ss: (S0, S1, S2, S3)) -> Self {
182 (ss.0.cast(), ss.1.cast(), ss.2.cast(), ss.3.cast())
183 }
184}
185impl<S0, S1, S2, S3, S4, T0: Conv<S0>, T1: Conv<S1>, T2: Conv<S2>, T3: Conv<S3>, T4: Conv<S4>>
186 Conv<(S0, S1, S2, S3, S4)> for (T0, T1, T2, T3, T4)
187{
188 #[inline]
189 fn try_conv(ss: (S0, S1, S2, S3, S4)) -> Result<Self> {
190 Ok((
191 ss.0.try_cast()?,
192 ss.1.try_cast()?,
193 ss.2.try_cast()?,
194 ss.3.try_cast()?,
195 ss.4.try_cast()?,
196 ))
197 }
198 #[inline]
199 fn conv(ss: (S0, S1, S2, S3, S4)) -> Self {
200 (
201 ss.0.cast(),
202 ss.1.cast(),
203 ss.2.cast(),
204 ss.3.cast(),
205 ss.4.cast(),
206 )
207 }
208}
209impl<S0, S1, S2, S3, S4, S5, T0, T1, T2, T3, T4, T5> Conv<(S0, S1, S2, S3, S4, S5)>
210 for (T0, T1, T2, T3, T4, T5)
211where
212 T0: Conv<S0>,
213 T1: Conv<S1>,
214 T2: Conv<S2>,
215 T3: Conv<S3>,
216 T4: Conv<S4>,
217 T5: Conv<S5>,
218{
219 #[inline]
220 fn try_conv(ss: (S0, S1, S2, S3, S4, S5)) -> Result<Self> {
221 Ok((
222 ss.0.try_cast()?,
223 ss.1.try_cast()?,
224 ss.2.try_cast()?,
225 ss.3.try_cast()?,
226 ss.4.try_cast()?,
227 ss.5.try_cast()?,
228 ))
229 }
230 #[inline]
231 fn conv(ss: (S0, S1, S2, S3, S4, S5)) -> Self {
232 (
233 ss.0.cast(),
234 ss.1.cast(),
235 ss.2.cast(),
236 ss.3.cast(),
237 ss.4.cast(),
238 ss.5.cast(),
239 )
240 }
241}
242
243#[cfg(any(feature = "std", feature = "libm"))]
244impl<S0, S1, T0: ConvFloat<S0>, T1: ConvFloat<S1>> ConvFloat<(S0, S1)> for (T0, T1) {
245 #[inline]
246 fn try_conv_trunc(ss: (S0, S1)) -> Result<Self> {
247 Ok((T0::try_conv_trunc(ss.0)?, T1::try_conv_trunc(ss.1)?))
248 }
249 #[inline]
250 fn try_conv_nearest(ss: (S0, S1)) -> Result<Self> {
251 Ok((T0::try_conv_nearest(ss.0)?, T1::try_conv_nearest(ss.1)?))
252 }
253 #[inline]
254 fn try_conv_floor(ss: (S0, S1)) -> Result<Self> {
255 Ok((T0::try_conv_floor(ss.0)?, T1::try_conv_floor(ss.1)?))
256 }
257 #[inline]
258 fn try_conv_ceil(ss: (S0, S1)) -> Result<Self> {
259 Ok((T0::try_conv_ceil(ss.0)?, T1::try_conv_ceil(ss.1)?))
260 }
261
262 #[inline]
263 fn conv_trunc(ss: (S0, S1)) -> Self {
264 (T0::conv_trunc(ss.0), T1::conv_trunc(ss.1))
265 }
266 #[inline]
267 fn conv_nearest(ss: (S0, S1)) -> Self {
268 (T0::conv_nearest(ss.0), T1::conv_nearest(ss.1))
269 }
270 #[inline]
271 fn conv_floor(ss: (S0, S1)) -> Self {
272 (T0::conv_floor(ss.0), T1::conv_floor(ss.1))
273 }
274 #[inline]
275 fn conv_ceil(ss: (S0, S1)) -> Self {
276 (T0::conv_ceil(ss.0), T1::conv_ceil(ss.1))
277 }
278}
279
280macro_rules! impl_via_trivial {
281 ($x:ty) => {
282 impl Conv<$x> for $x {
283 #[inline]
284 fn conv(x: $x) -> Self {
285 x
286 }
287 #[inline]
288 fn try_conv(x: $x) -> Result<Self> {
289 Ok(x)
290 }
291 }
292 };
293 ($x:ty $(, $xx:tt)* $(,)?) => {
294 impl_via_trivial!($x);
295 impl_via_trivial!($($xx),*);
296 };
297}
298
299#[rustfmt::skip]
300impl_via_trivial!(
301 u8, u16, u32, u64, u128, usize,
302 i8, i16, i32, i64, i128, isize,
303 f32, f64,
304);