hash.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "glm_alias.hpp"
4 #include <tuple>
5 
6 namespace iv
7 {
8 
9 //----------- iv::hash -------------------------
10 template<typename _Tp, typename Enabled=void>
11 struct hash;
12 
13 
14 //------------- use std::hash by default -----------------------
15 template< class Type, class Enabled >
16 struct hash
17 {
18  typedef size_t result_type;
19  typedef Type argument_type;
20 
21  size_t operator()( Type const & value ) const
22  {
23  return std::hash< Type >()( value );
24  }
25 };
26 
27 //-------------- enum hash ------------------------------------------
28 template< class Enum >
29 struct hash< Enum, typename std::enable_if< std::is_enum< Enum >::value >::type >
30 {
31  size_t operator()( Enum const & value ) const
32  {
33  using Underlying = typename std::underlying_type< Enum >::type;
34  return std::hash< Underlying >()( static_cast< Underlying >( value ) );
35  }
36 };
37 
38 //-------------- tuple and pair hash --------------------------------
39 namespace priv
40 {
41  template <class T>
42  inline void hash_combine(std::size_t& seed, T const& v)
43  {
44  seed ^= iv::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
45  }
46 
47  template <class Tuple, size_t Index = ::std::tuple_size<Tuple>::value - 1>
49  {
50  static void apply(size_t& seed, Tuple const& tuple)
51  {
53  hash_combine(seed, ::std::get<Index>(tuple));
54  }
55  };
56 
57  template <class Tuple>
58  struct HashValueImpl<Tuple,0>
59  {
60  static void apply(size_t& seed, Tuple const& tuple)
61  {
62  hash_combine(seed, ::std::get<0>(tuple));
63  }
64  };
65 }
66 
67 template< typename... TupleTypes >
68 struct hash< std::tuple< TupleTypes... > >
69 {
70  size_t operator()( std::tuple< TupleTypes... > const & value ) const
71  {
72  size_t seed = 0;
73  priv::HashValueImpl< std::tuple< TupleTypes... > >::apply( seed, value );
74  return seed;
75  }
76 };
77 
78 template< typename First, typename Second >
79 struct hash< std::pair< First, Second > >
80 {
81  size_t operator()( std::pair< First, Second > const & value ) const
82  {
83  return ::iv::hash< std::tuple< First, Second > >()( std::make_tuple( value.first, value.second ) );
84  }
85 };
86 
87 //--------------------- glm ---------------------------------------
88 template<>
89 struct hash< iv::int2 >
90 {
91  size_t operator()( iv::int2 const & val ) const
92  {
93  size_t seed = 0;
94  iv::priv::hash_combine( seed, val.x );
95  iv::priv::hash_combine( seed, val.y );
96  return seed;
97  }
98 };
99 
100 template<>
101 struct hash< iv::int3 >
102 {
103  size_t operator()( iv::int3 const & val ) const
104  {
105  size_t seed = 0;
106  iv::priv::hash_combine( seed, val.x );
107  iv::priv::hash_combine( seed, val.y );
108  iv::priv::hash_combine( seed, val.z );
109  return seed;
110  }
111 };
112 
113 }