emilib
hash_cache.hpp
1 // By Emil Ernerfeldt 2014-2016
2 // LICENSE:
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 
7 #include <functional> // std::hash
8 
9 namespace emilib {
10 
16 template<typename T>
17 class HashCache
18 {
19 public:
20  HashCache(T value) noexcept : _value(std::move(value))
21  {
22  using Hasher = typename std::hash<T>;
23  _hash = Hasher()(_value);
24  }
25 
26  HashCache(const HashCache& other) : _value(other._value)
27  {
28  _hash = other._hash;
29  }
30 
31  const HashCache& operator=(const HashCache& other)
32  {
33  _hash = other._hash;
34  _value = other._value;
35  }
36 
37  HashCache(HashCache&& other) noexcept { other.swap(*this); }
38  void operator=(HashCache&& other) noexcept { other.swap(*this); }
39 
40  void swap(HashCache& other) noexcept
41  {
42  std::swap(this->_value, other._value);
43  std::swap(this->_hash, other._hash);
44  }
45 
46  const T& value() const { return _value; }
47  std::size_t hash() const { return _hash; }
48 
49  operator T() { return _value; }
50 
51  friend bool operator==(const HashCache& a, const HashCache& b)
52  {
53  return a._hash == b._hash && a._value == b._value;
54  }
55 
56  friend bool operator!=(const HashCache& a, const HashCache& b)
57  {
58  return a._hash != b._hash || a._value != b._value;
59  }
60 
61 private:
62  T _value;
63  std::size_t _hash;
64 };
65 
66 template<typename Hasher>
68 {
69  Hasher hasher;
70 
71  template<typename T>
72  size_t operator()(const HashCache<T>& x) const
73  {
74  return hasher(x.value());
75  }
76 };
77 
78 } // namespace emilib
79 
80 namespace std {
81 
82 template <typename T>
83 struct hash<emilib::HashCache<T>>
84 {
85  const size_t operator()(const emilib::HashCache<T>& v) const
86  {
87  return v.hash();
88  }
89 };
90 
91 } // namespace std
Definition: dual.hpp:249
Definition: hash_cache.hpp:67
Definition: hash_cache.hpp:17
Definition: coroutine.hpp:18