]> git.proxmox.com Git - rustc.git/blame - vendor/packed_simd/src/api/from/from_array.rs
Update upstream source from tag 'upstream/1.52.1+dfsg1'
[rustc.git] / vendor / packed_simd / src / api / from / from_array.rs
CommitLineData
f20569fa
XL
1//! Implements `From<[T; N]>` and `Into<[T; N]>` for vector types.
2
3macro_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 mod [<$id _from>] {
60 use super::*;
61 #[test]
62 fn array() {
63 let vec: $id = Default::default();
64
65 // FIXME: Workaround for arrays with more than 32
66 // elements.
67 //
68 // Safe because we never take a reference to any
69 // uninitialized element.
70 union W {
71 array: [$elem_ty; $elem_count],
72 other: ()
73 }
74 let mut array = W { other: () };
75 for i in 0..$elem_count {
76 let default: $elem_ty = Default::default();
77 // note: array.other is the active member and
78 // initialized so we can take a reference to it:
79 let p = unsafe {
80 &mut array.other as *mut () as *mut $elem_ty
81 };
82 // note: default is a valid bit-pattern for
83 // $elem_ty:
84 unsafe {
85 crate::ptr::write(p.wrapping_add(i), default)
86 };
87 }
88 // note: the array variant of the union is properly
89 // initialized:
90 let mut array = unsafe {
91 array.array
92 };
93
94 array[0] = $non_default_array;
95 let vec = vec.replace(0, $non_default_vec);
96
97 let vec_from_array = $id::from(array);
98 assert_eq!(vec_from_array, vec);
99 let array_from_vec
100 = <[$elem_ty; $elem_count]>::from(vec);
101 // FIXME: Workaround for arrays with more than 32
102 // elements.
103 for i in 0..$elem_count {
104 assert_eq!(array_from_vec[i], array[i]);
105 }
106
107 let vec_from_into_array: $id = array.into();
108 assert_eq!(vec_from_into_array, vec);
109 let array_from_into_vec: [$elem_ty; $elem_count]
110 = vec.into();
111 // FIXME: Workaround for arrays with more than 32
112 // elements.
113 for i in 0..$elem_count {
114 assert_eq!(array_from_into_vec[i], array[i]);
115 }
116 }
117 }
118 }
119 }
120 };
121}