|
|
@@ -13,40 +13,44 @@
|
|
|
|
|
|
template <typename, typename> class identity;
|
|
|
|
|
|
+#define IDENTITY_HASH(type) \
|
|
|
+ struct ::std::hash<T> \
|
|
|
+ : public ::std::hash<identity<T, decltype(std::declval<T>().id)>> {}
|
|
|
+
|
|
|
namespace std {
|
|
|
- template <typename T, typename I> struct hash<identity<T, I>> {
|
|
|
- std::size_t operator()(identity<T, I> tp) const {
|
|
|
- return std::hash<I>()(tp.id);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- template <typename T, typename S> struct hash<std::pair<T, S>> {
|
|
|
- std::size_t operator()(std::pair<T, S> const & pair) const {
|
|
|
- return std::hash<T>()(pair.first) ^ std::hash<S>()(pair.second);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- template <std::size_t I> struct tuple_hash;
|
|
|
-
|
|
|
- template <> struct tuple_hash<0> {
|
|
|
- template <typename... As>
|
|
|
- std::size_t operator()(std::tuple<As...> const &) const {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- template <std::size_t I> struct tuple_hash {
|
|
|
- template <typename... As>
|
|
|
- std::size_t operator()(std::tuple<As...> const & tuple) const {
|
|
|
- using elt = typename std::tuple_element<I - 1, std::tuple<As...>>::type;
|
|
|
- return std::hash<elt>()(std::get<I - 1>(tuple)) ^
|
|
|
- tuple_hash<I - 1>()(tuple);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- template <typename... As> struct hash<std::tuple<As...>> {
|
|
|
- std::size_t operator()(std::tuple<As...> const & tuple) const {
|
|
|
- return tuple_hash<sizeof...(As)>()(tuple);
|
|
|
- }
|
|
|
- };
|
|
|
+template <typename T, typename I> struct hash<identity<T, I>> {
|
|
|
+ std::size_t operator()(identity<T, I> tp) const {
|
|
|
+ return std::hash<I>()(tp.id);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template <typename T, typename S> struct hash<std::pair<T, S>> {
|
|
|
+ std::size_t operator()(std::pair<T, S> const & pair) const {
|
|
|
+ return std::hash<T>()(pair.first) ^ std::hash<S>()(pair.second);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template <std::size_t I> struct tuple_hash;
|
|
|
+
|
|
|
+template <> struct tuple_hash<0> {
|
|
|
+ template <typename... As>
|
|
|
+ std::size_t operator()(std::tuple<As...> const &) const {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template <std::size_t I> struct tuple_hash {
|
|
|
+ template <typename... As>
|
|
|
+ std::size_t operator()(std::tuple<As...> const & tuple) const {
|
|
|
+ using elt = typename std::tuple_element<I - 1, std::tuple<As...>>::type;
|
|
|
+ return std::hash<elt>()(std::get<I - 1>(tuple)) ^
|
|
|
+ tuple_hash<I - 1>()(tuple);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template <typename... As> struct hash<std::tuple<As...>> {
|
|
|
+ std::size_t operator()(std::tuple<As...> const & tuple) const {
|
|
|
+ return tuple_hash<sizeof...(As)>()(tuple);
|
|
|
+ }
|
|
|
+};
|
|
|
}
|