2 // Copyright 2013 Francisco Jerez
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:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
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.
23 #ifndef CLOVER_UTIL_FUNCTIONAL_HPP
24 #define CLOVER_UTIL_FUNCTIONAL_HPP
26 #include <type_traits>
31 typename std::remove_reference<T>::type
32 operator()(T &&x) const {
38 template<typename T, typename S>
39 typename std::common_type<T, S>::type
40 operator()(T x, S y) const {
46 template<typename T, typename S>
47 typename std::common_type<T, S>::type
48 operator()(T x, S y) const {
56 operator()(T x) const {
62 template<typename T, typename S>
63 typename std::common_type<T, S>::type
64 operator()(T x, S y) const {
70 template<typename T, typename S>
71 typename std::common_type<T, S>::type
72 operator()(T x, S y) const {
78 template<typename T, typename S>
79 typename std::common_type<T, S>::type
80 operator()(T x, S y) const {
88 operator()(T x) const {
92 template<typename T, typename... Ts>
94 operator()(T x, Ts... xs) const {
95 T y = minimum()(xs...);
103 operator()(T x) const {
107 template<typename T, typename... Ts>
109 operator()(T x, Ts... xs) const {
110 T y = maximum()(xs...);
111 return x < y ? y : x;
118 operator()(T &x) const {
126 operator()(T &x) const {
132 class multiplies_by_t {
134 multiplies_by_t(T x) : x(x) {
138 typename std::common_type<T, S>::type
139 operator()(S y) const {
156 preincs_by_t(T n) : n(n) {
161 operator()(S &x) const {
178 predecs_by_t(T n) : n(n) {
183 operator()(S &x) const {
198 template<typename T, typename S>
200 operator()(T x, S y) const {
208 operator()(T &&x) const -> decltype(x()) {
216 operator()(T &&x) const -> decltype(*x) {
224 operator()(T &x) const {
230 operator()(std::reference_wrapper<T> x) const {
238 operator()(T &x) const -> decltype(x.begin()) {
246 operator()(T &x) const -> decltype(x.end()) {
254 operator()(T &x) const -> decltype(x.size()) {
260 class advances_by_t {
262 advances_by_t(T n) : n(n) {
267 operator()(S &&it) const {
283 template<typename... Ts>
285 operator()(Ts &&... xs) const {
286 return std::tuple<Ts...>(std::forward<Ts>(xs)...);
293 operator()(const T &x) const {
301 operator()(P &&p) const -> decltype(std::get<0>(std::forward<P>(p))) {
302 return std::get<0>(std::forward<P>(p));
309 operator()(P &&p) const -> decltype(std::get<1>(std::forward<P>(p))) {
310 return std::get<1>(std::forward<P>(p));
317 equals_t(T &&x) : x(x) {}
321 operator()(S &&y) const {
332 return { std::forward<T>(x) };
337 name_equals(const std::string &name) : name(name) {
342 operator()(const T &x) const {
343 return std::string(x.name.begin(), x.name.end()) == name;
347 const std::string &name;
352 id_equals(const uint32_t id) : id(id) {
357 operator()(const T &x) const {
368 key_equals_t(T &&x) : x(x) {
373 operator()(const P &p) const {
384 return { std::forward<T>(x) };
388 class type_equals_t {
390 type_equals_t(T type) : type(type) {
395 operator()(const S &x) const {
396 return x.type == type;
409 struct interval_overlaps {
412 operator()(T x0, T x1, T y0, T y1) {
413 return ((x0 <= y0 && y0 < x1) ||
414 (y0 <= x0 && x0 < y1));