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 28namespace 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 template<typename T> 315 class equals_t { 316 public: 317 equals_t(T &&x) : x(x) {} 318 319 template<typename S> 320 bool 321 operator()(S &&y) const { 322 return x == y; 323 } 324 325 private: 326 T x; 327 }; 328 329 template<typename T> 330 equals_t<T> 331 equals(T &&x) { 332 return { std::forward<T>(x) }; 333 } 334 335 class name_equals { 336 public: 337 name_equals(const std::string &name) : name(name) { 338 } 339 340 template<typename T> 341 bool 342 operator()(const T &x) const { 343 return std::string(x.name.begin(), x.name.end()) == name; 344 } 345 346 private: 347 const std::string &name; 348 }; 349 350 template<typename T> 351 class key_equals_t { 352 public: 353 key_equals_t(T &&x) : x(x) { 354 } 355 356 template<typename P> 357 bool 358 operator()(const P &p) const { 359 return p.first == x; 360 } 361 362 private: 363 T x; 364 }; 365 366 template<typename T> 367 key_equals_t<T> 368 key_equals(T &&x) { 369 return { std::forward<T>(x) }; 370 } 371 372 template<typename T> 373 class type_equals_t { 374 public: 375 type_equals_t(T type) : type(type) { 376 } 377 378 template<typename S> 379 bool 380 operator()(const S &x) const { 381 return x.type == type; 382 } 383 384 private: 385 T type; 386 }; 387 388 template<typename T> 389 type_equals_t<T> 390 type_equals(T x) { 391 return { x }; 392 } 393 394 struct interval_overlaps { 395 template<typename T> 396 bool 397 operator()(T x0, T x1, T y0, T y1) { 398 return ((x0 <= y0 && y0 < x1) || 399 (y0 <= x0 && x0 < y1)); 400 } 401 }; 402} 403 404#endif 405