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// template<class U> reference+=(U&& x) && noexcept;
15// template<class U> reference-=(U&& x) && noexcept;
16// template<class U> reference*=(U&& x) && noexcept;
17// template<class U> reference/=(U&& x) && noexcept;
18// template<class U> reference%=(U&& x) && noexcept;
19
20#include <experimental/simd>
21#include <functional>
22
23#include "../test_utils.h"
24
25namespace ex = std::experimental::parallelism_v2;
26
27struct PlusAssign {
28 template <typename T, typename U>
29 void operator()(T&& lhs, const U& rhs) const noexcept {
30 std::forward<T>(lhs) += rhs;
31 }
32};
33
34struct MinusAssign {
35 template <typename T, typename U>
36 void operator()(T&& lhs, const U& rhs) const noexcept {
37 std::forward<T>(lhs) -= rhs;
38 }
39};
40
41struct MultipliesAssign {
42 template <typename T, typename U>
43 void operator()(T&& lhs, const U& rhs) const noexcept {
44 std::forward<T>(lhs) *= rhs;
45 }
46};
47
48struct DividesAssign {
49 template <typename T, typename U>
50 void operator()(T&& lhs, const U& rhs) const noexcept {
51 std::forward<T>(lhs) /= rhs;
52 }
53};
54
55struct ModulusAssign {
56 template <typename T, typename U>
57 void operator()(T&& lhs, const U& rhs) const noexcept {
58 std::forward<T>(lhs) %= rhs;
59 }
60};
61
62template <typename T, typename SimdAbi, typename Op, typename OpAssign>
63struct SimdReferenceOperatorHelper {
64 template <class U>
65 void operator()() const {
66 ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
67 static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2))));
68 OpAssign{}(origin_simd[0], static_cast<U>(2));
69 assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2))));
70 }
71};
72
73template <class T, std::size_t>
74struct CheckReferenceArithOperators {
75 template <class SimdAbi>
76 void operator()() {
77 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::plus<>, PlusAssign>());
78 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::minus<>, MinusAssign>());
79 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::multiplies<>, MultipliesAssign>());
80 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::divides<>, DividesAssign>());
81 }
82};
83
84template <class T, std::size_t>
85struct CheckReferenceModOperators {
86 template <class SimdAbi>
87 void operator()() {
88 types::for_each(
89 simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::modulus<>, ModulusAssign>());
90 }
91};
92
93int main(int, char**) {
94 test_all_simd_abi<CheckReferenceArithOperators>();
95 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceModOperators>());
96 return 0;
97}
98

source code of libcxx/test/std/experimental/simd/simd.reference/reference_arith_operators.pass.cpp