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