Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.    class name_equals {
  315.    public:
  316.       name_equals(const std::string &name) : name(name) {
  317.       }
  318.  
  319.       template<typename T>
  320.       bool
  321.       operator()(const T &x) const {
  322.          return std::string(x.name.begin(), x.name.end()) == name;
  323.       }
  324.  
  325.    private:
  326.       const std::string &name;
  327.    };
  328.  
  329.    template<typename T>
  330.    class key_equals_t {
  331.    public:
  332.       key_equals_t(T &&x) : x(x) {
  333.       }
  334.  
  335.       template<typename P>
  336.       bool
  337.       operator()(const P &p) const {
  338.          return p.first == x;
  339.       }
  340.  
  341.    private:
  342.       T x;
  343.    };
  344.  
  345.    template<typename T>
  346.    key_equals_t<T>
  347.    key_equals(T &&x) {
  348.       return { std::forward<T>(x) };
  349.    }
  350.  
  351.    template<typename T>
  352.    class type_equals_t {
  353.    public:
  354.       type_equals_t(T type) : type(type) {
  355.       }
  356.  
  357.       template<typename S>
  358.       bool
  359.       operator()(const S &x) const {
  360.          return x.type == type;
  361.       }
  362.  
  363.    private:
  364.       T type;
  365.    };
  366.  
  367.    template<typename T>
  368.    type_equals_t<T>
  369.    type_equals(T x) {
  370.       return { x };
  371.    }
  372.  
  373.    struct interval_overlaps {
  374.       template<typename T>
  375.       bool
  376.       operator()(T x0, T x1, T y0, T y1) {
  377.          return ((x0 <= y0 && y0 < x1) ||
  378.                  (y0 <= x0 && x0 < y1));
  379.       }
  380.    };
  381. }
  382.  
  383. #endif
  384.