]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/simd/tests/mask_reductions.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / mask_reductions.cc
CommitLineData
83ffe9cd 1// Copyright (C) 2020-2023 Free Software Foundation, Inc.
02e32295
MK
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
aa89c53c 18// expensive: * [1-9] * *
02e32295
MK
19#include "bits/verify.h"
20#include "bits/metahelpers.h"
21
22// simd_mask generator functions
23template <class M>
24 M
25 make_mask(const std::initializer_list<bool>& init)
26 {
27 std::size_t i = 0;
28 M r = {};
29 for (;;)
30 {
31 for (bool x : init)
32 {
33 r[i] = x;
34 if (++i == M::size())
35 {
36 return r;
37 }
38 }
39 }
40 }
41
42template <class M>
43 M
44 make_alternating_mask()
45 {
46 return make_mask<M>({false, true});
47 }
48
49template <typename V>
50 void
51 test()
52 {
53 using M = typename V::mask_type;
54 const M alternating_mask = make_alternating_mask<M>();
55 COMPARE(alternating_mask[0], false); // assumption below
56 auto&& gen = make_mask<M>;
57
58 // all_of
59 VERIFY(all_of(M{true}));
60 VERIFY(!all_of(alternating_mask));
61 VERIFY(!all_of(M{false}));
62 using std::experimental::all_of;
63 VERIFY(all_of(true));
64 VERIFY(!all_of(false));
65 VERIFY(sfinae_is_callable<bool>(
66 [](auto x) -> decltype(std::experimental::all_of(x)) { return {}; }));
67 VERIFY(!sfinae_is_callable<int>(
68 [](auto x) -> decltype(std::experimental::all_of(x)) { return {}; }));
69 VERIFY(!sfinae_is_callable<float>(
70 [](auto x) -> decltype(std::experimental::all_of(x)) { return {}; }));
71 VERIFY(!sfinae_is_callable<char>(
72 [](auto x) -> decltype(std::experimental::all_of(x)) { return {}; }));
73
74 // any_of
75 VERIFY(any_of(M{true}));
76 COMPARE(any_of(alternating_mask), M::size() > 1);
77 VERIFY(!any_of(M{false}));
78 using std::experimental::any_of;
79 VERIFY(any_of(true));
80 VERIFY(!any_of(false));
81 VERIFY(sfinae_is_callable<bool>(
82 [](auto x) -> decltype(std::experimental::any_of(x)) { return {}; }));
83 VERIFY(!sfinae_is_callable<int>(
84 [](auto x) -> decltype(std::experimental::any_of(x)) { return {}; }));
85 VERIFY(!sfinae_is_callable<float>(
86 [](auto x) -> decltype(std::experimental::any_of(x)) { return {}; }));
87 VERIFY(!sfinae_is_callable<char>(
88 [](auto x) -> decltype(std::experimental::any_of(x)) { return {}; }));
89
90 // none_of
91 VERIFY(!none_of(M{true}));
92 COMPARE(none_of(alternating_mask), M::size() == 1);
93 VERIFY(none_of(M{false}));
94 using std::experimental::none_of;
95 VERIFY(!none_of(true));
96 VERIFY(none_of(false));
97 VERIFY(sfinae_is_callable<bool>(
98 [](auto x) -> decltype(std::experimental::none_of(x)) { return {}; }));
99 VERIFY(!sfinae_is_callable<int>(
100 [](auto x) -> decltype(std::experimental::none_of(x)) { return {}; }));
101 VERIFY(!sfinae_is_callable<float>(
102 [](auto x) -> decltype(std::experimental::none_of(x)) { return {}; }));
103 VERIFY(!sfinae_is_callable<char>(
104 [](auto x) -> decltype(std::experimental::none_of(x)) { return {}; }));
105
106 // some_of
107 VERIFY(!some_of(M{true}));
108 VERIFY(!some_of(M{false}));
109 if (M::size() > 1)
110 {
111 VERIFY(some_of(gen({true, false})));
112 VERIFY(some_of(gen({false, true})));
113 if (M::size() > 3)
114 {
115 VERIFY(some_of(gen({0, 0, 0, 1})));
116 }
117 }
118 using std::experimental::some_of;
119 VERIFY(!some_of(true));
120 VERIFY(!some_of(false));
121 VERIFY(sfinae_is_callable<bool>(
122 [](auto x) -> decltype(std::experimental::some_of(x)) { return {}; }));
123 VERIFY(!sfinae_is_callable<int>(
124 [](auto x) -> decltype(std::experimental::some_of(x)) { return {}; }));
125 VERIFY(!sfinae_is_callable<float>(
126 [](auto x) -> decltype(std::experimental::some_of(x)) { return {}; }));
127 VERIFY(!sfinae_is_callable<char>(
128 [](auto x) -> decltype(std::experimental::some_of(x)) { return {}; }));
129
130 // popcount
131 COMPARE(popcount(M{true}), int(M::size()));
132 COMPARE(popcount(alternating_mask), int(M::size()) / 2);
133 COMPARE(popcount(M{false}), 0);
134 COMPARE(popcount(gen({0, 0, 1})), int(M::size()) / 3);
135 COMPARE(popcount(gen({0, 0, 0, 1})), int(M::size()) / 4);
136 COMPARE(popcount(gen({0, 0, 0, 0, 1})), int(M::size()) / 5);
137 COMPARE(std::experimental::popcount(true), 1);
138 COMPARE(std::experimental::popcount(false), 0);
139 VERIFY(sfinae_is_callable<bool>(
140 [](auto x) -> decltype(std::experimental::popcount(x)) { return {}; }));
141 VERIFY(!sfinae_is_callable<int>(
142 [](auto x) -> decltype(std::experimental::popcount(x)) { return {}; }));
143 VERIFY(!sfinae_is_callable<float>(
144 [](auto x) -> decltype(std::experimental::popcount(x)) { return {}; }));
145 VERIFY(!sfinae_is_callable<char>(
146 [](auto x) -> decltype(std::experimental::popcount(x)) { return {}; }));
147
148 // find_first_set
149 {
150 M x(false);
151 for (int i = int(M::size() / 2 - 1); i >= 0; --i)
152 {
153 x[i] = true;
154 COMPARE(find_first_set(x), i) << x;
155 }
156 x = M(false);
157 for (int i = int(M::size() - 1); i >= 0; --i)
158 {
159 x[i] = true;
160 COMPARE(find_first_set(x), i) << x;
161 }
162 }
163 COMPARE(find_first_set(M{true}), 0);
164 if (M::size() > 1)
165 {
166 COMPARE(find_first_set(gen({0, 1})), 1);
167 }
168 if (M::size() > 2)
169 {
170 COMPARE(find_first_set(gen({0, 0, 1})), 2);
171 }
172 COMPARE(std::experimental::find_first_set(true), 0);
173 VERIFY(sfinae_is_callable<bool>(
174 [](auto x) -> decltype(std::experimental::find_first_set(x)) {
175 return {};
176 }));
177 VERIFY(!sfinae_is_callable<int>(
178 [](auto x) -> decltype(std::experimental::find_first_set(x)) {
179 return {};
180 }));
181 VERIFY(!sfinae_is_callable<float>(
182 [](auto x) -> decltype(std::experimental::find_first_set(x)) {
183 return {};
184 }));
185 VERIFY(!sfinae_is_callable<char>(
186 [](auto x) -> decltype(std::experimental::find_first_set(x)) {
187 return {};
188 }));
189
190 // find_last_set
191 {
192 M x(false);
193 for (int i = 0; i < int(M::size()); ++i)
194 {
195 x[i] = true;
196 COMPARE(find_last_set(x), i) << x;
197 }
198 }
199 COMPARE(find_last_set(M{true}), int(M::size()) - 1);
200 if (M::size() > 1)
201 {
202 COMPARE(find_last_set(gen({1, 0})),
203 int(M::size()) - 2 + int(M::size() & 1));
204 }
205 if (M::size() > 3 && (M::size() & 3) == 0)
206 {
207 COMPARE(find_last_set(gen({1, 0, 0, 0})),
208 int(M::size()) - 4 - int(M::size() & 3));
209 }
210 COMPARE(std::experimental::find_last_set(true), 0);
211 VERIFY(sfinae_is_callable<bool>(
212 [](auto x) -> decltype(std::experimental::find_last_set(x)) {
213 return {};
214 }));
215 VERIFY(!sfinae_is_callable<int>(
216 [](auto x) -> decltype(std::experimental::find_last_set(x)) {
217 return {};
218 }));
219 VERIFY(!sfinae_is_callable<float>(
220 [](auto x) -> decltype(std::experimental::find_last_set(x)) {
221 return {};
222 }));
223 VERIFY(!sfinae_is_callable<char>(
224 [](auto x) -> decltype(std::experimental::find_last_set(x)) {
225 return {};
226 }));
227 }