1bf215546Sopenharmony_ci// 2bf215546Sopenharmony_ci// Copyright 2013 Francisco Jerez 3bf215546Sopenharmony_ci// 4bf215546Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci// copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci// to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci// the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci// and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci// Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci// 11bf215546Sopenharmony_ci// The above copyright notice and this permission notice shall be included in 12bf215546Sopenharmony_ci// all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci// 14bf215546Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bf215546Sopenharmony_ci// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bf215546Sopenharmony_ci// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bf215546Sopenharmony_ci// OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci// 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#ifndef CLOVER_UTIL_FUNCTIONAL_HPP 24bf215546Sopenharmony_ci#define CLOVER_UTIL_FUNCTIONAL_HPP 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <type_traits> 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_cinamespace clover { 29bf215546Sopenharmony_ci struct identity { 30bf215546Sopenharmony_ci template<typename T> 31bf215546Sopenharmony_ci typename std::remove_reference<T>::type 32bf215546Sopenharmony_ci operator()(T &&x) const { 33bf215546Sopenharmony_ci return x; 34bf215546Sopenharmony_ci } 35bf215546Sopenharmony_ci }; 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci struct plus { 38bf215546Sopenharmony_ci template<typename T, typename S> 39bf215546Sopenharmony_ci typename std::common_type<T, S>::type 40bf215546Sopenharmony_ci operator()(T x, S y) const { 41bf215546Sopenharmony_ci return x + y; 42bf215546Sopenharmony_ci } 43bf215546Sopenharmony_ci }; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci struct minus { 46bf215546Sopenharmony_ci template<typename T, typename S> 47bf215546Sopenharmony_ci typename std::common_type<T, S>::type 48bf215546Sopenharmony_ci operator()(T x, S y) const { 49bf215546Sopenharmony_ci return x - y; 50bf215546Sopenharmony_ci } 51bf215546Sopenharmony_ci }; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci struct negate { 54bf215546Sopenharmony_ci template<typename T> 55bf215546Sopenharmony_ci T 56bf215546Sopenharmony_ci operator()(T x) const { 57bf215546Sopenharmony_ci return -x; 58bf215546Sopenharmony_ci } 59bf215546Sopenharmony_ci }; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci struct multiplies { 62bf215546Sopenharmony_ci template<typename T, typename S> 63bf215546Sopenharmony_ci typename std::common_type<T, S>::type 64bf215546Sopenharmony_ci operator()(T x, S y) const { 65bf215546Sopenharmony_ci return x * y; 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci }; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci struct divides { 70bf215546Sopenharmony_ci template<typename T, typename S> 71bf215546Sopenharmony_ci typename std::common_type<T, S>::type 72bf215546Sopenharmony_ci operator()(T x, S y) const { 73bf215546Sopenharmony_ci return x / y; 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci }; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci struct modulus { 78bf215546Sopenharmony_ci template<typename T, typename S> 79bf215546Sopenharmony_ci typename std::common_type<T, S>::type 80bf215546Sopenharmony_ci operator()(T x, S y) const { 81bf215546Sopenharmony_ci return x % y; 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci }; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci struct minimum { 86bf215546Sopenharmony_ci template<typename T> 87bf215546Sopenharmony_ci T 88bf215546Sopenharmony_ci operator()(T x) const { 89bf215546Sopenharmony_ci return x; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci template<typename T, typename... Ts> 93bf215546Sopenharmony_ci T 94bf215546Sopenharmony_ci operator()(T x, Ts... xs) const { 95bf215546Sopenharmony_ci T y = minimum()(xs...); 96bf215546Sopenharmony_ci return x < y ? x : y; 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci }; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci struct maximum { 101bf215546Sopenharmony_ci template<typename T> 102bf215546Sopenharmony_ci T 103bf215546Sopenharmony_ci operator()(T x) const { 104bf215546Sopenharmony_ci return x; 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci template<typename T, typename... Ts> 108bf215546Sopenharmony_ci T 109bf215546Sopenharmony_ci operator()(T x, Ts... xs) const { 110bf215546Sopenharmony_ci T y = maximum()(xs...); 111bf215546Sopenharmony_ci return x < y ? y : x; 112bf215546Sopenharmony_ci } 113bf215546Sopenharmony_ci }; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci struct preincs { 116bf215546Sopenharmony_ci template<typename T> 117bf215546Sopenharmony_ci T & 118bf215546Sopenharmony_ci operator()(T &x) const { 119bf215546Sopenharmony_ci return ++x; 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci }; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci struct predecs { 124bf215546Sopenharmony_ci template<typename T> 125bf215546Sopenharmony_ci T & 126bf215546Sopenharmony_ci operator()(T &x) const { 127bf215546Sopenharmony_ci return --x; 128bf215546Sopenharmony_ci } 129bf215546Sopenharmony_ci }; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci template<typename T> 132bf215546Sopenharmony_ci class multiplies_by_t { 133bf215546Sopenharmony_ci public: 134bf215546Sopenharmony_ci multiplies_by_t(T x) : x(x) { 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci template<typename S> 138bf215546Sopenharmony_ci typename std::common_type<T, S>::type 139bf215546Sopenharmony_ci operator()(S y) const { 140bf215546Sopenharmony_ci return x * y; 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci private: 144bf215546Sopenharmony_ci T x; 145bf215546Sopenharmony_ci }; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci template<typename T> 148bf215546Sopenharmony_ci multiplies_by_t<T> 149bf215546Sopenharmony_ci multiplies_by(T x) { 150bf215546Sopenharmony_ci return { x }; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci template<typename T> 154bf215546Sopenharmony_ci class preincs_by_t { 155bf215546Sopenharmony_ci public: 156bf215546Sopenharmony_ci preincs_by_t(T n) : n(n) { 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci template<typename S> 160bf215546Sopenharmony_ci S & 161bf215546Sopenharmony_ci operator()(S &x) const { 162bf215546Sopenharmony_ci return x += n; 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci private: 166bf215546Sopenharmony_ci T n; 167bf215546Sopenharmony_ci }; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci template<typename T> 170bf215546Sopenharmony_ci preincs_by_t<T> 171bf215546Sopenharmony_ci preincs_by(T n) { 172bf215546Sopenharmony_ci return { n }; 173bf215546Sopenharmony_ci } 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci template<typename T> 176bf215546Sopenharmony_ci class predecs_by_t { 177bf215546Sopenharmony_ci public: 178bf215546Sopenharmony_ci predecs_by_t(T n) : n(n) { 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci template<typename S> 182bf215546Sopenharmony_ci S & 183bf215546Sopenharmony_ci operator()(S &x) const { 184bf215546Sopenharmony_ci return x -= n; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci private: 188bf215546Sopenharmony_ci T n; 189bf215546Sopenharmony_ci }; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci template<typename T> 192bf215546Sopenharmony_ci predecs_by_t<T> 193bf215546Sopenharmony_ci predecs_by(T n) { 194bf215546Sopenharmony_ci return { n }; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci struct greater { 198bf215546Sopenharmony_ci template<typename T, typename S> 199bf215546Sopenharmony_ci bool 200bf215546Sopenharmony_ci operator()(T x, S y) const { 201bf215546Sopenharmony_ci return x > y; 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci }; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci struct evals { 206bf215546Sopenharmony_ci template<typename T> 207bf215546Sopenharmony_ci auto 208bf215546Sopenharmony_ci operator()(T &&x) const -> decltype(x()) { 209bf215546Sopenharmony_ci return x(); 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci }; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci struct derefs { 214bf215546Sopenharmony_ci template<typename T> 215bf215546Sopenharmony_ci auto 216bf215546Sopenharmony_ci operator()(T &&x) const -> decltype(*x) { 217bf215546Sopenharmony_ci return *x; 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci }; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci struct addresses { 222bf215546Sopenharmony_ci template<typename T> 223bf215546Sopenharmony_ci T * 224bf215546Sopenharmony_ci operator()(T &x) const { 225bf215546Sopenharmony_ci return &x; 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci template<typename T> 229bf215546Sopenharmony_ci T * 230bf215546Sopenharmony_ci operator()(std::reference_wrapper<T> x) const { 231bf215546Sopenharmony_ci return &x.get(); 232bf215546Sopenharmony_ci } 233bf215546Sopenharmony_ci }; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci struct begins { 236bf215546Sopenharmony_ci template<typename T> 237bf215546Sopenharmony_ci auto 238bf215546Sopenharmony_ci operator()(T &x) const -> decltype(x.begin()) { 239bf215546Sopenharmony_ci return x.begin(); 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci }; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci struct ends { 244bf215546Sopenharmony_ci template<typename T> 245bf215546Sopenharmony_ci auto 246bf215546Sopenharmony_ci operator()(T &x) const -> decltype(x.end()) { 247bf215546Sopenharmony_ci return x.end(); 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci }; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci struct sizes { 252bf215546Sopenharmony_ci template<typename T> 253bf215546Sopenharmony_ci auto 254bf215546Sopenharmony_ci operator()(T &x) const -> decltype(x.size()) { 255bf215546Sopenharmony_ci return x.size(); 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci }; 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci template<typename T> 260bf215546Sopenharmony_ci class advances_by_t { 261bf215546Sopenharmony_ci public: 262bf215546Sopenharmony_ci advances_by_t(T n) : n(n) { 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci template<typename S> 266bf215546Sopenharmony_ci S 267bf215546Sopenharmony_ci operator()(S &&it) const { 268bf215546Sopenharmony_ci std::advance(it, n); 269bf215546Sopenharmony_ci return std::forward<S>(it); 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci private: 273bf215546Sopenharmony_ci T n; 274bf215546Sopenharmony_ci }; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci template<typename T> 277bf215546Sopenharmony_ci advances_by_t<T> 278bf215546Sopenharmony_ci advances_by(T n) { 279bf215546Sopenharmony_ci return { n }; 280bf215546Sopenharmony_ci } 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci struct zips { 283bf215546Sopenharmony_ci template<typename... Ts> 284bf215546Sopenharmony_ci std::tuple<Ts...> 285bf215546Sopenharmony_ci operator()(Ts &&... xs) const { 286bf215546Sopenharmony_ci return std::tuple<Ts...>(std::forward<Ts>(xs)...); 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci }; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci struct is_zero { 291bf215546Sopenharmony_ci template<typename T> 292bf215546Sopenharmony_ci bool 293bf215546Sopenharmony_ci operator()(const T &x) const { 294bf215546Sopenharmony_ci return x == 0; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci }; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci struct keys { 299bf215546Sopenharmony_ci template<typename P> 300bf215546Sopenharmony_ci auto 301bf215546Sopenharmony_ci operator()(P &&p) const -> decltype(std::get<0>(std::forward<P>(p))) { 302bf215546Sopenharmony_ci return std::get<0>(std::forward<P>(p)); 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci }; 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci struct values { 307bf215546Sopenharmony_ci template<typename P> 308bf215546Sopenharmony_ci auto 309bf215546Sopenharmony_ci operator()(P &&p) const -> decltype(std::get<1>(std::forward<P>(p))) { 310bf215546Sopenharmony_ci return std::get<1>(std::forward<P>(p)); 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci }; 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci template<typename T> 315bf215546Sopenharmony_ci class equals_t { 316bf215546Sopenharmony_ci public: 317bf215546Sopenharmony_ci equals_t(T &&x) : x(x) {} 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci template<typename S> 320bf215546Sopenharmony_ci bool 321bf215546Sopenharmony_ci operator()(S &&y) const { 322bf215546Sopenharmony_ci return x == y; 323bf215546Sopenharmony_ci } 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci private: 326bf215546Sopenharmony_ci T x; 327bf215546Sopenharmony_ci }; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci template<typename T> 330bf215546Sopenharmony_ci equals_t<T> 331bf215546Sopenharmony_ci equals(T &&x) { 332bf215546Sopenharmony_ci return { std::forward<T>(x) }; 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci class name_equals { 336bf215546Sopenharmony_ci public: 337bf215546Sopenharmony_ci name_equals(const std::string &name) : name(name) { 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci template<typename T> 341bf215546Sopenharmony_ci bool 342bf215546Sopenharmony_ci operator()(const T &x) const { 343bf215546Sopenharmony_ci return std::string(x.name.begin(), x.name.end()) == name; 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci private: 347bf215546Sopenharmony_ci const std::string &name; 348bf215546Sopenharmony_ci }; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci template<typename T> 351bf215546Sopenharmony_ci class key_equals_t { 352bf215546Sopenharmony_ci public: 353bf215546Sopenharmony_ci key_equals_t(T &&x) : x(x) { 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci template<typename P> 357bf215546Sopenharmony_ci bool 358bf215546Sopenharmony_ci operator()(const P &p) const { 359bf215546Sopenharmony_ci return p.first == x; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci private: 363bf215546Sopenharmony_ci T x; 364bf215546Sopenharmony_ci }; 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci template<typename T> 367bf215546Sopenharmony_ci key_equals_t<T> 368bf215546Sopenharmony_ci key_equals(T &&x) { 369bf215546Sopenharmony_ci return { std::forward<T>(x) }; 370bf215546Sopenharmony_ci } 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci template<typename T> 373bf215546Sopenharmony_ci class type_equals_t { 374bf215546Sopenharmony_ci public: 375bf215546Sopenharmony_ci type_equals_t(T type) : type(type) { 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci template<typename S> 379bf215546Sopenharmony_ci bool 380bf215546Sopenharmony_ci operator()(const S &x) const { 381bf215546Sopenharmony_ci return x.type == type; 382bf215546Sopenharmony_ci } 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci private: 385bf215546Sopenharmony_ci T type; 386bf215546Sopenharmony_ci }; 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci template<typename T> 389bf215546Sopenharmony_ci type_equals_t<T> 390bf215546Sopenharmony_ci type_equals(T x) { 391bf215546Sopenharmony_ci return { x }; 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci template<typename T> 395bf215546Sopenharmony_ci class id_type_equals_t { 396bf215546Sopenharmony_ci public: 397bf215546Sopenharmony_ci id_type_equals_t(const uint32_t id, T t) : 398bf215546Sopenharmony_ci id(id), type(t) { 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci template<typename X> 402bf215546Sopenharmony_ci bool 403bf215546Sopenharmony_ci operator()(const X &x) const { 404bf215546Sopenharmony_ci return id == x.id && type(x); 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci private: 408bf215546Sopenharmony_ci const uint32_t id; 409bf215546Sopenharmony_ci type_equals_t<T> type; 410bf215546Sopenharmony_ci }; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci template<typename T> 413bf215546Sopenharmony_ci id_type_equals_t<T> 414bf215546Sopenharmony_ci id_type_equals(const uint32_t id, T x) { 415bf215546Sopenharmony_ci return { id, x }; 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci struct interval_overlaps { 419bf215546Sopenharmony_ci template<typename T> 420bf215546Sopenharmony_ci bool 421bf215546Sopenharmony_ci operator()(T x0, T x1, T y0, T y1) { 422bf215546Sopenharmony_ci return ((x0 <= y0 && y0 < x1) || 423bf215546Sopenharmony_ci (y0 <= x0 && x0 < y1)); 424bf215546Sopenharmony_ci } 425bf215546Sopenharmony_ci }; 426bf215546Sopenharmony_ci} 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci#endif 429