AnySet Documentation
extra-hash.h
Go to the documentation of this file.
1 #ifndef EXTRA_HASH_H
2 #define EXTRA_HASH_H
3 
4 #ifdef _MSC_VER
5 # include <iso646.h>
6 #endif
7 
8 #include <functional>
9 #include <cstddef>
10 #include <cstdint>
11 #include <complex>
12 #include <utility>
13 #include <tuple>
14 #include <bitset>
15 #include "AnyHash.h"
16 #include "AnySet.h"
17 
20 
21 namespace te {
22 
25 
40 {
41  return first ^ (second + std::size_t(0x9e3779b9ull) + (first << 6) + (first >> 2));
42 }
43 
44 
59 template <
60  class T, class U, class ... Args,
61  class = std::enable_if<
62  (sizeof...(Args) > 0u)
63  and std::is_same_v<T, std::size_t>
64  and std::is_same_v<U, std::size_t>
65  and std::conjunction_v<std::is_same<Args, std::size_t>...>
66  >
67 >
68 inline std::size_t hash_combine(T first, U second, Args ... args)
69 {
70  return hash_combine(hash_combine(first, second), args...);
71 }
72 
73 namespace detail {
74 
75 struct ArgHash {
76  template <class ... T>
77  std::size_t operator()(T&& ... args) const
78  {
79  if constexpr(sizeof...(args) == 1u)
80  return hash_value(std::forward<T>(args) ...);
81  else
82  return hash_combine(hash_value(std::forward<T>(args)) ...);
83  }
84 };
85 } /* namespace detail */
86 
88 
91 
93 template <class ... T>
94 struct Hash<std::tuple<T...>>
95 {
96  std::size_t operator()(const std::tuple<T ...>& tup) const
97  { return std::apply(detail::ArgHash{}, tup); }
98 };
99 
101 template <class T, class U>
102 struct Hash<std::pair<T, U>>
103 {
104  std::size_t operator()(const std::pair<T, U>& p) const
105  { return std::apply(detail::ArgHash{}, p); }
106 };
107 
109 template <class T>
110 struct Hash<std::complex<T>>
111 {
112  std::size_t operator()(const std::complex<T>& c) const
113  { return std::invoke(detail::ArgHash{}, real(c), imag(c)); }
114 };
115 
117 template <class T, std::size_t N>
118 struct Hash<std::array<T, N>>
119 {
120  std::size_t operator()(const std::array<T, N>& a) const
121  { return std::apply(detail::ArgHash{}, a); }
122 };
123 
125 
126 } /* namespace te */
127 
128 
129 
130 #endif /* EXTRA_HASH_H */
Definition: extra-hash.h:75
Primary classes and utility functions for AnySet.
Definition: SetOperations.h:21
std::size_t hash_combine(std::size_t first, std::size_t second)
Combine two hash values using a formula that is compatible with boost::hash_combine().
Definition: extra-hash.h:39
Function object that implements a hash function for instances of type T. Inherits from std::hash<T> u...
Definition: AnyHash.h:25