Skip to content

Commit a691caf

Browse files
committed
[libc++] <experimental/simd> Add swap functions of simd reference
1 parent 3a146d5 commit a691caf

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

libcxx/include/experimental/__simd/reference.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__type_traits/is_assignable.h>
1414
#include <__type_traits/is_same.h>
1515
#include <__utility/forward.h>
16+
#include <__utility/move.h>
1617
#include <cstddef>
1718
#include <experimental/__config>
1819
#include <experimental/__simd/utility.h>
@@ -55,6 +56,24 @@ class __simd_reference {
5556
__set(static_cast<value_type>(std::forward<_Up>(__v)));
5657
return {__s_, __idx_};
5758
}
59+
60+
friend _LIBCPP_HIDE_FROM_ABI void swap(__simd_reference&& __a, __simd_reference&& __b) noexcept {
61+
value_type __tmp(std::move(__a.__get()));
62+
__a.__set(std::move(__b.__get()));
63+
__b.__set(std::move(__tmp));
64+
}
65+
66+
friend _LIBCPP_HIDE_FROM_ABI void swap(value_type& __a, __simd_reference&& __b) noexcept {
67+
value_type __tmp(std::move(__a));
68+
__a = std::move(__b.__get());
69+
__b.__set(std::move(__tmp));
70+
}
71+
72+
friend _LIBCPP_HIDE_FROM_ABI void swap(__simd_reference&& __a, value_type& __b) noexcept {
73+
value_type __tmp(std::move(__a.__get()));
74+
__a.__set(std::move(__b));
75+
__b = std::move(__tmp);
76+
}
5877
};
5978

6079
} // namespace parallelism_v2

libcxx/include/experimental/simd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ inline namespace parallelism_v2 {
7878
#include <experimental/__config>
7979
#include <experimental/__simd/aligned_tag.h>
8080
#include <experimental/__simd/declaration.h>
81+
#include <experimental/__simd/reference.h>
8182
#include <experimental/__simd/scalar.h>
8283
#include <experimental/__simd/simd.h>
8384
#include <experimental/__simd/simd_mask.h>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14
10+
11+
// <experimental/simd>
12+
//
13+
// [simd.reference]
14+
// friend void swap(reference&& a, reference&& b) noexcept;
15+
// friend void swap(value_type& a, reference&& b) noexcept;
16+
// friend void swap(reference&& a, value_type& b) noexcept;
17+
18+
#include "../test_utils.h"
19+
#include <experimental/simd>
20+
21+
namespace ex = std::experimental::parallelism_v2;
22+
23+
template <class T, std::size_t>
24+
struct CheckSimdRefSwap {
25+
template <class SimdAbi>
26+
void operator()() {
27+
ex::simd<T, SimdAbi> origin_simd_1(1);
28+
ex::simd<T, SimdAbi> origin_simd_2(2);
29+
T value = 3;
30+
31+
static_assert(noexcept(swap(origin_simd_1[0], origin_simd_2[0])));
32+
swap(origin_simd_1[0], origin_simd_2[0]);
33+
assert((origin_simd_1[0] == 2) && (origin_simd_2[0] == 1));
34+
35+
static_assert(noexcept(swap(origin_simd_1[0], value)));
36+
swap(origin_simd_1[0], value);
37+
assert((origin_simd_1[0] == 3) && (value == 2));
38+
39+
static_assert(noexcept(swap(value, origin_simd_2[0])));
40+
swap(value, origin_simd_2[0]);
41+
assert((value == 1) && (origin_simd_2[0] == 2));
42+
}
43+
};
44+
45+
template <class T, std::size_t>
46+
struct CheckMaskRefSwap {
47+
template <class SimdAbi>
48+
void operator()() {
49+
ex::simd_mask<T, SimdAbi> origin_mask_1(true);
50+
ex::simd_mask<T, SimdAbi> origin_mask_2(false);
51+
bool value = true;
52+
53+
static_assert(noexcept(swap(origin_mask_1[0], origin_mask_2[0])));
54+
swap(origin_mask_1[0], origin_mask_2[0]);
55+
assert((origin_mask_1[0] == false) && (origin_mask_2[0] == true));
56+
57+
static_assert(noexcept(swap(origin_mask_1[0], value)));
58+
swap(origin_mask_1[0], value);
59+
assert((origin_mask_1[0] == true) && (value == false));
60+
61+
static_assert(noexcept(swap(value, origin_mask_2[0])));
62+
swap(value, origin_mask_2[0]);
63+
assert((value == true) && (origin_mask_2[0] == false));
64+
}
65+
};
66+
67+
int main(int, char**) {
68+
test_all_simd_abi<CheckSimdRefSwap>();
69+
test_all_simd_abi<CheckMaskRefSwap>();
70+
return 0;
71+
}

0 commit comments

Comments
 (0)