QxOrm 1.4.9
C++ Object Relational Mapping library
Loading...
Searching...
No Matches
QxHashValue.h
Go to the documentation of this file.
1/****************************************************************************
2**
3** https://www.qxorm.com/
4** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
5**
6** This file is part of the QxOrm library
7**
8** This software is provided 'as-is', without any express or implied
9** warranty. In no event will the authors be held liable for any
10** damages arising from the use of this software
11**
12** Commercial Usage
13** Licensees holding valid commercial QxOrm licenses may use this file in
14** accordance with the commercial license agreement provided with the
15** Software or, alternatively, in accordance with the terms contained in
16** a written agreement between you and Lionel Marty
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3.0 as published by the Free Software
21** Foundation and appearing in the file 'license.gpl3.txt' included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU General Public License version 3.0 requirements will be
24** met : http://www.gnu.org/copyleft/gpl.html
25**
26** If you are unsure which license is appropriate for your use, or
27** if you have questions regarding the use of this file, please contact :
28** contact@qxorm.com
29**
30****************************************************************************/
31
32#ifndef _QX_HASH_VALUE_H_
33#define _QX_HASH_VALUE_H_
34
35#ifdef _MSC_VER
36#pragma once
37#endif
38
46#include <QtCore/qstring.h>
47#include <QtCore/qdatetime.h>
48#include <QtCore/qvariant.h>
49#include <QtCore/qpair.h>
50
51#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
52#define qx_hash_result uint
53#else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
54#define qx_hash_result std::size_t
55#endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
56
57inline std::size_t hash_value(const QString & s) { return qHash(s); }
58inline std::size_t hash_value(const QVariant & v) { return qHash(v.toString()); }
59inline std::size_t hash_value(const QDate & d) { return qHash(d.toJulianDay()); }
60inline std::size_t hash_value(const QTime & t) { return qHash(t.toString()); }
61inline std::size_t hash_value(const QDateTime & dt) { return qHash(dt.toString()); }
62
63inline qx_hash_result qHash(const QVariant & v) { return static_cast<qx_hash_result>(hash_value(v)); }
64
65#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
66inline qx_hash_result qHash(const QDate & d) { return static_cast<qx_hash_result>(hash_value(d)); }
67inline qx_hash_result qHash(const QTime & t) { return static_cast<qx_hash_result>(hash_value(t)); }
68inline qx_hash_result qHash(const QDateTime & dt) { return static_cast<qx_hash_result>(hash_value(dt)); }
69#endif // (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
70
71namespace qx {
72template <class T>
73inline void hash_combine(std::size_t & seed, const T & t)
74{ seed ^= qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2); }
75} // namespace qx
76
77template <typename T0, typename T1>
78inline std::size_t hash_value(const QPair<T0, T1> & p)
79{
80 std::size_t seed = 0;
81 qx::hash_combine(seed, p.first);
82 qx::hash_combine(seed, p.second);
83 return seed;
84}
85
86#ifdef _QX_ENABLE_BOOST
87
88namespace boost {
89namespace tuples {
90
91template <typename T0, typename T1>
92inline std::size_t hash_value(const boost::tuple<T0, T1> & tu)
93{
94 std::size_t seed = 0;
95 qx::hash_combine(seed, boost::get<0>(tu));
96 qx::hash_combine(seed, boost::get<1>(tu));
97 return seed;
98}
99
100template <typename T0, class T1, typename T2>
101inline std::size_t hash_value(const boost::tuple<T0, T1, T2> & tu)
102{
103 std::size_t seed = 0;
104 qx::hash_combine(seed, boost::get<0>(tu));
105 qx::hash_combine(seed, boost::get<1>(tu));
106 qx::hash_combine(seed, boost::get<2>(tu));
107 return seed;
108}
109
110template <typename T0, typename T1, typename T2, typename T3>
111inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3> & tu)
112{
113 std::size_t seed = 0;
114 qx::hash_combine(seed, boost::get<0>(tu));
115 qx::hash_combine(seed, boost::get<1>(tu));
116 qx::hash_combine(seed, boost::get<2>(tu));
117 qx::hash_combine(seed, boost::get<3>(tu));
118 return seed;
119}
120
121template <typename T0, typename T1, typename T2, typename T3, typename T4>
122inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4> & tu)
123{
124 std::size_t seed = 0;
125 qx::hash_combine(seed, boost::get<0>(tu));
126 qx::hash_combine(seed, boost::get<1>(tu));
127 qx::hash_combine(seed, boost::get<2>(tu));
128 qx::hash_combine(seed, boost::get<3>(tu));
129 qx::hash_combine(seed, boost::get<4>(tu));
130 return seed;
131}
132
133template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
134inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5> & tu)
135{
136 std::size_t seed = 0;
137 qx::hash_combine(seed, boost::get<0>(tu));
138 qx::hash_combine(seed, boost::get<1>(tu));
139 qx::hash_combine(seed, boost::get<2>(tu));
140 qx::hash_combine(seed, boost::get<3>(tu));
141 qx::hash_combine(seed, boost::get<4>(tu));
142 qx::hash_combine(seed, boost::get<5>(tu));
143 return seed;
144}
145
146template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
147inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
148{
149 std::size_t seed = 0;
150 qx::hash_combine(seed, boost::get<0>(tu));
151 qx::hash_combine(seed, boost::get<1>(tu));
152 qx::hash_combine(seed, boost::get<2>(tu));
153 qx::hash_combine(seed, boost::get<3>(tu));
154 qx::hash_combine(seed, boost::get<4>(tu));
155 qx::hash_combine(seed, boost::get<5>(tu));
156 qx::hash_combine(seed, boost::get<6>(tu));
157 return seed;
158}
159
160template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
161inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
162{
163 std::size_t seed = 0;
164 qx::hash_combine(seed, boost::get<0>(tu));
165 qx::hash_combine(seed, boost::get<1>(tu));
166 qx::hash_combine(seed, boost::get<2>(tu));
167 qx::hash_combine(seed, boost::get<3>(tu));
168 qx::hash_combine(seed, boost::get<4>(tu));
169 qx::hash_combine(seed, boost::get<5>(tu));
170 qx::hash_combine(seed, boost::get<6>(tu));
171 qx::hash_combine(seed, boost::get<7>(tu));
172 return seed;
173}
174
175template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
176inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
177{
178 std::size_t seed = 0;
179 qx::hash_combine(seed, boost::get<0>(tu));
180 qx::hash_combine(seed, boost::get<1>(tu));
181 qx::hash_combine(seed, boost::get<2>(tu));
182 qx::hash_combine(seed, boost::get<3>(tu));
183 qx::hash_combine(seed, boost::get<4>(tu));
184 qx::hash_combine(seed, boost::get<5>(tu));
185 qx::hash_combine(seed, boost::get<6>(tu));
186 qx::hash_combine(seed, boost::get<7>(tu));
187 qx::hash_combine(seed, boost::get<8>(tu));
188 return seed;
189}
190
191template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
192inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
193{
194 std::size_t seed = 0;
195 qx::hash_combine(seed, boost::get<0>(tu));
196 qx::hash_combine(seed, boost::get<1>(tu));
197 qx::hash_combine(seed, boost::get<2>(tu));
198 qx::hash_combine(seed, boost::get<3>(tu));
199 qx::hash_combine(seed, boost::get<4>(tu));
200 qx::hash_combine(seed, boost::get<5>(tu));
201 qx::hash_combine(seed, boost::get<6>(tu));
202 qx::hash_combine(seed, boost::get<7>(tu));
203 qx::hash_combine(seed, boost::get<8>(tu));
204 qx::hash_combine(seed, boost::get<9>(tu));
205 return seed;
206}
207
208template <typename T0, typename T1>
209inline qx_hash_result qHash(const boost::tuple<T0, T1> & tu)
210{ return static_cast<qx_hash_result>(hash_value(tu)); }
211
212template <typename T0, class T1, typename T2>
213inline qx_hash_result qHash(const boost::tuple<T0, T1, T2> & tu)
214{ return static_cast<qx_hash_result>(hash_value(tu)); }
215
216template <typename T0, typename T1, typename T2, typename T3>
217inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3> & tu)
218{ return static_cast<qx_hash_result>(hash_value(tu)); }
219
220template <typename T0, typename T1, typename T2, typename T3, typename T4>
221inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4> & tu)
222{ return static_cast<qx_hash_result>(hash_value(tu)); }
223
224template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
225inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5> & tu)
226{ return static_cast<qx_hash_result>(hash_value(tu)); }
227
228template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
229inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
230{ return static_cast<qx_hash_result>(hash_value(tu)); }
231
232template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
233inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
234{ return static_cast<qx_hash_result>(hash_value(tu)); }
235
236template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
237inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
238{ return static_cast<qx_hash_result>(hash_value(tu)); }
239
240template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
241inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
242{ return static_cast<qx_hash_result>(hash_value(tu)); }
243
244} // namespace tuples
245} // namespace boost
246
247#endif // _QX_ENABLE_BOOST
248
249// Compilation option '_QX_HASH_NO_STD_NAMESPACE'
250// Try to avoid compilation error, something like : error: no matching function for call to 'qHash(const std::tuple<...>&)'
251// This is due to C++ ADL to resolve specialized functions : qHash(T) should be implemented in the same namespace as T
252// For 'std' classes, it should be NOT allowed : the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std
253// More details here : https://www.kdab.com/how-to-declare-a-qhash-overload/
254// And here : https://stackoverflow.com/questions/47460098/using-standard-library-types-as-keys-in-qhash-or-qset
255#ifndef _QX_HASH_NO_STD_NAMESPACE
256namespace std {
257#endif // _QX_HASH_NO_STD_NAMESPACE
258
259#ifndef QT_NO_STL
260inline qx_hash_result qHash(const std::string & s) { QString tmp = QString::fromStdString(s); return qHash(tmp); }
261inline qx_hash_result qHash(const std::wstring & s) { QString tmp = QString::fromStdWString(s); return qHash(tmp); }
262#else // QT_NO_STL
263inline qx_hash_result qHash(const std::string & s) { QString tmp = QString::fromLatin1(s.data(), int(s.size())); return qHash(tmp); }
264inline qx_hash_result qHash(const std::wstring & s) { qAssert(false); /* Need STL compatibility ! */ return 0; }
265#endif // QT_NO_STL
266
267template <typename T0, typename T1>
268inline std::size_t hash_value(const std::tuple<T0, T1> & tu)
269{
270 std::size_t seed = 0;
271 qx::hash_combine(seed, std::get<0>(tu));
272 qx::hash_combine(seed, std::get<1>(tu));
273 return seed;
274}
275
276template <typename T0, class T1, typename T2>
277inline std::size_t hash_value(const std::tuple<T0, T1, T2> & tu)
278{
279 std::size_t seed = 0;
280 qx::hash_combine(seed, std::get<0>(tu));
281 qx::hash_combine(seed, std::get<1>(tu));
282 qx::hash_combine(seed, std::get<2>(tu));
283 return seed;
284}
285
286template <typename T0, typename T1, typename T2, typename T3>
287inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3> & tu)
288{
289 std::size_t seed = 0;
290 qx::hash_combine(seed, std::get<0>(tu));
291 qx::hash_combine(seed, std::get<1>(tu));
292 qx::hash_combine(seed, std::get<2>(tu));
293 qx::hash_combine(seed, std::get<3>(tu));
294 return seed;
295}
296
297template <typename T0, typename T1, typename T2, typename T3, typename T4>
298inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4> & tu)
299{
300 std::size_t seed = 0;
301 qx::hash_combine(seed, std::get<0>(tu));
302 qx::hash_combine(seed, std::get<1>(tu));
303 qx::hash_combine(seed, std::get<2>(tu));
304 qx::hash_combine(seed, std::get<3>(tu));
305 qx::hash_combine(seed, std::get<4>(tu));
306 return seed;
307}
308
309template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
310inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5> & tu)
311{
312 std::size_t seed = 0;
313 qx::hash_combine(seed, std::get<0>(tu));
314 qx::hash_combine(seed, std::get<1>(tu));
315 qx::hash_combine(seed, std::get<2>(tu));
316 qx::hash_combine(seed, std::get<3>(tu));
317 qx::hash_combine(seed, std::get<4>(tu));
318 qx::hash_combine(seed, std::get<5>(tu));
319 return seed;
320}
321
322template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
323inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
324{
325 std::size_t seed = 0;
326 qx::hash_combine(seed, std::get<0>(tu));
327 qx::hash_combine(seed, std::get<1>(tu));
328 qx::hash_combine(seed, std::get<2>(tu));
329 qx::hash_combine(seed, std::get<3>(tu));
330 qx::hash_combine(seed, std::get<4>(tu));
331 qx::hash_combine(seed, std::get<5>(tu));
332 qx::hash_combine(seed, std::get<6>(tu));
333 return seed;
334}
335
336template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
337inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
338{
339 std::size_t seed = 0;
340 qx::hash_combine(seed, std::get<0>(tu));
341 qx::hash_combine(seed, std::get<1>(tu));
342 qx::hash_combine(seed, std::get<2>(tu));
343 qx::hash_combine(seed, std::get<3>(tu));
344 qx::hash_combine(seed, std::get<4>(tu));
345 qx::hash_combine(seed, std::get<5>(tu));
346 qx::hash_combine(seed, std::get<6>(tu));
347 qx::hash_combine(seed, std::get<7>(tu));
348 return seed;
349}
350
351template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
352inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
353{
354 std::size_t seed = 0;
355 qx::hash_combine(seed, std::get<0>(tu));
356 qx::hash_combine(seed, std::get<1>(tu));
357 qx::hash_combine(seed, std::get<2>(tu));
358 qx::hash_combine(seed, std::get<3>(tu));
359 qx::hash_combine(seed, std::get<4>(tu));
360 qx::hash_combine(seed, std::get<5>(tu));
361 qx::hash_combine(seed, std::get<6>(tu));
362 qx::hash_combine(seed, std::get<7>(tu));
363 qx::hash_combine(seed, std::get<8>(tu));
364 return seed;
365}
366
367template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
368inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
369{
370 std::size_t seed = 0;
371 qx::hash_combine(seed, std::get<0>(tu));
372 qx::hash_combine(seed, std::get<1>(tu));
373 qx::hash_combine(seed, std::get<2>(tu));
374 qx::hash_combine(seed, std::get<3>(tu));
375 qx::hash_combine(seed, std::get<4>(tu));
376 qx::hash_combine(seed, std::get<5>(tu));
377 qx::hash_combine(seed, std::get<6>(tu));
378 qx::hash_combine(seed, std::get<7>(tu));
379 qx::hash_combine(seed, std::get<8>(tu));
380 qx::hash_combine(seed, std::get<9>(tu));
381 return seed;
382}
383
384#if ((QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) || ((QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))))
385template <typename T0, typename T1>
386inline qx_hash_result qHash(const std::pair<T0, T1> & p)
387{
388 std::size_t seed = 0;
389 qx::hash_combine(seed, p.first);
390 qx::hash_combine(seed, p.second);
391 return static_cast<qx_hash_result>(seed);
392}
393#endif // ((QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) || ((QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))))
394
395template <typename T0, typename T1>
396inline qx_hash_result qHash(const std::tuple<T0, T1> & tu)
397{ return static_cast<qx_hash_result>(hash_value(tu)); }
398
399template <typename T0, class T1, typename T2>
400inline qx_hash_result qHash(const std::tuple<T0, T1, T2> & tu)
401{ return static_cast<qx_hash_result>(hash_value(tu)); }
402
403template <typename T0, typename T1, typename T2, typename T3>
404inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3> & tu)
405{ return static_cast<qx_hash_result>(hash_value(tu)); }
406
407template <typename T0, typename T1, typename T2, typename T3, typename T4>
408inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4> & tu)
409{ return static_cast<qx_hash_result>(hash_value(tu)); }
410
411template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
412inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5> & tu)
413{ return static_cast<qx_hash_result>(hash_value(tu)); }
414
415template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
416inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
417{ return static_cast<qx_hash_result>(hash_value(tu)); }
418
419template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
420inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
421{ return static_cast<qx_hash_result>(hash_value(tu)); }
422
423template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
424inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
425{ return static_cast<qx_hash_result>(hash_value(tu)); }
426
427template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
428inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
429{ return static_cast<qx_hash_result>(hash_value(tu)); }
430
431#ifndef _QX_HASH_NO_STD_NAMESPACE
432} // namespace std
433#endif // _QX_HASH_NO_STD_NAMESPACE
434
435#endif // _QX_HASH_VALUE_H_
std::size_t hash_value(const QString &s)
Definition QxHashValue.h:57
#define qx_hash_result
Definition QxHashValue.h:54
qx_hash_result qHash(const QVariant &v)
Definition QxHashValue.h:63
#define qAssert(x)
Definition QxMacro.h:52
std::size_t hash_value(const boost::tuple< T0, T1 > &tu)
Definition QxHashValue.h:92
qx_hash_result qHash(const boost::tuple< T0, T1 > &tu)
Root namespace for all QxOrm library features.
void hash_combine(std::size_t &seed, const T &t)
Definition QxHashValue.h:73
qx_hash_result qHash(const std::string &s)
std::size_t hash_value(const std::tuple< T0, T1 > &tu)