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__