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] `_, "`Element references operator= `_", None, Yin Zhang, |Complete| | `[parallel.simd.reference] `_, "`Element references swap functions `_", None, Yin Zhang, |Complete| | `[parallel.simd.reference] `_, "`Element references compound assignment operators `_", None, Yin Zhang, |Complete| +| `[parallel.simd.reference] `_, "`Element references unary operators ++/-- `_", None, Yin Zhang, |Complete| | `[parallel.simd.class] `_, "`Class template simd declaration and alias `_", [parallel.simd.abi], Yin Zhang, |Complete| | `[parallel.simd.class] `_, "`simd<>::size() `_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete| | `[parallel.simd.class] `_, "`simd default constructor `_", None, Yin Zhang, |Complete| diff --git a/libcxx/include/experimental/__simd/reference.h b/libcxx/include/experimental/__simd/reference.h index f5bb3ba688e43b..39f60d64f7b41f 100644 --- a/libcxx/include/experimental/__simd/reference.h +++ b/libcxx/include/experimental/__simd/reference.h @@ -132,6 +132,31 @@ class __simd_reference { __set(__get() >> static_cast(std::forward<_Up>(__v))); return {__s_, __idx_}; } + + // Note: All legal vectorizable types support operator++/--. + // There doesn't seem to be a way to trigger the constraint. + // Therefore, no SFINAE check is added here. + __simd_reference _LIBCPP_HIDE_FROM_ABI operator++() && noexcept { + __set(__get() + 1); + return {__s_, __idx_}; + } + + value_type _LIBCPP_HIDE_FROM_ABI operator++(int) && noexcept { + auto __r = __get(); + __set(__get() + 1); + return __r; + } + + __simd_reference _LIBCPP_HIDE_FROM_ABI operator--() && noexcept { + __set(__get() - 1); + return {__s_, __idx_}; + } + + value_type _LIBCPP_HIDE_FROM_ABI operator--(int) && noexcept { + auto __r = __get(); + __set(__get() - 1); + return __r; + } }; template 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..7452dc986cd4af --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// +// +// [simd.reference] +// reference operator++() && noexcept; +// value_type operator++(int) && noexcept; +// reference operator--() && noexcept; +// value_type operator--(int) && noexcept; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; + +template +struct CheckSimdReferenceUnaryOperators { + template + void operator()() const { + ex::simd origin_simd(static_cast(3)); + static_assert(noexcept(++origin_simd[0])); + assert(((T)(++origin_simd[0]) == static_cast(4)) && ((T)origin_simd[0] == static_cast(4))); + static_assert(noexcept(origin_simd[0]++)); + assert(((T)(origin_simd[0]++) == static_cast(4)) && ((T)origin_simd[0] == static_cast(5))); + static_assert(noexcept(--origin_simd[0])); + assert(((T)(--origin_simd[0]) == static_cast(4)) && ((T)origin_simd[0] == static_cast(4))); + static_assert(noexcept(origin_simd[0]--)); + assert(((T)(origin_simd[0]--) == static_cast(4)) && ((T)origin_simd[0] == static_cast(3))); + } +}; + +int main(int, char**) { + test_all_simd_abi(); + return 0; +}