kranewm

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in C++
git clone git://git.deurzen.net/kranewm
Log | Files | Refs | LICENSE

util.hh (3713B)


      1 #ifndef __WINSYS_UTIL_H_GUARD__
      2 #define __WINSYS_UTIL_H_GUARD__
      3 
      4 #include <cstdlib>
      5 #include <iostream>
      6 #include <optional>
      7 #include <string>
      8 #include <type_traits>
      9 #include <unordered_map>
     10 #include <vector>
     11 
     12 namespace Util
     13 {
     14 
     15     void die(const std::string&&);
     16     void warn(const std::string&&);
     17     void assert(bool, const std::string&&);
     18 
     19     template <
     20         typename T,
     21         typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
     22     >
     23     struct Change final
     24     {
     25         Change(T value)
     26             : value(value)
     27         {}
     28 
     29         operator T() const { return value; }
     30 
     31         T value;
     32     };
     33 
     34     template<typename T>
     35     struct is_iterable final
     36     {
     37     private:
     38         template<typename Container> static char test(typename Container::iterator*);
     39         template<typename Container> static int  test(...);
     40     public:
     41         enum { value = sizeof(test<T>(0)) == sizeof(char) };
     42     };
     43 
     44     template <typename Container>
     45     typename std::enable_if<is_iterable<Container>::value, void>::type
     46     erase_remove(Container& c, typename Container::value_type const& t)
     47     {
     48         auto iter = std::remove(c.begin(), c.end(), t);
     49 
     50         if (iter == c.end())
     51             return;
     52 
     53         c.erase(iter, c.end());
     54     }
     55 
     56     template <typename Container, typename UnaryPredicate>
     57     typename std::enable_if<is_iterable<Container>::value, void>::type
     58     erase_remove_if(Container& c, UnaryPredicate p)
     59     {
     60         auto iter = std::remove_if(c.begin(), c.end(), p);
     61 
     62         if (iter == c.end())
     63             return;
     64 
     65         c.erase(iter, c.end());
     66     }
     67 
     68     template <typename Container>
     69     typename std::enable_if<is_iterable<Container>::value, void>::type
     70     erase_at_index(Container& c, const std::size_t index)
     71     {
     72         if (index < c.size())
     73             c.erase(c.begin() + index);
     74     }
     75 
     76     template <typename Container>
     77     typename std::enable_if<is_iterable<Container>::value, void>::type
     78     append(Container& c1, Container const& c2)
     79     {
     80         c1.reserve(c1.size() + c2.size());
     81         c1.insert(c1.end(), c2.begin(), c2.end());
     82     }
     83 
     84     template <typename Container>
     85     typename std::enable_if<is_iterable<Container>::value, const bool>::type
     86     contains(Container const& c, typename Container::value_type const& t)
     87     {
     88         return std::find(c.begin(), c.end(), t) != c.end();
     89     }
     90 
     91     template <typename K, typename V>
     92     std::optional<V>
     93     retrieve(std::unordered_map<K, V>& c, K& key)
     94     {
     95         typename std::unordered_map<K, V>::iterator iter = c.find(key);
     96 
     97         if (iter == c.end())
     98             return std::nullopt;
     99 
    100         return iter->second;
    101     }
    102 
    103     template <typename K, typename V>
    104     V&
    105     at(std::unordered_map<K, V>& c, K& key)
    106     {
    107         return c.at(key);
    108     }
    109 
    110     template <typename K, typename V>
    111     std::optional<const V>
    112     const_retrieve(std::unordered_map<K, V> const& c, K const& key)
    113     {
    114         typename std::unordered_map<K, V>::const_iterator iter = c.find(key);
    115 
    116         if (iter == c.end())
    117             return std::nullopt;
    118 
    119         return iter->second;
    120     }
    121 
    122     template <typename Container>
    123     typename std::enable_if<is_iterable<Container>::value, const std::optional<const std::size_t>>::type
    124     index_of(Container const& c, typename Container::value_type const& t)
    125     {
    126         auto iter = std::find(c.begin(), c.end(), t);
    127         if (iter != c.end())
    128             return iter - c.begin();
    129 
    130         return std::nullopt;
    131     }
    132 
    133     template <typename Container>
    134     typename std::enable_if<is_iterable<Container>::value, const std::size_t>::type
    135     last_index(Container const& c)
    136     {
    137         return c.empty() ? 0 : c.size() - 1;
    138     }
    139 
    140 }
    141 
    142 #endif//__WINSYS_UTIL_H_GUARD__