clover: Migrate a bunch of pointers and references in the object tree to smart refere...
[mesa.git] / src / gallium / state_trackers / clover / util / functional.hpp
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_FUNCTIONAL_HPP
24 #define CLOVER_UTIL_FUNCTIONAL_HPP
25
26 #include <type_traits>
27
28 namespace clover {
29 struct identity {
30 template<typename T>
31 typename std::remove_reference<T>::type
32 operator()(T &&x) const {
33 return x;
34 }
35 };
36
37 struct plus {
38 template<typename T, typename S>
39 typename std::common_type<T, S>::type
40 operator()(T x, S y) const {
41 return x + y;
42 }
43 };
44
45 struct minus {
46 template<typename T, typename S>
47 typename std::common_type<T, S>::type
48 operator()(T x, S y) const {
49 return x - y;
50 }
51 };
52
53 struct negate {
54 template<typename T>
55 T
56 operator()(T x) const {
57 return -x;
58 }
59 };
60
61 struct multiplies {
62 template<typename T, typename S>
63 typename std::common_type<T, S>::type
64 operator()(T x, S y) const {
65 return x * y;
66 }
67 };
68
69 struct divides {
70 template<typename T, typename S>
71 typename std::common_type<T, S>::type
72 operator()(T x, S y) const {
73 return x / y;
74 }
75 };
76
77 struct modulus {
78 template<typename T, typename S>
79 typename std::common_type<T, S>::type
80 operator()(T x, S y) const {
81 return x % y;
82 }
83 };
84
85 struct minimum {
86 template<typename T>
87 T
88 operator()(T x) const {
89 return x;
90 }
91
92 template<typename T, typename... Ts>
93 T
94 operator()(T x, Ts... xs) const {
95 T y = minimum()(xs...);
96 return x < y ? x : y;
97 }
98 };
99
100 struct maximum {
101 template<typename T>
102 T
103 operator()(T x) const {
104 return x;
105 }
106
107 template<typename T, typename... Ts>
108 T
109 operator()(T x, Ts... xs) const {
110 T y = maximum()(xs...);
111 return x < y ? y : x;
112 }
113 };
114
115 struct preincs {
116 template<typename T>
117 T &
118 operator()(T &x) const {
119 return ++x;
120 }
121 };
122
123 struct predecs {
124 template<typename T>
125 T &
126 operator()(T &x) const {
127 return --x;
128 }
129 };
130
131 template<typename T>
132 class multiplies_by_t {
133 public:
134 multiplies_by_t(T x) : x(x) {
135 }
136
137 template<typename S>
138 typename std::common_type<T, S>::type
139 operator()(S y) const {
140 return x * y;
141 }
142
143 private:
144 T x;
145 };
146
147 template<typename T>
148 multiplies_by_t<T>
149 multiplies_by(T x) {
150 return { x };
151 }
152
153 template<typename T>
154 class preincs_by_t {
155 public:
156 preincs_by_t(T n) : n(n) {
157 }
158
159 template<typename S>
160 S &
161 operator()(S &x) const {
162 return x += n;
163 }
164
165 private:
166 T n;
167 };
168
169 template<typename T>
170 preincs_by_t<T>
171 preincs_by(T n) {
172 return { n };
173 }
174
175 template<typename T>
176 class predecs_by_t {
177 public:
178 predecs_by_t(T n) : n(n) {
179 }
180
181 template<typename S>
182 S &
183 operator()(S &x) const {
184 return x -= n;
185 }
186
187 private:
188 T n;
189 };
190
191 template<typename T>
192 predecs_by_t<T>
193 predecs_by(T n) {
194 return { n };
195 }
196
197 struct greater {
198 template<typename T, typename S>
199 bool
200 operator()(T x, S y) const {
201 return x > y;
202 }
203 };
204
205 struct evals {
206 template<typename T>
207 auto
208 operator()(T &&x) const -> decltype(x()) {
209 return x();
210 }
211 };
212
213 struct derefs {
214 template<typename T>
215 auto
216 operator()(T &&x) const -> decltype(*x) {
217 return *x;
218 }
219 };
220
221 struct addresses {
222 template<typename T>
223 T *
224 operator()(T &x) const {
225 return &x;
226 }
227
228 template<typename T>
229 T *
230 operator()(std::reference_wrapper<T> x) const {
231 return &x.get();
232 }
233 };
234
235 struct begins {
236 template<typename T>
237 auto
238 operator()(T &x) const -> decltype(x.begin()) {
239 return x.begin();
240 }
241 };
242
243 struct ends {
244 template<typename T>
245 auto
246 operator()(T &x) const -> decltype(x.end()) {
247 return x.end();
248 }
249 };
250
251 struct sizes {
252 template<typename T>
253 auto
254 operator()(T &x) const -> decltype(x.size()) {
255 return x.size();
256 }
257 };
258
259 template<typename T>
260 class advances_by_t {
261 public:
262 advances_by_t(T n) : n(n) {
263 }
264
265 template<typename S>
266 S
267 operator()(S &&it) const {
268 std::advance(it, n);
269 return it;
270 }
271
272 private:
273 T n;
274 };
275
276 template<typename T>
277 advances_by_t<T>
278 advances_by(T n) {
279 return { n };
280 }
281
282 struct zips {
283 template<typename... Ts>
284 std::tuple<Ts...>
285 operator()(Ts &&... xs) const {
286 return std::tuple<Ts...>(std::forward<Ts>(xs)...);
287 }
288 };
289
290 struct is_zero {
291 template<typename T>
292 bool
293 operator()(const T &x) const {
294 return x == 0;
295 }
296 };
297
298 struct keys {
299 template<typename P>
300 auto
301 operator()(P &&p) const -> decltype(std::get<0>(std::forward<P>(p))) {
302 return std::get<0>(std::forward<P>(p));
303 }
304 };
305
306 struct values {
307 template<typename P>
308 auto
309 operator()(P &&p) const -> decltype(std::get<1>(std::forward<P>(p))) {
310 return std::get<1>(std::forward<P>(p));
311 }
312 };
313
314 class name_equals {
315 public:
316 name_equals(const std::string &name) : name(name) {
317 }
318
319 template<typename T>
320 bool
321 operator()(const T &x) const {
322 return std::string(x.name.begin(), x.name.end()) == name;
323 }
324
325 private:
326 const std::string &name;
327 };
328
329 template<typename T>
330 class key_equals_t {
331 public:
332 key_equals_t(T &&x) : x(x) {
333 }
334
335 template<typename S>
336 bool
337 operator()(const std::pair<T, S> &p) const {
338 return p.first == x;
339 }
340
341 private:
342 T x;
343 };
344
345 template<typename T>
346 key_equals_t<T>
347 key_equals(T &&x) {
348 return { std::forward<T>(x) };
349 }
350
351 template<typename T>
352 class type_equals_t {
353 public:
354 type_equals_t(T type) : type(type) {
355 }
356
357 template<typename S>
358 bool
359 operator()(const S &x) const {
360 return x.type == type;
361 }
362
363 private:
364 T type;
365 };
366
367 template<typename T>
368 type_equals_t<T>
369 type_equals(T x) {
370 return { x };
371 }
372
373 struct interval_overlaps {
374 template<typename T>
375 bool
376 operator()(T x0, T x1, T y0, T y1) {
377 return ((x0 <= y0 && y0 < x1) ||
378 (y0 <= x0 && x0 < y1));
379 }
380 };
381 }
382
383 #endif