[libcxx-commits] [libcxx] cf0f6a1 - [libc++] <experimental/simd> Add assignment operator of simd reference (#70020)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 26 14:09:59 PDT 2023
Author: ZhangYin
Date: 2023-10-26T23:09:55+02:00
New Revision: cf0f6a146038ca95e9ab9df40c153fd22015a042
URL: https://github.com/llvm/llvm-project/commit/cf0f6a146038ca95e9ab9df40c153fd22015a042
DIFF: https://github.com/llvm/llvm-project/commit/cf0f6a146038ca95e9ab9df40c153fd22015a042.diff
LOG: [libc++] <experimental/simd> Add assignment operator of simd reference (#70020)
Added:
libcxx/test/std/experimental/simd/simd.reference/reference_assignment.pass.cpp
Modified:
libcxx/docs/Status/ParallelismProjects.csv
libcxx/include/experimental/__simd/reference.h
Removed:
################################################################################
diff --git a/libcxx/docs/Status/ParallelismProjects.csv b/libcxx/docs/Status/ParallelismProjects.csv
index 667a74d207c9363..05a66080823d421 100644
--- a/libcxx/docs/Status/ParallelismProjects.csv
+++ b/libcxx/docs/Status/ParallelismProjects.csv
@@ -15,6 +15,7 @@ Section,Description,Dependencies,Assignee,Complete
| `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits resize_simd", None, Yin Zhang, |In Progress|
| `[parallel.simd.whereexpr] <https://wg21.link/N4808>`_, "Where expression class templates", None, Yin Zhang, |In Progress|
| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references operator value_type() <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
+| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references operator= <https://github.com/llvm/llvm-project/pull/70020>`_", None, Yin Zhang, |Complete|
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`Class template simd declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete|
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd broadcast constructor <https://reviews.llvm.org/D156225>`_", None, Yin Zhang, |Complete|
diff --git a/libcxx/include/experimental/__simd/reference.h b/libcxx/include/experimental/__simd/reference.h
index 335b127bf271fad..8c58d24f2f2dc42 100644
--- a/libcxx/include/experimental/__simd/reference.h
+++ b/libcxx/include/experimental/__simd/reference.h
@@ -10,6 +10,7 @@
#ifndef _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H
#define _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H
+#include <__type_traits/is_assignable.h>
#include <experimental/__simd/utility.h>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -44,6 +45,12 @@ class __simd_reference {
__simd_reference(const __simd_reference&) = delete;
_LIBCPP_HIDE_FROM_ABI operator value_type() const noexcept { return __get(); }
+
+ template <class _Up, enable_if_t<is_assignable_v<value_type&, _Up&&>, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Up&& __v) && noexcept {
+ __set(static_cast<value_type>(std::forward<_Up>(__v)));
+ return {__s_, __idx_};
+ }
};
} // namespace parallelism_v2
diff --git a/libcxx/test/std/experimental/simd/simd.reference/reference_assignment.pass.cpp b/libcxx/test/std/experimental/simd/simd.reference/reference_assignment.pass.cpp
new file mode 100644
index 000000000000000..4b943689c6fdefb
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.reference/reference_assignment.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// [simd.reference]
+// template<class U> reference=(U&& x) && noexcept;
+//
+// XFAIL: LIBCXX-AIX-FIXME
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, class SimdAbi>
+struct CheckSimdReferenceAssignmentHelper {
+ template <class U>
+ void operator()() const {
+ if constexpr (std::is_assignable_v<T&, U&&>) {
+ ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });
+ for (size_t i = 0; i < origin_simd.size(); ++i) {
+ static_assert(noexcept(origin_simd[i] = static_cast<U>(i + 1)));
+ origin_simd[i] = static_cast<U>(i + 1);
+ assert(origin_simd[i] == static_cast<T>(std::forward<U>(i + 1)));
+ }
+ }
+ }
+};
+
+template <class T, class SimdAbi>
+struct CheckMaskReferenceAssignmentHelper {
+ template <class U>
+ void operator()() const {
+ if constexpr (std::is_assignable_v<bool&, U&&>) {
+ ex::simd_mask<T, SimdAbi> origin_mask(true);
+ for (size_t i = 0; i < origin_mask.size(); ++i) {
+ static_assert(noexcept(origin_mask[i] = static_cast<U>(i + 1)));
+ origin_mask[i] = static_cast<U>(i % 2);
+ assert(origin_mask[i] == static_cast<T>(std::forward<U>(i % 2)));
+ }
+ }
+ }
+};
+
+template <class T, class SimdAbi>
+struct CheckReferenceAssignmentTraitsHelper {
+ template <class U>
+ void operator()() const {
+ if constexpr (std::is_assignable_v<T&, U&&>)
+ static_assert(std::is_assignable_v<typename ex::simd<T, SimdAbi>::reference&&, U&&>);
+ else
+ static_assert(!std::is_assignable_v<typename ex::simd<T, SimdAbi>::reference&&, U&&>);
+
+ if constexpr (std::is_assignable_v<bool&, U&&>)
+ static_assert(std::is_assignable_v<typename ex::simd_mask<T, SimdAbi>::reference&&, U&&>);
+ else
+ static_assert(!std::is_assignable_v<typename ex::simd_mask<T, SimdAbi>::reference&&, U&&>);
+ }
+};
+
+template <class T, std::size_t>
+struct CheckReferenceAssignment {
+ template <class SimdAbi>
+ void operator()() {
+ types::for_each(arithmetic_no_bool_types(), CheckSimdReferenceAssignmentHelper<T, SimdAbi>());
+ types::for_each(arithmetic_no_bool_types(), CheckMaskReferenceAssignmentHelper<T, SimdAbi>());
+
+ types::for_each(arithmetic_no_bool_types(), CheckReferenceAssignmentTraitsHelper<T, SimdAbi>());
+ }
+};
+
+int main(int, char**) {
+ test_all_simd_abi<CheckReferenceAssignment>();
+ return 0;
+}
More information about the libcxx-commits
mailing list