19 #ifndef _VATA2_UTIL_HH_
20 #define _VATA2_UTIL_HH_
30 #include <unordered_map>
33 #define DEBUG_PRINT(x) { std::cerr << "debug: " << x << "\n"; }
34 #define DEBUG_PRINT_LN(x) { DEBUG_PRINT(__func__ << ":" << __LINE__ << ": " << x) }
35 #define WARN_PRINT(x) { std::cerr << "warning: " << x << "\n"; }
46 auto itLhs = lhs.begin();
47 auto itRhs = rhs.begin();
48 while (itLhs != lhs.end() && itRhs != rhs.end())
50 if (*itLhs == *itRhs) {
return false; }
51 else if (*itLhs < *itRhs) { ++itLhs; }
69 size_t rhs_hash = std::hash<T>{}(rhs);
70 lhs ^= rhs_hash + 0x9e3779b9 + (lhs<<6) + (lhs>>2);
81 template <
typename It>
86 for (; first != last; ++first)
95 template <
class T,
class K>
96 inline bool haskey(
const T& cont,
const K& key)
98 return cont.find(key) != cont.cend();
102 template <
template <
class,
class,
class...>
class Map,
class T1,
class T2,
class... Args>
107 for (
const auto& key_val_pair : mp)
109 auto it_ins_pair = result.insert({key_val_pair.second, key_val_pair.first});
110 if (!it_ins_pair.second)
112 throw std::runtime_error(
"duplicate key when inverting a map");
120 template<
class Tuple, std::
size_t N>
135 template <
class A,
class B>
136 struct hash<std::pair<A,B>>
140 size_t accum = std::hash<A>{}(k.first);
149 struct hash<std::set<A>>
161 struct hash<std::vector<A>>
177 template <
class A> std::string to_string(
const A& value);
178 template <
class A> std::string to_string(
const std::set<A>& st);
179 template <
class A> std::string to_string(
const std::vector<A>& vec);
180 template <
class A> std::string to_string(
const std::list<A>& vec);
181 template <
class A> std::string to_string(
const std::stack<A>& stck);
182 template <
class A> std::string to_string(
const std::function<A>& func);
183 template <
class A,
class B> std::string to_string(
const std::pair<A, B>& p);
184 template <
class A,
class B> std::string to_string(
const std::unordered_map<A, B>& unmap);
185 template <
class A,
class B> std::string to_string(
const std::map<A, B>& mp);
194 inline std::string to_string(
char ch)
202 inline std::string to_string(
const std::string& str) {
return str; }
206 std::string to_string(
const std::vector<A>& vec)
208 std::string result =
"[";
210 for (
auto elem : vec)
212 if (!first) { result +=
", "; }
214 result += std::to_string(elem);
223 std::string to_string(
const std::list<A>& vec)
225 std::string result =
"[";
227 for (
auto elem : vec)
229 if (!first) { result +=
", "; }
231 result += std::to_string(elem);
239 template <
class A,
class B>
240 std::string to_string(
const std::unordered_map<A, B>& unmap)
242 std::string result =
"{";
244 for (
auto key_val_pair : unmap)
246 if (!first) { result +=
", "; }
249 std::to_string(key_val_pair.first) +
251 std::to_string(key_val_pair.second);
259 template <
class A,
class B>
260 std::string to_string(
const std::map<A, B>& mp)
262 std::string result =
"{";
264 for (
auto key_val_pair : mp)
266 if (!first) { result +=
", "; }
269 std::to_string(key_val_pair.first) +
271 std::to_string(key_val_pair.second);
280 std::string to_string(
const std::set<A>& st)
282 std::string result =
"{";
286 if (!first) { result +=
", "; }
288 result += std::to_string(elem);
297 std::string to_string(
const std::stack<A>& stck)
299 std::stack<A> copy = stck;
301 while (!copy.empty()) {
302 vec.push_back(copy.top());
305 std::reverse(vec.begin(), vec.end());
306 return std::to_string(vec);
311 std::string to_string(
const std::function<A>& fun)
313 return std::to_string(static_cast<const void*>(&fun));
317 template <
class... Ts>
318 std::string to_string(
const std::tuple<Ts...>& tup)
320 std::string str =
"<";
327 template <
class A,
class B>
328 std::string to_string(
const std::pair<A, B>& p)
330 return std::to_string(std::tuple<A, B>(p.first, p.second));
335 std::string to_string(
const A& value)
337 std::ostringstream os;
353 template<
class Tuple,
size_t N>
356 static std::string
print(
const Tuple& t)
359 return res +
", " + std::to_string(std::get<N-1>(t));
363 template<
class Tuple>
365 static std::string
print(
const Tuple& t)
367 return std::to_string(std::get<0>(t));
bool haskey(const T &cont, const K &key)
checks whether a container with find contains a key
bool are_disjoint(const std::set< T > &lhs, const std::set< T > &rhs)
Are two sets disjoint?
size_t hash_combine(size_t lhs, const T &rhs)
Combine two hash values.
Map< T2, T1 > invert_map(const Map< T1, T2 > &mp)
inverts a map (should work for std::map and std::unordered_map)
static std::string print(const Tuple &t)
size_t operator()(const std::pair< A, B > &k) const
size_t hash_range(It first, It last)
Hashes a range.
size_t operator()(const std::set< A > &cont) const
size_t operator()(const std::vector< A > &cont) const
static std::string print(const Tuple &t)