llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
hash.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <cstdint>
8 #include <utility>
9 #include <tuple>
10 #include <functional>
11 
12 
13 
17 template <class T>
18 inline void hash_combine(std::size_t& seed, const T& v)
19 {
20  std::hash<T> hasher;
21  seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
22 }
23 
24 
25 
29 template<typename T1, typename T2>
30 struct std::hash<std::pair<T1, T2>> {
31  std::size_t operator()(const std::pair<T1, T2> &p) const
32  {
33  std::size_t hash = 0;
34  hash_combine(hash, std::hash<T1>{}(p.first));
35  hash_combine(hash, std::hash<T2>{}(p.second));
36  return hash;
37  }
38 };
39 
43 template<typename T>
44 struct std::hash<std::vector<T>> {
45  std::size_t operator()(const std::vector<T> &v) const
46  {
47  std::size_t hash = 0;
48  for (const auto &elem : v) {
49  hash_combine(hash, std::hash<T>{}(elem));
50  }
51  return hash;
52  }
53 };
54 
58 template<typename... Ts>
59 class std::hash<std::tuple<Ts...>> {
60 private:
61  template <size_t I, size_t N>
62  static std::size_t Hash(const std::tuple<Ts...> &t)
63  {
64  if constexpr (I < N) {
65  auto Elem = std::get<I>(t);
66  std::size_t hash(0);
67  hash_combine(hash, std::hash<decltype(Elem)>()(Elem));
68  hash_combine(hash, Hash<I + 1, N>(t));
69  return hash;
70  } else {
71  return std::size_t(0);
72  }
73  }
74 
75 public:
76  std::size_t operator()(const std::tuple<Ts...> &t) const
77  {
78  return Hash<0, std::tuple_size<std::tuple<Ts...>>::value>(t);
79  }
80 };