CGRA-ME
TupleHash.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * The software programs comprising "CGRA-ME" and the documentation provided
3  * with them are copyright by its authors and the University of Toronto. Only
4  * non-commercial, not-for-profit use of this software is permitted without ex-
5  * plicit permission. This software is provided "as is" with no warranties or
6  * guarantees of support. See the LICENCE for more details. You should have re-
7  * ceived a copy of the full licence along with this software. If not, see
8  * <http://cgra-me.ece.utoronto.ca/license/>.
9  ******************************************************************************/
10 
11 #ifndef __TUPLE_HASH_H__
12 #define __TUPLE_HASH_H__
13 
20 #include <tuple>
21 namespace tuple_hash {
22  namespace {
23  template<class T>
24  [[nodiscard]]
25  std::size_t hash_combine(std::size_t seed, const T& v) {
26  return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2));
27  }
28 
29  template<std::size_t INDEX>
30  struct hashvalueimpl {
31  template<typename TUPLE>
32  [[nodiscard]]
33  static size_t apply(std::size_t seed, const TUPLE& tuple) {
34  return hash_combine(
35  hashvalueimpl<INDEX-1>::apply(seed, tuple),
36  std::get<INDEX>(tuple)
37  );
38  }
39  };
40 
41  template<>
42  struct hashvalueimpl<0> {
43  template<typename TUPLE>
44  [[nodiscard]]
45  static size_t apply(std::size_t seed, const TUPLE& tuple) {
46  return hash_combine(seed, std::get<0>(tuple));
47  }
48  };
49  }
50 
51  template<typename...>
52  struct hash;
53 
54  template<typename... TT>
55  struct hash<std::tuple<TT...>> {
56  template<typename TUPLE>
57  std::size_t operator()(const TUPLE& tuple) const {
58  std::size_t seed = 0;
59  return hashvalueimpl<std::tuple_size<TUPLE>::value - 1>::apply(seed, tuple);
60  }
61  };
62 
63  template<typename T>
64  std::size_t hashValue(const T& t) {
65  return hash<T>{}(t);
66  }
67 
85  template<typename Derived>
86  struct TupleHashOps {
87  const Derived& asDerived() const { return *static_cast<const Derived*>(this); }
88  Derived& asDerived() { return *static_cast< Derived*>(this); }
89 
90  bool operator==(const Derived& rhs) const { return asDerived().asTuple() == rhs.asTuple(); }
91  bool operator<(const Derived& rhs) const { return asDerived().asTuple() < rhs.asTuple(); }
92 
93  struct Hash { std::size_t operator()(const Derived& d) const {
94  return hashValue(d.asTuple());
95  }};
96  };
97 }
98 
104 template<typename... CArgs>
105 struct ImplicitTuple : std::tuple<CArgs...> {
106  using Base = std::tuple<CArgs...>;
107 
108  template<typename Arg>
109  explicit ImplicitTuple(Arg&& arg) : Base(std::forward<Arg>(arg)) { }
110 
111  ImplicitTuple(Base arg) : Base(std::move(arg)) { }
112 
113  template<typename Arg1, typename... Args>
114  ImplicitTuple(Arg1&& arg1, Args&&... args) : Base(std::forward<Arg1>(arg1), std::forward<Args>(args)...) { }
115 
116  using Base::tuple;
117  using Base::operator=;
118 };
119 
120 #endif /* __TUPLE_HASH_H__ */
ImplicitTuple
Definition: TupleHash.h:105
tuple_hash::hash
Definition: TupleHash.h:60
tuple_hash::TupleHashOps::operator==
bool operator==(const Derived &rhs) const
Definition: TupleHash.h:98
tuple_hash
Definition: TupleHash.h:21
tuple_hash::hashValue
std::size_t hashValue(const T &t)
Definition: TupleHash.h:72
tuple_hash::TupleHashOps::Hash::operator()
std::size_t operator()(const Derived &d) const
Definition: TupleHash.h:101
ImplicitTuple::ImplicitTuple
ImplicitTuple(Base arg)
Definition: TupleHash.h:111
ImplicitTuple::ImplicitTuple
ImplicitTuple(Arg1 &&arg1, Args &&... args)
Definition: TupleHash.h:114
tuple_hash::TupleHashOps::asDerived
const Derived & asDerived() const
Definition: TupleHash.h:95
ImplicitTuple::Base
std::tuple< CArgs... > Base
Definition: TupleHash.h:106
tuple_hash::TupleHashOps::operator<
bool operator<(const Derived &rhs) const
Definition: TupleHash.h:99
ImplicitTuple::ImplicitTuple
ImplicitTuple(Arg &&arg)
Definition: TupleHash.h:109