xref: /llvm-project/libcxx/test/std/experimental/simd/simd.reference/reference_arith_operators.pass.cpp (revision 09e3a360581dc36d0820d3fb6da9bd7cfed87b5d)
1899055f2SZhangYin //===----------------------------------------------------------------------===//
2899055f2SZhangYin //
3899055f2SZhangYin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4899055f2SZhangYin // See https://llvm.org/LICENSE.txt for license information.
5899055f2SZhangYin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6899055f2SZhangYin //
7899055f2SZhangYin //===----------------------------------------------------------------------===//
8899055f2SZhangYin 
9899055f2SZhangYin // UNSUPPORTED: c++03, c++11, c++14
10899055f2SZhangYin 
11899055f2SZhangYin // <experimental/simd>
12899055f2SZhangYin //
13899055f2SZhangYin // [simd.reference]
14899055f2SZhangYin // template<class U> reference+=(U&& x) && noexcept;
15899055f2SZhangYin // template<class U> reference-=(U&& x) && noexcept;
16899055f2SZhangYin // template<class U> reference*=(U&& x) && noexcept;
17899055f2SZhangYin // template<class U> reference/=(U&& x) && noexcept;
18899055f2SZhangYin // template<class U> reference%=(U&& x) && noexcept;
19899055f2SZhangYin 
20899055f2SZhangYin #include <experimental/simd>
21*09e3a360SLouis Dionne #include <functional>
22*09e3a360SLouis Dionne 
23*09e3a360SLouis Dionne #include "../test_utils.h"
24899055f2SZhangYin 
25899055f2SZhangYin namespace ex = std::experimental::parallelism_v2;
26899055f2SZhangYin 
27899055f2SZhangYin struct PlusAssign {
28899055f2SZhangYin   template <typename T, typename U>
29899055f2SZhangYin   void operator()(T&& lhs, const U& rhs) const noexcept {
30899055f2SZhangYin     std::forward<T>(lhs) += rhs;
31899055f2SZhangYin   }
32899055f2SZhangYin };
33899055f2SZhangYin 
34899055f2SZhangYin struct MinusAssign {
35899055f2SZhangYin   template <typename T, typename U>
36899055f2SZhangYin   void operator()(T&& lhs, const U& rhs) const noexcept {
37899055f2SZhangYin     std::forward<T>(lhs) -= rhs;
38899055f2SZhangYin   }
39899055f2SZhangYin };
40899055f2SZhangYin 
41899055f2SZhangYin struct MultipliesAssign {
42899055f2SZhangYin   template <typename T, typename U>
43899055f2SZhangYin   void operator()(T&& lhs, const U& rhs) const noexcept {
44899055f2SZhangYin     std::forward<T>(lhs) *= rhs;
45899055f2SZhangYin   }
46899055f2SZhangYin };
47899055f2SZhangYin 
48899055f2SZhangYin struct DividesAssign {
49899055f2SZhangYin   template <typename T, typename U>
50899055f2SZhangYin   void operator()(T&& lhs, const U& rhs) const noexcept {
51899055f2SZhangYin     std::forward<T>(lhs) /= rhs;
52899055f2SZhangYin   }
53899055f2SZhangYin };
54899055f2SZhangYin 
55899055f2SZhangYin struct ModulusAssign {
56899055f2SZhangYin   template <typename T, typename U>
57899055f2SZhangYin   void operator()(T&& lhs, const U& rhs) const noexcept {
58899055f2SZhangYin     std::forward<T>(lhs) %= rhs;
59899055f2SZhangYin   }
60899055f2SZhangYin };
61899055f2SZhangYin 
62899055f2SZhangYin template <typename T, typename SimdAbi, typename Op, typename OpAssign>
63899055f2SZhangYin struct SimdReferenceOperatorHelper {
64899055f2SZhangYin   template <class U>
65899055f2SZhangYin   void operator()() const {
66899055f2SZhangYin     ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
67899055f2SZhangYin     static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2))));
68899055f2SZhangYin     OpAssign{}(origin_simd[0], static_cast<U>(2));
69899055f2SZhangYin     assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2))));
70899055f2SZhangYin   }
71899055f2SZhangYin };
72899055f2SZhangYin 
73899055f2SZhangYin template <class T, std::size_t>
74899055f2SZhangYin struct CheckReferenceArithOperators {
75899055f2SZhangYin   template <class SimdAbi>
76899055f2SZhangYin   void operator()() {
77899055f2SZhangYin     types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::plus<>, PlusAssign>());
78899055f2SZhangYin     types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::minus<>, MinusAssign>());
79899055f2SZhangYin     types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::multiplies<>, MultipliesAssign>());
80899055f2SZhangYin     types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::divides<>, DividesAssign>());
81899055f2SZhangYin   }
82899055f2SZhangYin };
83899055f2SZhangYin 
84899055f2SZhangYin template <class T, std::size_t>
85899055f2SZhangYin struct CheckReferenceModOperators {
86899055f2SZhangYin   template <class SimdAbi>
87899055f2SZhangYin   void operator()() {
88899055f2SZhangYin     types::for_each(
89899055f2SZhangYin         simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::modulus<>, ModulusAssign>());
90899055f2SZhangYin   }
91899055f2SZhangYin };
92899055f2SZhangYin 
93899055f2SZhangYin int main(int, char**) {
94899055f2SZhangYin   test_all_simd_abi<CheckReferenceArithOperators>();
95899055f2SZhangYin   types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceModOperators>());
96899055f2SZhangYin   return 0;
97899055f2SZhangYin }
98