1/// @ref gtx_hash
2/// @file glm/gtx/hash.inl
3///
4/// @see core (dependence)
5///
6/// @defgroup gtx_hash GLM_GTX_hash
7/// @ingroup gtx
8///
9/// @brief Add std::hash support for glm types
10///
11/// <glm/gtx/hash.inl> need to be included to use these functionalities.
12
13namespace glm {
14namespace detail
15{
16	GLM_INLINE void hash_combine(size_t &seed, size_t hash)
17	{
18		hash += 0x9e3779b9 + (seed << 6) + (seed >> 2);
19		seed ^= hash;
20	}
21}}
22
23namespace std
24{
25	template <typename T, glm::precision P>
26	GLM_FUNC_QUALIFIER size_t hash<glm::tvec1<T, P>>::operator()(glm::tvec1<T, P> const & v) const
27	{
28		hash<T> hasher;
29		return hasher(v.x);
30	}
31
32	template <typename T, glm::precision P>
33	GLM_FUNC_QUALIFIER size_t hash<glm::tvec2<T, P>>::operator()(glm::tvec2<T, P> const & v) const
34	{
35		size_t seed = 0;
36		hash<T> hasher;
37		glm::detail::hash_combine(seed, hasher(v.x));
38		glm::detail::hash_combine(seed, hasher(v.y));
39		return seed;
40	}
41
42	template <typename T, glm::precision P>
43	GLM_FUNC_QUALIFIER size_t hash<glm::tvec3<T, P>>::operator()(glm::tvec3<T, P> const & v) const
44	{
45		size_t seed = 0;
46		hash<T> hasher;
47		glm::detail::hash_combine(seed, hasher(v.x));
48		glm::detail::hash_combine(seed, hasher(v.y));
49		glm::detail::hash_combine(seed, hasher(v.z));
50		return seed;
51	}
52
53	template <typename T, glm::precision P>
54	GLM_FUNC_QUALIFIER size_t hash<glm::tvec4<T, P>>::operator()(glm::tvec4<T, P> const & v) const
55	{
56		size_t seed = 0;
57		hash<T> hasher;
58		glm::detail::hash_combine(seed, hasher(v.x));
59		glm::detail::hash_combine(seed, hasher(v.y));
60		glm::detail::hash_combine(seed, hasher(v.z));
61		glm::detail::hash_combine(seed, hasher(v.w));
62		return seed;
63	}
64
65	template <typename T, glm::precision P>
66	GLM_FUNC_QUALIFIER size_t hash<glm::tquat<T, P>>::operator()(glm::tquat<T,P> const & q) const
67	{
68		size_t seed = 0;
69		hash<T> hasher;
70		glm::detail::hash_combine(seed, hasher(q.x));
71		glm::detail::hash_combine(seed, hasher(q.y));
72		glm::detail::hash_combine(seed, hasher(q.z));
73		glm::detail::hash_combine(seed, hasher(q.w));
74		return seed;
75	}
76
77	template <typename T, glm::precision P>
78	GLM_FUNC_QUALIFIER size_t hash<glm::tdualquat<T, P>>::operator()(glm::tdualquat<T, P> const & q) const
79	{
80		size_t seed = 0;
81		hash<glm::tquat<T, P>> hasher;
82		glm::detail::hash_combine(seed, hasher(q.real));
83		glm::detail::hash_combine(seed, hasher(q.dual));
84		return seed;
85	}
86
87	template <typename T, glm::precision P>
88	GLM_FUNC_QUALIFIER size_t hash<glm::tmat2x2<T, P>>::operator()(glm::tmat2x2<T, P> const & m) const
89	{
90		size_t seed = 0;
91		hash<glm::tvec2<T, P>> hasher;
92		glm::detail::hash_combine(seed, hasher(m[0]));
93		glm::detail::hash_combine(seed, hasher(m[1]));
94		return seed;
95	}
96
97	template <typename T, glm::precision P>
98	GLM_FUNC_QUALIFIER size_t hash<glm::tmat2x3<T, P>>::operator()(glm::tmat2x3<T, P> const & m) const
99	{
100		size_t seed = 0;
101		hash<glm::tvec3<T, P>> hasher;
102		glm::detail::hash_combine(seed, hasher(m[0]));
103		glm::detail::hash_combine(seed, hasher(m[1]));
104		return seed;
105	}
106
107	template <typename T, glm::precision P>
108	GLM_FUNC_QUALIFIER size_t hash<glm::tmat2x4<T, P>>::operator()(glm::tmat2x4<T, P> const & m) const
109	{
110		size_t seed = 0;
111		hash<glm::tvec4<T, P>> hasher;
112		glm::detail::hash_combine(seed, hasher(m[0]));
113		glm::detail::hash_combine(seed, hasher(m[1]));
114		return seed;
115	}
116
117	template <typename T, glm::precision P>
118	GLM_FUNC_QUALIFIER size_t hash<glm::tmat3x2<T, P>>::operator()(glm::tmat3x2<T, P> const & m) const
119	{
120		size_t seed = 0;
121		hash<glm::tvec2<T, P>> hasher;
122		glm::detail::hash_combine(seed, hasher(m[0]));
123		glm::detail::hash_combine(seed, hasher(m[1]));
124		glm::detail::hash_combine(seed, hasher(m[2]));
125		return seed;
126	}
127
128	template <typename T, glm::precision P>
129	GLM_FUNC_QUALIFIER size_t hash<glm::tmat3x3<T, P>>::operator()(glm::tmat3x3<T, P> const & m) const
130	{
131		size_t seed = 0;
132		hash<glm::tvec3<T, P>> hasher;
133		glm::detail::hash_combine(seed, hasher(m[0]));
134		glm::detail::hash_combine(seed, hasher(m[1]));
135		glm::detail::hash_combine(seed, hasher(m[2]));
136		return seed;
137	}
138
139	template <typename T, glm::precision P>
140	GLM_FUNC_QUALIFIER size_t hash<glm::tmat3x4<T, P>>::operator()(glm::tmat3x4<T, P> const & m) const
141	{
142		size_t seed = 0;
143		hash<glm::tvec4<T, P>> hasher;
144		glm::detail::hash_combine(seed, hasher(m[0]));
145		glm::detail::hash_combine(seed, hasher(m[1]));
146		glm::detail::hash_combine(seed, hasher(m[2]));
147		return seed;
148	}
149
150	template <typename T, glm::precision P>
151	GLM_FUNC_QUALIFIER size_t hash<glm::tmat4x2<T,P>>::operator()(glm::tmat4x2<T,P> const & m) const
152	{
153		size_t seed = 0;
154		hash<glm::tvec2<T, P>> hasher;
155		glm::detail::hash_combine(seed, hasher(m[0]));
156		glm::detail::hash_combine(seed, hasher(m[1]));
157		glm::detail::hash_combine(seed, hasher(m[2]));
158		glm::detail::hash_combine(seed, hasher(m[3]));
159		return seed;
160	}
161
162	template <typename T, glm::precision P>
163	GLM_FUNC_QUALIFIER size_t hash<glm::tmat4x3<T,P>>::operator()(glm::tmat4x3<T,P> const & m) const
164	{
165		size_t seed = 0;
166		hash<glm::tvec3<T, P>> hasher;
167		glm::detail::hash_combine(seed, hasher(m[0]));
168		glm::detail::hash_combine(seed, hasher(m[1]));
169		glm::detail::hash_combine(seed, hasher(m[2]));
170		glm::detail::hash_combine(seed, hasher(m[3]));
171		return seed;
172	}
173
174	template <typename T, glm::precision P>
175	GLM_FUNC_QUALIFIER size_t hash<glm::tmat4x4<T,P>>::operator()(glm::tmat4x4<T, P> const & m) const
176	{
177		size_t seed = 0;
178		hash<glm::tvec4<T, P>> hasher;
179		glm::detail::hash_combine(seed, hasher(m[0]));
180		glm::detail::hash_combine(seed, hasher(m[1]));
181		glm::detail::hash_combine(seed, hasher(m[2]));
182		glm::detail::hash_combine(seed, hasher(m[3]));
183		return seed;
184	}
185}
186