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 AndAssign {
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 OrAssign {
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 XorAssign {
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 LeftShiftAssign {
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 RightShiftAssign {
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
62struct LeftShift {
63 template <typename T, typename U>
64 T operator()(const T& lhs, const U& rhs) const noexcept {
65 return lhs << rhs;
66 }
67};
68
69struct RightShift {
70 template <typename T, typename U>
71 T operator()(const T& lhs, const U& rhs) const noexcept {
72 return lhs >> rhs;
73 }
74};
75
76template <typename T, typename SimdAbi, typename Op, typename OpAssign>
77struct SimdReferenceOperatorHelper {
78 template <class U>
79 void operator()() const {
80 ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
81 static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2))));
82 OpAssign{}(origin_simd[0], static_cast<U>(2));
83 assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2))));
84 }
85};
86
87template <typename T, typename SimdAbi, typename Op, typename OpAssign>
88struct MaskReferenceOperatorHelper {
89 template <class U>
90 void operator()() const {
91 ex::simd_mask<T, SimdAbi> origin_mask(true);
92 static_assert(noexcept(OpAssign{}(origin_mask[0], static_cast<U>(false))));
93 OpAssign{}(origin_mask[0], static_cast<U>(false));
94 assert((bool)origin_mask[0] == (bool)Op{}(true, static_cast<bool>(std::forward<U>(false))));
95 }
96};
97
98template <class T, std::size_t>
99struct CheckReferenceBitwiseOperators {
100 template <class SimdAbi>
101 void operator()() {
102 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>());
103 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>());
104 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>());
105 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, LeftShift, LeftShiftAssign>());
106 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, RightShift, RightShiftAssign>());
107
108 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>());
109 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>());
110 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>());
111 }
112};
113
114int main(int, char**) {
115 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceBitwiseOperators>());
116 return 0;
117}
118

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