]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/where.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / where.cc
1 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // expensive: * [1-9] * *
19 #include "bits/verify.h"
20 #include "bits/make_vec.h"
21 #include "bits/metahelpers.h"
22
23 template <class V>
24 struct Convertible
25 {
26 operator V() const { return V(4); }
27 };
28
29 template <class M, class T>
30 constexpr bool
31 where_is_ill_formed_impl(M, const T&, float)
32 {
33 return true;
34 }
35
36 template <class M, class T>
37 constexpr auto
38 where_is_ill_formed_impl(M m, const T& v, int)
39 -> std::conditional_t<true, bool, decltype(std::experimental::where(m, v))>
40 {
41 return false;
42 }
43
44 template <class M, class T>
45 constexpr bool
46 where_is_ill_formed(M m, const T& v)
47 {
48 return where_is_ill_formed_impl(m, v, int());
49 }
50
51 template <typename T>
52 void
53 where_fundamental()
54 {
55 using std::experimental::where;
56 T x = T();
57 where(true, x) = x + 1;
58 COMPARE(x, T(1));
59 where(false, x) = x - 1;
60 COMPARE(x, T(1));
61 where(true, x) += T(1);
62 COMPARE(x, T(2));
63 }
64
65 template <typename V>
66 void
67 test()
68 {
69 using M = typename V::mask_type;
70 using T = typename V::value_type;
71 where_fundamental<T>();
72 VERIFY(!(sfinae_is_callable<V>(
73 [](auto x) -> decltype(where(true, x))* { return nullptr; })));
74
75 const V indexes([](int i) { return i + 1; });
76 const M alternating_mask = make_mask<M>({true, false});
77 V x = 0;
78 where(alternating_mask, x) = indexes;
79 COMPARE(alternating_mask, x == indexes);
80
81 where(!alternating_mask, x) = T(2);
82 COMPARE(!alternating_mask, x == T(2)) << x;
83
84 where(!alternating_mask, x) = Convertible<V>();
85 COMPARE(!alternating_mask, x == T(4));
86
87 x = 0;
88 COMPARE(x, T(0));
89 where(alternating_mask, x) += indexes;
90 COMPARE(alternating_mask, x == indexes);
91
92 x = 10;
93 COMPARE(x, T(10));
94 where(!alternating_mask, x) += T(1);
95 COMPARE(!alternating_mask, x == T(11));
96 where(alternating_mask, x) -= Convertible<V>();
97 COMPARE(alternating_mask, x == T(6));
98 constexpr bool fast_math =
99 #ifdef __FAST_MATH__
100 true;
101 #else
102 false;
103 #endif
104 if constexpr (fast_math && std::is_floating_point_v<T>)
105 where(alternating_mask, x) *= T(.5);
106 else
107 where(alternating_mask, x) /= T(2);
108 COMPARE(alternating_mask, x == T(3)) << "\nx = " << x;
109 where(alternating_mask, x) *= T(3);
110 COMPARE(alternating_mask, x == T(9));
111 COMPARE(!alternating_mask, x == T(11));
112
113 x = 10;
114 where(alternating_mask, x)++;
115 COMPARE(alternating_mask, x == T(11));
116 ++where(alternating_mask, x);
117 COMPARE(alternating_mask, x == T(12));
118 where(alternating_mask, x)--;
119 COMPARE(alternating_mask, x == T(11));
120 --where(alternating_mask, x);
121 --where(alternating_mask, x);
122 COMPARE(alternating_mask, x == T(9));
123 COMPARE(alternating_mask, -where(alternating_mask, x) == T(-T(9)));
124
125 const auto y = x;
126 VERIFY(where_is_ill_formed(true, y));
127 VERIFY(where_is_ill_formed(true, x));
128 VERIFY(where_is_ill_formed(true, V(x)));
129
130 M test = alternating_mask;
131 where(alternating_mask, test) = M(true);
132 COMPARE(test, alternating_mask);
133 where(alternating_mask, test) = M(false);
134 COMPARE(test, M(false));
135 where(alternating_mask, test) = M(true);
136 COMPARE(test, alternating_mask);
137 }