1 //! Implements methods to read a vector type from a slice.
3 macro_rules
! impl_slice_from_slice
{
4 ([$elem_ty
:ident
; $elem_count
:expr
]: $id
:ident
| $test_tt
:tt
) => {
6 /// Instantiates a new vector with the values of the `slice`.
10 /// If `slice.len() < Self::lanes()` or `&slice[0]` is not aligned
11 /// to an `align_of::<Self>()` boundary.
13 pub fn from_slice_aligned(slice
: &[$elem_ty
]) -> Self {
15 assert
!(slice
.len() >= $elem_count
);
16 let target_ptr
= slice
.get_unchecked(0) as *const $elem_ty
;
17 assert_eq
!(target_ptr
.align_offset(crate::mem
::align_of
::<Self>()), 0);
18 Self::from_slice_aligned_unchecked(slice
)
22 /// Instantiates a new vector with the values of the `slice`.
26 /// If `slice.len() < Self::lanes()`.
28 pub fn from_slice_unaligned(slice
: &[$elem_ty
]) -> Self {
30 assert
!(slice
.len() >= $elem_count
);
31 Self::from_slice_unaligned_unchecked(slice
)
35 /// Instantiates a new vector with the values of the `slice`.
39 /// If `slice.len() < Self::lanes()` or `&slice[0]` is not aligned
40 /// to an `align_of::<Self>()` boundary, the behavior is undefined.
42 pub unsafe fn from_slice_aligned_unchecked(slice
: &[$elem_ty
]) -> Self {
43 debug_assert
!(slice
.len() >= $elem_count
);
44 let target_ptr
= slice
.get_unchecked(0) as *const $elem_ty
;
45 debug_assert_eq
!(target_ptr
.align_offset(crate::mem
::align_of
::<Self>()), 0);
47 #[allow(clippy::cast_ptr_alignment)]
48 *(target_ptr
as *const Self)
51 /// Instantiates a new vector with the values of the `slice`.
55 /// If `slice.len() < Self::lanes()` the behavior is undefined.
57 pub unsafe fn from_slice_unaligned_unchecked(slice
: &[$elem_ty
]) -> Self {
58 use crate::mem
::size_of
;
59 debug_assert
!(slice
.len() >= $elem_count
);
60 let target_ptr
= slice
.get_unchecked(0) as *const $elem_ty
as *const u8;
61 let mut x
= Self::splat(0 as $elem_ty
);
62 let self_ptr
= &mut x
as *mut Self as *mut u8;
63 crate::ptr
::copy_nonoverlapping(target_ptr
, self_ptr
, size_of
::<Self>());
71 // Comparisons use integer casts within mantissa^1 range.
72 #[allow(clippy::float_cmp)]
73 pub mod [<$id _slice_from_slice
>] {
75 use crate::iter
::Iterator
;
77 #[cfg_attr(not(target_arch = "wasm32"), test)]
78 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
79 fn from_slice_unaligned() {
80 let mut unaligned
= [42 as $elem_ty
; $id
::lanes() + 1];
81 unaligned
[0] = 0 as $elem_ty
;
82 let vec
= $id
::from_slice_unaligned(&unaligned
[1..]);
83 for (index
, &b
) in unaligned
.iter().enumerate() {
85 assert_eq
!(b
, 0 as $elem_ty
);
87 assert_eq
!(b
, 42 as $elem_ty
);
88 assert_eq
!(b
, vec
.extract(index
- 1));
93 // FIXME: wasm-bindgen-test does not support #[should_panic]
94 // #[cfg_attr(not(target_arch = "wasm32"), test)]
95 // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
96 #[cfg(not(target_arch = "wasm32"))]
99 fn from_slice_unaligned_fail() {
100 let mut unaligned
= [42 as $elem_ty
; $id
::lanes() + 1];
101 unaligned
[0] = 0 as $elem_ty
;
102 // the slice is not large enough => panic
103 let _vec
= $id
::from_slice_unaligned(&unaligned
[2..]);
107 data
: [$elem_ty
; 2 * $id
::lanes()],
111 #[cfg_attr(not(target_arch = "wasm32"), test)]
112 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
113 fn from_slice_aligned() {
114 let mut aligned
= A
{
115 data
: [0 as $elem_ty
; 2 * $id
::lanes()],
117 for i
in $id
::lanes()..(2 * $id
::lanes()) {
119 aligned
.data
[i
] = 42 as $elem_ty
;
124 $id
::from_slice_aligned(
125 &aligned
.data
[$id
::lanes()..]
129 unsafe { aligned.data.iter().enumerate() }
{
130 if index
< $id
::lanes() {
131 assert_eq
!(b
, 0 as $elem_ty
);
133 assert_eq
!(b
, 42 as $elem_ty
);
135 b
, vec
.extract(index
- $id
::lanes())
141 // FIXME: wasm-bindgen-test does not support #[should_panic]
142 // #[cfg_attr(not(target_arch = "wasm32"), test)]
143 // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
144 #[cfg(not(target_arch = "wasm32"))]
147 fn from_slice_aligned_fail_lanes() {
149 data
: [0 as $elem_ty
; 2 * $id
::lanes()],
152 $id
::from_slice_aligned(
153 &aligned
.data
[2 * $id
::lanes()..]
158 // FIXME: wasm-bindgen-test does not support #[should_panic]
159 // #[cfg_attr(not(target_arch = "wasm32"), test)]
160 // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
161 #[cfg(not(target_arch = "wasm32"))]
164 fn from_slice_aligned_fail_align() {
167 data
: [0 as $elem_ty
; 2 * $id
::lanes()],
170 // get a pointer to the front of data
171 let ptr
: *const $elem_ty
= aligned
.data
.as_ptr()
173 // offset pointer by one element
174 let ptr
= ptr
.wrapping_add(1);
177 crate::mem
::align_of
::<$id
>()
179 // the pointer is properly aligned, so
180 // from_slice_aligned won't fail here (e.g. this
181 // can happen for i128x1). So we panic to make
182 // the "should_fail" test pass:
186 // create a slice - this is safe, because the
187 // elements of the slice exist, are properly
188 // initialized, and properly aligned:
189 let s
: &[$elem_ty
] = slice
::from_raw_parts(
192 // this should always panic because the slice
193 // alignment does not match the alignment
194 // requirements for the vector type:
195 let _vec
= $id
::from_slice_aligned(s
);