[libcxx-commits] [libcxx] [libc++] <experimental/simd> Add ++/-- operators for simd reference (PR #88091)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 12 02:49:54 PDT 2024
https://github.com/joy2myself updated https://github.com/llvm/llvm-project/pull/88091
>From 07bfbb2b8573aa7c0ba5a06032058353dab29ae1 Mon Sep 17 00:00:00 2001
From: Yin Zhang <zhangyin2018 at iscas.ac.cn>
Date: Tue, 19 Mar 2024 20:30:51 +0800
Subject: [PATCH] [libc++] <experimental/simd> Add ++/-- operators for simd
reference
---
libcxx/docs/Status/ParallelismProjects.csv | 1 +
.../include/experimental/__simd/reference.h | 26 ++++++
.../simd.reference/reference_unary.pass.cpp | 90 +++++++++++++++++++
3 files changed, 117 insertions(+)
create mode 100644 libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp
diff --git a/libcxx/docs/Status/ParallelismProjects.csv b/libcxx/docs/Status/ParallelismProjects.csv
index d5186094610c6e..055be02843a2fd 100644
--- a/libcxx/docs/Status/ParallelismProjects.csv
+++ b/libcxx/docs/Status/ParallelismProjects.csv
@@ -18,6 +18,7 @@ Section,Description,Dependencies,Assignee,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.reference] <https://wg21.link/N4808>`_, "`Element references swap functions <https://github.com/llvm/llvm-project/pull/86478>`_", None, Yin Zhang, |Complete|
| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references compound assignment operators <https://github.com/llvm/llvm-project/pull/86761>`_", None, Yin Zhang, |Complete|
+| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references unary operators ++/-- <https://github.com/llvm/llvm-project/pull/88091>`_", 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 default constructor <https://github.com/llvm/llvm-project/pull/70424>`_", None, Yin Zhang, |Complete|
diff --git a/libcxx/include/experimental/__simd/reference.h b/libcxx/include/experimental/__simd/reference.h
index f5bb3ba688e43b..e73b1df122d8a2 100644
--- a/libcxx/include/experimental/__simd/reference.h
+++ b/libcxx/include/experimental/__simd/reference.h
@@ -132,6 +132,32 @@ class __simd_reference {
__set(__get() >> static_cast<value_type>(std::forward<_Up>(__v)));
return {__s_, __idx_};
}
+
+ template <class _Up = value_type, class = decltype(std::declval<_Up>()++)>
+ __simd_reference _LIBCPP_HIDE_FROM_ABI operator++() && noexcept {
+ __set(__get() + 1);
+ return {__s_, __idx_};
+ }
+
+ template <class _Up = value_type, class = decltype(++std::declval<_Up>())>
+ value_type _LIBCPP_HIDE_FROM_ABI operator++(int) && noexcept {
+ auto __r = __get();
+ __set(__get() + 1);
+ return __r;
+ }
+
+ template <class _Up = value_type, class = decltype(std::declval<_Up>()--)>
+ __simd_reference _LIBCPP_HIDE_FROM_ABI operator--() && noexcept {
+ __set(__get() - 1);
+ return {__s_, __idx_};
+ }
+
+ template <class _Up = value_type, class = decltype(--std::declval<_Up>())>
+ value_type _LIBCPP_HIDE_FROM_ABI operator--(int) && noexcept {
+ auto __r = __get();
+ __set(__get() - 1);
+ return __r;
+ }
};
template <class _Tp, class _Storage, class _Vp>
diff --git a/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp b/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp
new file mode 100644
index 00000000000000..d6ee39b1f4c741
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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]
+// reference operator++() && noexcept;
+// value_type operator++(int) && noexcept;
+// reference operator--() && noexcept;
+// value_type operator--(int) && noexcept;
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdReferenceUnaryOperators {
+ template <class SimdAbi>
+ void operator()() const {
+ ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
+ static_assert(noexcept(++origin_simd[0]));
+ assert(((T)(++origin_simd[0]) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(4)));
+ static_assert(noexcept(origin_simd[0]++));
+ assert(((T)(origin_simd[0]++) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(5)));
+ static_assert(noexcept(--origin_simd[0]));
+ assert(((T)(--origin_simd[0]) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(4)));
+ static_assert(noexcept(origin_simd[0]--));
+ assert(((T)(origin_simd[0]--) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(3)));
+ }
+};
+
+template <class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>
+struct has_pre_increment : std::false_type {};
+
+template <class T, class SimdAbi>
+struct has_pre_increment<T, SimdAbi, std::void_t<decltype(++std::declval<ex::simd<T, SimdAbi>>()[0])>>
+ : std::true_type {};
+
+template <class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>
+struct has_post_increment : std::false_type {};
+
+template <class T, class SimdAbi>
+struct has_post_increment<T, SimdAbi, std::void_t<decltype(std::declval<ex::simd<T, SimdAbi>>()[0]++)>>
+ : std::true_type {};
+
+template <class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>
+struct has_pre_decrement : std::false_type {};
+
+template <class T, class SimdAbi>
+struct has_pre_decrement<T, SimdAbi, std::void_t<decltype(--std::declval<ex::simd<T, SimdAbi>>()[0])>>
+ : std::true_type {};
+
+template <class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>
+struct has_post_decrement : std::false_type {};
+
+template <class T, class SimdAbi>
+struct has_post_decrement<T, SimdAbi, std::void_t<decltype(std::declval<ex::simd<T, SimdAbi>>()[0]--)>>
+ : std::true_type {};
+
+template <class T, std::size_t>
+struct CheckSimdReferenceUnaryTraits {
+ template <class SimdAbi>
+ void operator()() {
+ if constexpr (std::is_floating_point_v<T>) {
+ static_assert(!has_pre_increment<T, SimdAbi>::value);
+ static_assert(!has_post_increment<T, SimdAbi>::value);
+ static_assert(!has_pre_decrement<T, SimdAbi>::value);
+ static_assert(!has_post_decrement<T, SimdAbi>::value);
+ } else {
+ static_assert(has_pre_increment<T, SimdAbi>::value);
+ static_assert(has_post_increment<T, SimdAbi>::value);
+ static_assert(has_pre_decrement<T, SimdAbi>::value);
+ static_assert(has_post_decrement<T, SimdAbi>::value);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckSimdReferenceUnaryOperators>());
+ test_all_simd_abi<CheckSimdReferenceUnaryTraits>();
+ return 0;
+}
More information about the libcxx-commits
mailing list