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 operator ()clover::identity32 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 operator ()clover::plus40 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 operator ()clover::minus48 operator()(T x, S y) const { 49 return x - y; 50 } 51 }; 52 53 struct negate { 54 template<typename T> 55 T operator ()clover::negate56 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 operator ()clover::multiplies64 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 operator ()clover::divides72 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 operator ()clover::modulus80 operator()(T x, S y) const { 81 return x % y; 82 } 83 }; 84 85 struct minimum { 86 template<typename T> 87 T operator ()clover::minimum88 operator()(T x) const { 89 return x; 90 } 91 92 template<typename T, typename... Ts> 93 T operator ()clover::minimum94 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 operator ()clover::maximum103 operator()(T x) const { 104 return x; 105 } 106 107 template<typename T, typename... Ts> 108 T operator ()clover::maximum109 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 & operator ()clover::preincs118 operator()(T &x) const { 119 return ++x; 120 } 121 }; 122 123 struct predecs { 124 template<typename T> 125 T & operator ()clover::predecs126 operator()(T &x) const { 127 return --x; 128 } 129 }; 130 131 template<typename T> 132 class multiplies_by_t { 133 public: multiplies_by_t(T x)134 multiplies_by_t(T x) : x(x) { 135 } 136 137 template<typename S> 138 typename std::common_type<T, S>::type operator ()(S y) const139 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> multiplies_by(T x)149 multiplies_by(T x) { 150 return { x }; 151 } 152 153 template<typename T> 154 class preincs_by_t { 155 public: preincs_by_t(T n)156 preincs_by_t(T n) : n(n) { 157 } 158 159 template<typename S> 160 S & operator ()(S & x) const161 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> preincs_by(T n)171 preincs_by(T n) { 172 return { n }; 173 } 174 175 template<typename T> 176 class predecs_by_t { 177 public: predecs_by_t(T n)178 predecs_by_t(T n) : n(n) { 179 } 180 181 template<typename S> 182 S & operator ()(S & x) const183 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> predecs_by(T n)193 predecs_by(T n) { 194 return { n }; 195 } 196 197 struct greater { 198 template<typename T, typename S> 199 bool operator ()clover::greater200 operator()(T x, S y) const { 201 return x > y; 202 } 203 }; 204 205 struct evals { 206 template<typename T> 207 auto operator ()clover::evals208 operator()(T &&x) const -> decltype(x()) { 209 return x(); 210 } 211 }; 212 213 struct derefs { 214 template<typename T> 215 auto operator ()clover::derefs216 operator()(T &&x) const -> decltype(*x) { 217 return *x; 218 } 219 }; 220 221 struct addresses { 222 template<typename T> 223 T * operator ()clover::addresses224 operator()(T &x) const { 225 return &x; 226 } 227 228 template<typename T> 229 T * operator ()clover::addresses230 operator()(std::reference_wrapper<T> x) const { 231 return &x.get(); 232 } 233 }; 234 235 struct begins { 236 template<typename T> 237 auto operator ()clover::begins238 operator()(T &x) const -> decltype(x.begin()) { 239 return x.begin(); 240 } 241 }; 242 243 struct ends { 244 template<typename T> 245 auto operator ()clover::ends246 operator()(T &x) const -> decltype(x.end()) { 247 return x.end(); 248 } 249 }; 250 251 struct sizes { 252 template<typename T> 253 auto operator ()clover::sizes254 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: advances_by_t(T n)262 advances_by_t(T n) : n(n) { 263 } 264 265 template<typename S> 266 S operator ()(S && it) const267 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> advances_by(T n)278 advances_by(T n) { 279 return { n }; 280 } 281 282 struct zips { 283 template<typename... Ts> 284 std::tuple<Ts...> operator ()clover::zips285 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 operator ()clover::is_zero293 operator()(const T &x) const { 294 return x == 0; 295 } 296 }; 297 298 struct keys { 299 template<typename P> 300 auto operator ()clover::keys301 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 operator ()clover::values309 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: equals_t(T && x)317 equals_t(T &&x) : x(x) {} 318 319 template<typename S> 320 bool operator ()(S && y) const321 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> equals(T && x)331 equals(T &&x) { 332 return { std::forward<T>(x) }; 333 } 334 335 class name_equals { 336 public: name_equals(const std::string & name)337 name_equals(const std::string &name) : name(name) { 338 } 339 340 template<typename T> 341 bool operator ()(const T & x) const342 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: key_equals_t(T && x)353 key_equals_t(T &&x) : x(x) { 354 } 355 356 template<typename P> 357 bool operator ()(const P & p) const358 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> key_equals(T && x)368 key_equals(T &&x) { 369 return { std::forward<T>(x) }; 370 } 371 372 template<typename T> 373 class type_equals_t { 374 public: type_equals_t(T type)375 type_equals_t(T type) : type(type) { 376 } 377 378 template<typename S> 379 bool operator ()(const S & x) const380 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> type_equals(T x)390 type_equals(T x) { 391 return { x }; 392 } 393 394 struct interval_overlaps { 395 template<typename T> 396 bool operator ()clover::interval_overlaps397 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