Skip to content

Commit dc53410

Browse files
authored
[libc++] <experimental/simd> Add operator value_type() of simd reference (llvm#68960)
1 parent 8291147 commit dc53410

File tree

7 files changed

+167
-6
lines changed

7 files changed

+167
-6
lines changed

libcxx/docs/Status/ParallelismProjects.csv

+3
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@ Section,Description,Dependencies,Assignee,Complete
1414
| `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits rebind_simd", None, Yin Zhang, |In Progress|
1515
| `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits resize_simd", None, Yin Zhang, |In Progress|
1616
| `[parallel.simd.whereexpr] <https://wg21.link/N4808>`_, "Where expression class templates", None, Yin Zhang, |In Progress|
17+
| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references operator value_type() <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
1718
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`Class template simd declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
1819
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete|
1920
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd broadcast constructor <https://reviews.llvm.org/D156225>`_", None, Yin Zhang, |Complete|
2021
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd generate constructor <https://reviews.llvm.org/D159442>`_", None, Yin Zhang, |Complete|
22+
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd subscript operators <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
2123
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "Class template simd implementation", None, Yin Zhang, |In Progress|
2224
| `[parallel.simd.nonmembers] <https://wg21.link/N4808>`_, "simd non-member operations", None, Yin Zhang, |In Progress|
2325
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`Class template simd_mask declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
2426
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.class] simd<>::size(), Yin Zhang, |Complete|
2527
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask broadcast constructor <https://reviews.llvm.org/D156225>`_", None, Yin Zhang, |Complete|
28+
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask subscript operators <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
2629
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "Class template simd_mask implementation", None, Yin Zhang, |In Progress|
2730
| `[parallel.simd.mask.nonmembers] <https://wg21.link/N4808>`_, "simd_mask non-member operations", None, Yin Zhang, |In Progress|

libcxx/include/experimental/__simd/reference.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ class __simd_reference {
2626
_Storage& __s_;
2727
size_t __idx_;
2828

29-
_LIBCPP_HIDE_FROM_ABI _Vp __get() const { return __s_.__get(__idx_); }
29+
_LIBCPP_HIDE_FROM_ABI __simd_reference(_Storage& __s, size_t __idx) : __s_(__s), __idx_(__idx) {}
30+
31+
_LIBCPP_HIDE_FROM_ABI _Vp __get() const noexcept { return __s_.__get(__idx_); }
3032

3133
_LIBCPP_HIDE_FROM_ABI void __set(_Vp __v) {
3234
if constexpr (is_same_v<_Vp, bool>)
@@ -40,6 +42,8 @@ class __simd_reference {
4042

4143
__simd_reference() = delete;
4244
__simd_reference(const __simd_reference&) = delete;
45+
46+
_LIBCPP_HIDE_FROM_ABI operator value_type() const noexcept { return __get(); }
4347
};
4448

4549
} // namespace parallelism_v2

libcxx/include/experimental/__simd/simd.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ class simd {
4646

4747
// generator constructor
4848
template <class _Generator, enable_if_t<__can_generate_v<value_type, _Generator, size()>, int> = 0>
49-
explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) : __s_(_Impl::__generate(std::forward<_Generator>(__g))) {}
49+
explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) noexcept
50+
: __s_(_Impl::__generate(std::forward<_Generator>(__g))) {}
5051

5152
// scalar access [simd.subscr]
52-
// Add operator[] temporarily to test braodcast. Add test for it in later patch.
53-
_LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const { return __s_.__get(__i); }
53+
_LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) noexcept { return reference(__s_, __i); }
54+
_LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const noexcept { return __s_.__get(__i); }
5455
};
5556

5657
template <class _Tp>

libcxx/include/experimental/__simd/simd_mask.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class simd_mask {
4242
_LIBCPP_HIDE_FROM_ABI explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
4343

4444
// scalar access [simd.mask.subscr]
45-
// Add operator[] temporarily to test braodcast. Add test for it in later patch.
46-
_LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const { return __s_.__get(__i); }
45+
_LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) noexcept { return reference(__s_, __i); }
46+
_LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const noexcept { return __s_.__get(__i); }
4747
};
4848

