]> git.proxmox.com Git - rustc.git/blob - vendor/packed_simd_2/src/api/from/from_array.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / vendor / packed_simd_2 / src / api / from / from_array.rs
1 //! Implements `From<[T; N]>` and `Into<[T; N]>` for vector types.
2
3 macro_rules! impl_from_array {
4 ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt
5 | ($non_default_array:expr, $non_default_vec:expr)) => {
6 impl From<[$elem_ty; $elem_count]> for $id {
7 #[inline]
8 fn from(array: [$elem_ty; $elem_count]) -> Self {
9 union U {
10 array: [$elem_ty; $elem_count],
11 vec: $id,
12 }
13 unsafe { U { array }.vec }
14 }
15 }
16
17 impl From<$id> for [$elem_ty; $elem_count] {
18 #[inline]
19 fn from(vec: $id) -> Self {
20 union U {
21 array: [$elem_ty; $elem_count],
22 vec: $id,
23 }
24 unsafe { U { vec }.array }
25 }
26 }
27
28 // FIXME: `Into::into` is not inline, but due to
29 // the blanket impl in `std`, which is not
30 // marked `default`, we cannot override it here with
31 // specialization.
32 /*
33 impl Into<[$elem_ty; $elem_count]> for $id {
34 #[inline]
35 fn into(self) -> [$elem_ty; $elem_count] {
36 union U {
37 array: [$elem_ty; $elem_count],
38 vec: $id,
39 }
40 unsafe { U { vec: self }.array }
41 }
42 }
43
44 impl Into<$id> for [$elem_ty; $elem_count] {
45 #[inline]
46 fn into(self) -> $id {
47 union U {
48 array: [$elem_ty; $elem_count],
49 vec: $id,
50 }
51 unsafe { U { array: self }.vec }
52 }
53 }
54 */
55
56 test_if! {
57 $test_tt:
58 paste::item! {
59 // Comparisons use integer casts within mantissa^1 range.
60 #[allow(clippy::float_cmp)]
61 mod [<$id _from>] {
62 use super::*;
63 #[test]
64 fn array() {
65 let vec: $id = Default::default();
66
67 // FIXME: Workaround for arrays with more than 32
68 // elements.
69 //
70 // Safe because we never take a reference to any
71 // uninitialized element.
72 union W {
73 array: [$elem_ty; $elem_count],
74 other: ()
75 }
76 let mut array = W { other: () };
77 for i in 0..$elem_count {
78 let default: $elem_ty = Default::default();
79 // note: array.other is the active member and
80 // initialized so we can take a reference to it:
81 let p = unsafe {
82 &mut array.other as *mut () as *mut $elem_ty
83 };
84 // note: default is a valid bit-pattern for
85 // $elem_ty:
86 unsafe {
87 crate::ptr::write(p.wrapping_add(i), default)
88 };
89 }
90 // note: the array variant of the union is properly
91 // initialized:
92 let mut array = unsafe {
93 array.array
94 };
95
96 array[0] = $non_default_array;
97 let vec = vec.replace(0, $non_default_vec);
98
99 let vec_from_array = $id::from(array);
100 assert_eq!(vec_from_array, vec);
101 let array_from_vec
102 = <[$elem_ty; $elem_count]>::from(vec);
103 // FIXME: Workaround for arrays with more than 32
104 // elements.
105 for i in 0..$elem_count {
106 assert_eq!(array_from_vec[i], array[i]);
107 }
108
109 let vec_from_into_array: $id = array.into();
110 assert_eq!(vec_from_into_array, vec);
111 let array_from_into_vec: [$elem_ty; $elem_count]
112 = vec.into();
113 // FIXME: Workaround for arrays with more than 32
114 // elements.
115 for i in 0..$elem_count {
116 assert_eq!(array_from_into_vec[i], array[i]);
117 }
118 }
119 }
120 }
121 }
122 };
123 }