Home | History | Annotate | Download | only in util
      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    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