4949
template <class _Tp>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.class]
14+
// reference operator[](size_t i);
15+
// value_type operator[](size_t i) const;
16+
17+
#include "../test_utils.h"
18+
#include <experimental/simd>
19+
20+
namespace ex = std::experimental::parallelism_v2;
21+
22+
template <class T, std::size_t>
23+
struct CheckSimdReferenceSubscr {
24+
template <class SimdAbi>
25+
void operator()() {
26+
ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });
27+
for (size_t i = 0; i < origin_simd.size(); ++i) {
28+
static_assert(noexcept(origin_simd[i]));
29+
static_assert(std::is_same_v<typename ex::simd<T, SimdAbi>::reference, decltype(origin_simd[i])>);
30+
assert(origin_simd[i] == static_cast<T>(i));
31+
}
32+
}
33+
};
34+
35+
template <class T, std::size_t>
36+
struct CheckSimdValueTypeSubscr {
37+
template <class SimdAbi>
38+
void operator()() {
39+
const ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });
40+
for (size_t i = 0; i < origin_simd.size(); ++i) {
41+
static_assert(noexcept(origin_simd[i]));
42+
static_assert(std::is_same_v<T, decltype(origin_simd[i])>);
43+
assert(origin_simd[i] == static_cast<T>(i));
44+
}
45+
}
46+
};
47+
48+
int main(int, char**) {
49+
test_all_simd_abi<CheckSimdReferenceSubscr>();
50+
test_all_simd_abi<CheckSimdValueTypeSubscr>();
51+
return 0;
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.class]
14+
// reference operator[](size_t i);
15+
// value_type operator[](size_t i) const;
16+
17+
#include "../test_utils.h"
18+
#include <experimental/simd>
19+
20+
namespace ex = std::experimental::parallelism_v2;
21+
22+
template <class T, std::size_t>
23+
struct CheckSimdMaskReferenceSubscr {
24+
template <class SimdAbi>
25+
void operator()() {
26+
ex::simd_mask<T, SimdAbi> origin_simd_mask(true);
27+
for (size_t i = 0; i < origin_simd_mask.size(); ++i) {
28+
static_assert(noexcept(origin_simd_mask[i]));
29+
static_assert(std::is_same_v<typename ex::simd_mask<T, SimdAbi>::reference, decltype(origin_simd_mask[i])>);
30+
assert(origin_simd_mask[i] == true);
31+
}
32+
}
33+
};
34+
35+
template <class T, std::size_t>
36+
struct CheckSimdMaskValueTypeSubscr {
37+
template <class SimdAbi>
38+
void operator()() {
39+
const ex::simd_mask<T, SimdAbi> origin_simd_mask(true);
40+
for (size_t i = 0; i < origin_simd_mask.size(); ++i) {
41+
static_assert(noexcept(origin_simd_mask[i]));
42+
static_assert(std::is_same_v<bool, decltype(origin_simd_mask[i])>);
43+
assert(origin_simd_mask[i] == true);
44+
}
45+
}
46+
};
47+
48+
int main(int, char**) {
49+
test_all_simd_abi<CheckSimdMaskReferenceSubscr>();
50+
test_all_simd_abi<CheckSimdMaskValueTypeSubscr>();
51+
return 0;
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
// operator value_type() const noexcept;
15+
16+
#include "../test_utils.h"
17+
#include <experimental/simd>
18+
19+
namespace ex = std::experimental::parallelism_v2;
20+
21+
template <class T, std::size_t>
22+
struct CheckSimdReferenceValueType {
23+
template <class SimdAbi>
24+
void operator()() {
25+
ex::simd<T, SimdAbi> origin_simd([](T i) { return static_cast<T>(i); });
26+
for (size_t i = 0; i < origin_simd.size(); ++i) {
27+
static_assert(noexcept(T(origin_simd[i])));
28+
assert(T(origin_simd[i]) == static_cast<T>(i));
29+
}
30+
}
31+
};
32+
33+
template <class T, std::size_t>
34+
struct CheckMaskReferenceValueType {
35+
template <class SimdAbi>
36+
void operator()() {
37+
ex::simd_mask<T, SimdAbi> origin_simd_mask(true);
38+
for (size_t i = 0; i < origin_simd_mask.size(); ++i) {
39+
static_assert(noexcept(bool(origin_simd_mask[i])));
40+
assert(bool(origin_simd_mask[i]) == true);
41+
}
42+
}
43+
};
44+
45+
int main(int, char**) {
46+
test_all_simd_abi<CheckSimdReferenceValueType>();
47+
test_all_simd_abi<CheckMaskReferenceValueType>();
48+
return 0;
49+
}

0 commit comments

Comments
 (0)