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