Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/clover/util/algorithm.hpp
4572 views
1
//
2
// Copyright 2013 Francisco Jerez
3
//
4
// Permission is hereby granted, free of charge, to any person obtaining a
5
// copy of this software and associated documentation files (the "Software"),
6
// to deal in the Software without restriction, including without limitation
7
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
// and/or sell copies of the Software, and to permit persons to whom the
9
// Software is furnished to do so, subject to the following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included in
12
// all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
// OTHER DEALINGS IN THE SOFTWARE.
21
//
22
23
#ifndef CLOVER_UTIL_ALGORITHM_HPP
24
#define CLOVER_UTIL_ALGORITHM_HPP
25
26
#include <algorithm>
27
#include <sstream>
28
#include <stdexcept>
29
30
#include "util/range.hpp"
31
#include "util/functional.hpp"
32
33
namespace clover {
34
namespace detail {
35
template<typename R>
36
using preferred_reference_type = decltype(*std::declval<R>().begin());
37
}
38
39
///
40
/// Return the first element in a range.
41
///
42
template<typename R>
43
detail::preferred_reference_type<R>
44
head(R &&r) {
45
assert(!r.empty());
46
return r.front();
47
}
48
49
///
50
/// Return all elements in a range but the first.
51
///
52
template<typename R>
53
slice_range<R>
54
tail(R &&r) {
55
assert(!r.empty());
56
return { std::forward<R>(r), 1, r.size() };
57
}
58
59
///
60
/// Return the only element in a range.
61
///
62
template<typename R>
63
detail::preferred_reference_type<R>
64
unique(R &&r) {
65
if (r.size() != 1)
66
throw std::out_of_range("");
67
68
return r.front();
69
}
70
71
///
72
/// Combine a variable number of ranges element-wise in a single
73
/// range of tuples.
74
///
75
template<typename... Rs>
76
adaptor_range<zips, Rs...>
77
zip(Rs &&... rs) {
78
return map(zips(), std::forward<Rs>(rs)...);
79
}
80
81
///
82
/// Evaluate the elements of a range.
83
///
84
/// Useful because most of the range algorithms evaluate their
85
/// result lazily.
86
///
87
template<typename R>
88
void
89
eval(R &&r) {
90
for (auto i = r.begin(), e = r.end(); i != e; ++i)
91
*i;
92
}
93
94
///
95
/// Apply functor \a f element-wise on a variable number of ranges
96
/// \a rs.
97
///
98
/// The functor \a f should take as many arguments as ranges are
99
/// provided.
100
///
101
template<typename F, typename... Rs>
102
void
103
for_each(F &&f, Rs &&... rs) {
104
eval(map(std::forward<F>(f), std::forward<Rs>(rs)...));
105
}
106
107
///
108
/// Copy all elements from range \a r into an output container
109
/// starting from iterator \a i.
110
///
111
template<typename R, typename I>
112
void
113
copy(R &&r, I i) {
114
for (detail::preferred_reference_type<R> x : r)
115
*(i++) = x;
116
}
117
118
///
119
/// Reduce the elements of range \a r by applying functor \a f
120
/// element by element.
121
///
122
/// \a f should take an accumulator value (which is initialized to
123
/// \a a) and an element value as arguments, and return an updated
124
/// accumulator value.
125
///
126
/// \returns The final value of the accumulator.
127
///
128
template<typename F, typename A, typename R>
129
A
130
fold(F &&f, A a, R &&r) {
131
for (detail::preferred_reference_type<R> x : r)
132
a = f(a, x);
133
134
return a;
135
}
136
137
///
138
/// Return how many elements of range \a r are equal to \a x.
139
///
140
template<typename T, typename R>
141
typename std::remove_reference<R>::type::size_type
142
count(T &&x, R &&r) {
143
typename std::remove_reference<R>::type::size_type n = 0;
144
145
for (detail::preferred_reference_type<R> y : r) {
146
if (x == y)
147
n++;
148
}
149
150
return n;
151
}
152
153
///
154
/// Return the first element in range \a r for which predicate \a f
155
/// evaluates to true.
156
///
157
template<typename F, typename R>
158
detail::preferred_reference_type<R>
159
find(F &&f, R &&r) {
160
for (detail::preferred_reference_type<R> x : r) {
161
if (f(x))
162
return x;
163
}
164
165
throw std::out_of_range("");
166
}
167
168
///
169
/// Return true if the element-wise application of predicate \a f
170
/// on \a rs evaluates to true for all elements.
171
///
172
template<typename F, typename... Rs>
173
bool
174
all_of(F &&f, Rs &&... rs) {
175
for (auto b : map(f, rs...)) {
176
if (!b)
177
return false;
178
}
179
180
return true;
181
}
182
183
///
184
/// Return true if the element-wise application of predicate \a f
185
/// on \a rs evaluates to true for any element.
186
///
187
template<typename F, typename... Rs>
188
bool
189
any_of(F &&f, Rs &&... rs) {
190
for (auto b : map(f, rs...)) {
191
if (b)
192
return true;
193
}
194
195
return false;
196
}
197
198
///
199
/// Erase elements for which predicate \a f evaluates to true from
200
/// container \a r.
201
///
202
template<typename F, typename R>
203
void
204
erase_if(F &&f, R &&r) {
205
auto i = r.begin(), e = r.end();
206
207
for (auto j = r.begin(); j != e; ++j) {
208
if (!f(*j)) {
209
if (j != i)
210
*i = std::move(*j);
211
++i;
212
}
213
}
214
215
r.erase(i, e);
216
}
217
218
///
219
/// Build a vector of string from a space separated string
220
/// quoted parts content is preserved and unquoted
221
///
222
inline std::vector<std::string>
223
tokenize(const std::string &s) {
224
std::vector<std::string> ss;
225
std::ostringstream oss;
226
227
// OpenCL programs can pass a quoted argument, most frequently the
228
// include path. This is useful so that path containing spaces is
229
// treated as a single argument instead of being split by the spaces.
230
// Additionally, the argument should also be unquoted before being
231
// passed to the compiler. We avoid using std::string::replace here to
232
// remove quotes, as the single and double quote characters can be a
233
// part of the file name.
234
bool escape_next = false;
235
bool in_quote_double = false;
236
bool in_quote_single = false;
237
238
for (auto c : s) {
239
if (escape_next) {
240
oss.put(c);
241
escape_next = false;
242
} else if (c == '\\') {
243
escape_next = true;
244
} else if (c == '"' && !in_quote_single) {
245
in_quote_double = !in_quote_double;
246
} else if (c == '\'' && !in_quote_double) {
247
in_quote_single = !in_quote_single;
248
} else if (c != ' ' || in_quote_single || in_quote_double) {
249
oss.put(c);
250
} else if (oss.tellp() > 0) {
251
ss.emplace_back(oss.str());
252
oss.str("");
253
}
254
}
255
256
if (oss.tellp() > 0)
257
ss.emplace_back(oss.str());
258
259
if (in_quote_double || in_quote_single)
260
throw invalid_build_options_error();
261
262
return ss;
263
}
264
265
///
266
/// Build a \a sep separated string from a vector of T
267
///
268
template<typename T>
269
std::string
270
detokenize(const std::vector<T> &ss, const std::string &sep) {
271
std::string r;
272
273
for (const auto &s : ss)
274
r += (r.empty() ? "" : sep) + std::to_string(s);
275
276
return r;
277
}
278
279
///
280
/// Build a \a sep separated string from a vector of string
281
///
282
template <>
283
inline std::string
284
detokenize(const std::vector<std::string> &ss, const std::string &sep) {
285
std::string r;
286
287
for (const auto &s : ss)
288
r += (r.empty() || s.empty() ? "" : sep) + s;
289
290
return r;
291
}
292
}
293
294
#endif
295
296