// // Copyright 2013 Francisco Jerez // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // #ifndef CLOVER_UTIL_FUNCTIONAL_HPP #define CLOVER_UTIL_FUNCTIONAL_HPP #include namespace clover { struct identity { template typename std::remove_reference::type operator()(T &&x) const { return x; } }; struct plus { template typename std::common_type::type operator()(T x, S y) const { return x + y; } }; struct minus { template typename std::common_type::type operator()(T x, S y) const { return x - y; } }; struct negate { template T operator()(T x) const { return -x; } }; struct multiplies { template typename std::common_type::type operator()(T x, S y) const { return x * y; } }; struct divides { template typename std::common_type::type operator()(T x, S y) const { return x / y; } }; struct modulus { template typename std::common_type::type operator()(T x, S y) const { return x % y; } }; struct minimum { template T operator()(T x) const { return x; } template T operator()(T x, Ts... xs) const { T y = minimum()(xs...); return x < y ? x : y; } }; struct maximum { template T operator()(T x) const { return x; } template T operator()(T x, Ts... xs) const { T y = maximum()(xs...); return x < y ? y : x; } }; struct preincs { template T & operator()(T &x) const { return ++x; } }; struct predecs { template T & operator()(T &x) const { return --x; } }; template class multiplies_by_t { public: multiplies_by_t(T x) : x(x) { } template typename std::common_type::type operator()(S y) const { return x * y; } private: T x; }; template multiplies_by_t multiplies_by(T x) { return { x }; } template class preincs_by_t { public: preincs_by_t(T n) : n(n) { } template S & operator()(S &x) const { return x += n; } private: T n; }; template preincs_by_t preincs_by(T n) { return { n }; } template class predecs_by_t { public: predecs_by_t(T n) : n(n) { } template S & operator()(S &x) const { return x -= n; } private: T n; }; template predecs_by_t predecs_by(T n) { return { n }; } struct greater { template bool operator()(T x, S y) const { return x > y; } }; struct evals { template auto operator()(T &&x) const -> decltype(x()) { return x(); } }; struct derefs { template auto operator()(T &&x) const -> decltype(*x) { return *x; } }; struct addresses { template T * operator()(T &x) const { return &x; } template T * operator()(std::reference_wrapper x) const { return &x.get(); } }; struct begins { template auto operator()(T &x) const -> decltype(x.begin()) { return x.begin(); } }; struct ends { template auto operator()(T &x) const -> decltype(x.end()) { return x.end(); } }; struct sizes { template auto operator()(T &x) const -> decltype(x.size()) { return x.size(); } }; template class advances_by_t { public: advances_by_t(T n) : n(n) { } template S operator()(S &&it) const { std::advance(it, n); return it; } private: T n; }; template advances_by_t advances_by(T n) { return { n }; } struct zips { template std::tuple operator()(Ts &&... xs) const { return std::tuple(std::forward(xs)...); } }; struct is_zero { template bool operator()(const T &x) const { return x == 0; } }; struct keys { template auto operator()(P &&p) const -> decltype(std::get<0>(std::forward

(p))) { return std::get<0>(std::forward

(p)); } }; struct values { template auto operator()(P &&p) const -> decltype(std::get<1>(std::forward

(p))) { return std::get<1>(std::forward

(p)); } }; class name_equals { public: name_equals(const std::string &name) : name(name) { } template bool operator()(const T &x) const { return std::string(x.name.begin(), x.name.end()) == name; } private: const std::string &name; }; template class key_equals_t { public: key_equals_t(T &&x) : x(x) { } template bool operator()(const std::pair &p) const { return p.first == x; } private: T x; }; template key_equals_t key_equals(T &&x) { return { std::forward(x) }; } template class type_equals_t { public: type_equals_t(T type) : type(type) { } template bool operator()(const S &x) const { return x.type == type; } private: T type; }; template type_equals_t type_equals(T x) { return { x }; } struct interval_overlaps { template bool operator()(T x0, T x1, T y0, T y1) { return ((x0 <= y0 && y0 < x1) || (y0 <= x0 && x0 < y1)); } }; } #endif