xref: /llvm-project/libcxx/test/std/experimental/simd/simd.reference/reference_bitwise_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 AndAssign {
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 OrAssign {
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 XorAssign {
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 LeftShiftAssign {
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 RightShiftAssign {
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 struct LeftShift {
63899055f2SZhangYin   template <typename T, typename U>
64899055f2SZhangYin   T operator()(const T& lhs, const U& rhs) const noexcept {
65899055f2SZhangYin     return lhs << rhs;
66899055f2SZhangYin   }
67899055f2SZhangYin };
68899055f2SZhangYin 
69899055f2SZhangYin struct RightShift {
70899055f2SZhangYin   template <typename T, typename U>
71899055f2SZhangYin   T operator()(const T& lhs, const U& rhs) const noexcept {
72899055f2SZhangYin     return lhs >> rhs;
73899055f2SZhangYin   }
74899055f2SZhangYin };
75899055f2SZhangYin 
76899055f2SZhangYin template <typename T, typename SimdAbi, typename Op, typename OpAssign>
77899055f2SZhangYin struct SimdReferenceOperatorHelper {
78899055f2SZhangYin   template <class U>
79899055f2SZhangYin   void operator()() const {
80899055f2SZhangYin     ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
81899055f2SZhangYin     static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2))));
82899055f2SZhangYin     OpAssign{}(origin_simd[0], static_cast<U>(2));
83899055f2SZhangYin     assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2))));
84899055f2SZhangYin   }
85899055f2SZhangYin };
86899055f2SZhangYin 
87899055f2SZhangYin template <typename T, typename SimdAbi, typename Op, typename OpAssign>
88899055f2SZhangYin struct MaskReferenceOperatorHelper {
89899055f2SZhangYin   template <class U>
90899055f2SZhangYin   void operator()() const {
91899055f2SZhangYin     ex::simd_mask<T, SimdAbi> origin_mask(true);
92899055f2SZhangYin     static_assert(noexcept(OpAssign{}(origin_mask[0], static_cast<U>(false))));
93899055f2SZhangYin     OpAssign{}(origin_mask[0], static_cast<U>(false));
94899055f2SZhangYin     assert((bool)origin_mask[0] == (bool)Op{}(true, static_cast<bool>(std::forward<U>(false))));
95899055f2SZhangYin   }
96899055f2SZhangYin };
97899055f2SZhangYin 
98899055f2SZhangYin template <class T, std::size_t>
99899055f2SZhangYin struct CheckReferenceBitwiseOperators {
100899055f2SZhangYin   template <class SimdAbi>
101899055f2SZhangYin   void operator()() {
102899055f2SZhangYin     types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>());
103899055f2SZhangYin     types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>());
104899055f2SZhangYin     types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>());
105899055f2SZhangYin     types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, LeftShift, LeftShiftAssign>());
106899055f2SZhangYin     types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, RightShift, RightShiftAssign>());
107899055f2SZhangYin 
108899055f2SZhangYin     types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>());
109899055f2SZhangYin     types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>());
110899055f2SZhangYin     types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>());
111899055f2SZhangYin   }
112899055f2SZhangYin };
113899055f2SZhangYin 
114899055f2SZhangYin int main(int, char**) {
115899055f2SZhangYin   types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceBitwiseOperators>());
116899055f2SZhangYin   return 0;
117899055f2SZhangYin }
118