QxOrm  1.5.0
C++ Object Relational Mapping library
QxHashValue.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** https://www.qxorm.com/
00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
00005 **
00006 ** This file is part of the QxOrm library
00007 **
00008 ** This software is provided 'as-is', without any express or implied
00009 ** warranty. In no event will the authors be held liable for any
00010 ** damages arising from the use of this software
00011 **
00012 ** Commercial Usage
00013 ** Licensees holding valid commercial QxOrm licenses may use this file in
00014 ** accordance with the commercial license agreement provided with the
00015 ** Software or, alternatively, in accordance with the terms contained in
00016 ** a written agreement between you and Lionel Marty
00017 **
00018 ** GNU General Public License Usage
00019 ** Alternatively, this file may be used under the terms of the GNU
00020 ** General Public License version 3.0 as published by the Free Software
00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the
00022 ** packaging of this file. Please review the following information to
00023 ** ensure the GNU General Public License version 3.0 requirements will be
00024 ** met : http://www.gnu.org/copyleft/gpl.html
00025 **
00026 ** If you are unsure which license is appropriate for your use, or
00027 ** if you have questions regarding the use of this file, please contact :
00028 ** contact@qxorm.com
00029 **
00030 ****************************************************************************/
00031 
00032 #ifndef _QX_HASH_VALUE_H_
00033 #define _QX_HASH_VALUE_H_
00034 
00035 #ifdef _MSC_VER
00036 #pragma once
00037 #endif
00038 
00046 #include <QtCore/qstring.h>
00047 #include <QtCore/qdatetime.h>
00048 #include <QtCore/qvariant.h>
00049 #include <QtCore/qpair.h>
00050 
00051 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
00052 #define qx_hash_result uint
00053 #else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
00054 #define qx_hash_result std::size_t
00055 #endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
00056 
00057 inline std::size_t hash_value(const QString & s)      { return qHash(s); }
00058 inline std::size_t hash_value(const QVariant & v)     { return qHash(v.toString()); }
00059 inline std::size_t hash_value(const QDate & d)        { return qHash(d.toJulianDay()); }
00060 inline std::size_t hash_value(const QTime & t)        { return qHash(t.toString()); }
00061 inline std::size_t hash_value(const QDateTime & dt)   { return qHash(dt.toString()); }
00062 
00063 inline qx_hash_result qHash(const QVariant & v)       { return static_cast<qx_hash_result>(hash_value(v)); }
00064 
00065 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
00066 inline qx_hash_result qHash(const QDate & d)          { return static_cast<qx_hash_result>(hash_value(d)); }
00067 inline qx_hash_result qHash(const QTime & t)          { return static_cast<qx_hash_result>(hash_value(t)); }
00068 inline qx_hash_result qHash(const QDateTime & dt)     { return static_cast<qx_hash_result>(hash_value(dt)); }
00069 #endif // (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
00070 
00071 namespace qx {
00072 template <class T>
00073 inline void hash_combine(std::size_t & seed, const T & t)
00074 { seed ^= qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2); }
00075 } // namespace qx
00076 
00077 template <typename T0, typename T1>
00078 inline std::size_t hash_value(const QPair<T0, T1> & p)
00079 {
00080    std::size_t seed = 0;
00081    qx::hash_combine(seed, p.first);
00082    qx::hash_combine(seed, p.second);
00083    return seed;
00084 }
00085 
00086 #ifdef _QX_ENABLE_BOOST
00087 
00088 namespace boost {
00089 namespace tuples {
00090 
00091 template <typename T0, typename T1>
00092 inline std::size_t hash_value(const boost::tuple<T0, T1> & tu)
00093 {
00094    std::size_t seed = 0;
00095    qx::hash_combine(seed, boost::get<0>(tu));
00096    qx::hash_combine(seed, boost::get<1>(tu));
00097    return seed;
00098 }
00099 
00100 template <typename T0, class T1, typename T2>
00101 inline std::size_t hash_value(const boost::tuple<T0, T1, T2> & tu)
00102 {
00103    std::size_t seed = 0;
00104    qx::hash_combine(seed, boost::get<0>(tu));
00105    qx::hash_combine(seed, boost::get<1>(tu));
00106    qx::hash_combine(seed, boost::get<2>(tu));
00107    return seed;
00108 }
00109 
00110 template <typename T0, typename T1, typename T2, typename T3>
00111 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3> & tu)
00112 {
00113    std::size_t seed = 0;
00114    qx::hash_combine(seed, boost::get<0>(tu));
00115    qx::hash_combine(seed, boost::get<1>(tu));
00116    qx::hash_combine(seed, boost::get<2>(tu));
00117    qx::hash_combine(seed, boost::get<3>(tu));
00118    return seed;
00119 }
00120 
00121 template <typename T0, typename T1, typename T2, typename T3, typename T4>
00122 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4> & tu)
00123 {
00124    std::size_t seed = 0;
00125    qx::hash_combine(seed, boost::get<0>(tu));
00126    qx::hash_combine(seed, boost::get<1>(tu));
00127    qx::hash_combine(seed, boost::get<2>(tu));
00128    qx::hash_combine(seed, boost::get<3>(tu));
00129    qx::hash_combine(seed, boost::get<4>(tu));
00130    return seed;
00131 }
00132 
00133 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
00134 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5> & tu)
00135 {
00136    std::size_t seed = 0;
00137    qx::hash_combine(seed, boost::get<0>(tu));
00138    qx::hash_combine(seed, boost::get<1>(tu));
00139    qx::hash_combine(seed, boost::get<2>(tu));
00140    qx::hash_combine(seed, boost::get<3>(tu));
00141    qx::hash_combine(seed, boost::get<4>(tu));
00142    qx::hash_combine(seed, boost::get<5>(tu));
00143    return seed;
00144 }
00145 
00146 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00147 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
00148 {
00149    std::size_t seed = 0;
00150    qx::hash_combine(seed, boost::get<0>(tu));
00151    qx::hash_combine(seed, boost::get<1>(tu));
00152    qx::hash_combine(seed, boost::get<2>(tu));
00153    qx::hash_combine(seed, boost::get<3>(tu));
00154    qx::hash_combine(seed, boost::get<4>(tu));
00155    qx::hash_combine(seed, boost::get<5>(tu));
00156    qx::hash_combine(seed, boost::get<6>(tu));
00157    return seed;
00158 }
00159 
00160 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00161 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
00162 {
00163    std::size_t seed = 0;
00164    qx::hash_combine(seed, boost::get<0>(tu));
00165    qx::hash_combine(seed, boost::get<1>(tu));
00166    qx::hash_combine(seed, boost::get<2>(tu));
00167    qx::hash_combine(seed, boost::get<3>(tu));
00168    qx::hash_combine(seed, boost::get<4>(tu));
00169    qx::hash_combine(seed, boost::get<5>(tu));
00170    qx::hash_combine(seed, boost::get<6>(tu));
00171    qx::hash_combine(seed, boost::get<7>(tu));
00172    return seed;
00173 }
00174 
00175 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
00176 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
00177 {
00178    std::size_t seed = 0;
00179    qx::hash_combine(seed, boost::get<0>(tu));
00180    qx::hash_combine(seed, boost::get<1>(tu));
00181    qx::hash_combine(seed, boost::get<2>(tu));
00182    qx::hash_combine(seed, boost::get<3>(tu));
00183    qx::hash_combine(seed, boost::get<4>(tu));
00184    qx::hash_combine(seed, boost::get<5>(tu));
00185    qx::hash_combine(seed, boost::get<6>(tu));
00186    qx::hash_combine(seed, boost::get<7>(tu));
00187    qx::hash_combine(seed, boost::get<8>(tu));
00188    return seed;
00189 }
00190 
00191 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
00192 inline std::size_t hash_value(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
00193 {
00194    std::size_t seed = 0;
00195    qx::hash_combine(seed, boost::get<0>(tu));
00196    qx::hash_combine(seed, boost::get<1>(tu));
00197    qx::hash_combine(seed, boost::get<2>(tu));
00198    qx::hash_combine(seed, boost::get<3>(tu));
00199    qx::hash_combine(seed, boost::get<4>(tu));
00200    qx::hash_combine(seed, boost::get<5>(tu));
00201    qx::hash_combine(seed, boost::get<6>(tu));
00202    qx::hash_combine(seed, boost::get<7>(tu));
00203    qx::hash_combine(seed, boost::get<8>(tu));
00204    qx::hash_combine(seed, boost::get<9>(tu));
00205    return seed;
00206 }
00207 
00208 template <typename T0, typename T1>
00209 inline qx_hash_result qHash(const boost::tuple<T0, T1> & tu)
00210 { return static_cast<qx_hash_result>(hash_value(tu)); }
00211 
00212 template <typename T0, class T1, typename T2>
00213 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2> & tu)
00214 { return static_cast<qx_hash_result>(hash_value(tu)); }
00215 
00216 template <typename T0, typename T1, typename T2, typename T3>
00217 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3> & tu)
00218 { return static_cast<qx_hash_result>(hash_value(tu)); }
00219 
00220 template <typename T0, typename T1, typename T2, typename T3, typename T4>
00221 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4> & tu)
00222 { return static_cast<qx_hash_result>(hash_value(tu)); }
00223 
00224 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
00225 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5> & tu)
00226 { return static_cast<qx_hash_result>(hash_value(tu)); }
00227 
00228 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00229 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
00230 { return static_cast<qx_hash_result>(hash_value(tu)); }
00231 
00232 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00233 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
00234 { return static_cast<qx_hash_result>(hash_value(tu)); }
00235 
00236 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
00237 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
00238 { return static_cast<qx_hash_result>(hash_value(tu)); }
00239 
00240 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
00241 inline qx_hash_result qHash(const boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
00242 { return static_cast<qx_hash_result>(hash_value(tu)); }
00243 
00244 } // namespace tuples
00245 } // namespace boost
00246 
00247 #endif // _QX_ENABLE_BOOST
00248 
00249 // Compilation option '_QX_HASH_NO_STD_NAMESPACE'
00250 // Try to avoid compilation error, something like : error: no matching function for call to 'qHash(const std::tuple<...>&)'
00251 // This is due to C++ ADL to resolve specialized functions : qHash(T) should be implemented in the same namespace as T
00252 // 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
00253 // More details here : https://www.kdab.com/how-to-declare-a-qhash-overload/
00254 // And here : https://stackoverflow.com/questions/47460098/using-standard-library-types-as-keys-in-qhash-or-qset
00255 #ifndef _QX_HASH_NO_STD_NAMESPACE
00256 namespace std {
00257 #endif // _QX_HASH_NO_STD_NAMESPACE
00258 
00259 #ifndef QT_NO_STL
00260 inline qx_hash_result qHash(const std::string & s)     { QString tmp = QString::fromStdString(s); return qHash(tmp); }
00261 inline qx_hash_result qHash(const std::wstring & s)    { QString tmp = QString::fromStdWString(s); return qHash(tmp); }
00262 #else // QT_NO_STL
00263 inline qx_hash_result qHash(const std::string & s)     { QString tmp = QString::fromLatin1(s.data(), int(s.size())); return qHash(tmp); }
00264 inline qx_hash_result qHash(const std::wstring & s)    { qAssert(false); /* Need STL compatibility ! */ return 0; }
00265 #endif // QT_NO_STL
00266 
00267 template <typename T0, typename T1>
00268 inline std::size_t hash_value(const std::tuple<T0, T1> & tu)
00269 {
00270    std::size_t seed = 0;
00271    qx::hash_combine(seed, std::get<0>(tu));
00272    qx::hash_combine(seed, std::get<1>(tu));
00273    return seed;
00274 }
00275 
00276 template <typename T0, class T1, typename T2>
00277 inline std::size_t hash_value(const std::tuple<T0, T1, T2> & tu)
00278 {
00279    std::size_t seed = 0;
00280    qx::hash_combine(seed, std::get<0>(tu));
00281    qx::hash_combine(seed, std::get<1>(tu));
00282    qx::hash_combine(seed, std::get<2>(tu));
00283    return seed;
00284 }
00285 
00286 template <typename T0, typename T1, typename T2, typename T3>
00287 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3> & tu)
00288 {
00289    std::size_t seed = 0;
00290    qx::hash_combine(seed, std::get<0>(tu));
00291    qx::hash_combine(seed, std::get<1>(tu));
00292    qx::hash_combine(seed, std::get<2>(tu));
00293    qx::hash_combine(seed, std::get<3>(tu));
00294    return seed;
00295 }
00296 
00297 template <typename T0, typename T1, typename T2, typename T3, typename T4>
00298 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4> & tu)
00299 {
00300    std::size_t seed = 0;
00301    qx::hash_combine(seed, std::get<0>(tu));
00302    qx::hash_combine(seed, std::get<1>(tu));
00303    qx::hash_combine(seed, std::get<2>(tu));
00304    qx::hash_combine(seed, std::get<3>(tu));
00305    qx::hash_combine(seed, std::get<4>(tu));
00306    return seed;
00307 }
00308 
00309 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
00310 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5> & tu)
00311 {
00312    std::size_t seed = 0;
00313    qx::hash_combine(seed, std::get<0>(tu));
00314    qx::hash_combine(seed, std::get<1>(tu));
00315    qx::hash_combine(seed, std::get<2>(tu));
00316    qx::hash_combine(seed, std::get<3>(tu));
00317    qx::hash_combine(seed, std::get<4>(tu));
00318    qx::hash_combine(seed, std::get<5>(tu));
00319    return seed;
00320 }
00321 
00322 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00323 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
00324 {
00325    std::size_t seed = 0;
00326    qx::hash_combine(seed, std::get<0>(tu));
00327    qx::hash_combine(seed, std::get<1>(tu));
00328    qx::hash_combine(seed, std::get<2>(tu));
00329    qx::hash_combine(seed, std::get<3>(tu));
00330    qx::hash_combine(seed, std::get<4>(tu));
00331    qx::hash_combine(seed, std::get<5>(tu));
00332    qx::hash_combine(seed, std::get<6>(tu));
00333    return seed;
00334 }
00335 
00336 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00337 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
00338 {
00339    std::size_t seed = 0;
00340    qx::hash_combine(seed, std::get<0>(tu));
00341    qx::hash_combine(seed, std::get<1>(tu));
00342    qx::hash_combine(seed, std::get<2>(tu));
00343    qx::hash_combine(seed, std::get<3>(tu));
00344    qx::hash_combine(seed, std::get<4>(tu));
00345    qx::hash_combine(seed, std::get<5>(tu));
00346    qx::hash_combine(seed, std::get<6>(tu));
00347    qx::hash_combine(seed, std::get<7>(tu));
00348    return seed;
00349 }
00350 
00351 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
00352 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
00353 {
00354    std::size_t seed = 0;
00355    qx::hash_combine(seed, std::get<0>(tu));
00356    qx::hash_combine(seed, std::get<1>(tu));
00357    qx::hash_combine(seed, std::get<2>(tu));
00358    qx::hash_combine(seed, std::get<3>(tu));
00359    qx::hash_combine(seed, std::get<4>(tu));
00360    qx::hash_combine(seed, std::get<5>(tu));
00361    qx::hash_combine(seed, std::get<6>(tu));
00362    qx::hash_combine(seed, std::get<7>(tu));
00363    qx::hash_combine(seed, std::get<8>(tu));
00364    return seed;
00365 }
00366 
00367 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
00368 inline std::size_t hash_value(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
00369 {
00370    std::size_t seed = 0;
00371    qx::hash_combine(seed, std::get<0>(tu));
00372    qx::hash_combine(seed, std::get<1>(tu));
00373    qx::hash_combine(seed, std::get<2>(tu));
00374    qx::hash_combine(seed, std::get<3>(tu));
00375    qx::hash_combine(seed, std::get<4>(tu));
00376    qx::hash_combine(seed, std::get<5>(tu));
00377    qx::hash_combine(seed, std::get<6>(tu));
00378    qx::hash_combine(seed, std::get<7>(tu));
00379    qx::hash_combine(seed, std::get<8>(tu));
00380    qx::hash_combine(seed, std::get<9>(tu));
00381    return seed;
00382 }
00383 
00384 #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))))
00385 template <typename T0, typename T1>
00386 inline qx_hash_result qHash(const std::pair<T0, T1> & p)
00387 {
00388    std::size_t seed = 0;
00389    qx::hash_combine(seed, p.first);
00390    qx::hash_combine(seed, p.second);
00391    return static_cast<qx_hash_result>(seed);
00392 }
00393 #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))))
00394 
00395 template <typename T0, typename T1>
00396 inline qx_hash_result qHash(const std::tuple<T0, T1> & tu)
00397 { return static_cast<qx_hash_result>(hash_value(tu)); }
00398 
00399 template <typename T0, class T1, typename T2>
00400 inline qx_hash_result qHash(const std::tuple<T0, T1, T2> & tu)
00401 { return static_cast<qx_hash_result>(hash_value(tu)); }
00402 
00403 template <typename T0, typename T1, typename T2, typename T3>
00404 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3> & tu)
00405 { return static_cast<qx_hash_result>(hash_value(tu)); }
00406 
00407 template <typename T0, typename T1, typename T2, typename T3, typename T4>
00408 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4> & tu)
00409 { return static_cast<qx_hash_result>(hash_value(tu)); }
00410 
00411 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
00412 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5> & tu)
00413 { return static_cast<qx_hash_result>(hash_value(tu)); }
00414 
00415 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00416 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6> & tu)
00417 { return static_cast<qx_hash_result>(hash_value(tu)); }
00418 
00419 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00420 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7> & tu)
00421 { return static_cast<qx_hash_result>(hash_value(tu)); }
00422 
00423 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
00424 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> & tu)
00425 { return static_cast<qx_hash_result>(hash_value(tu)); }
00426 
00427 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
00428 inline qx_hash_result qHash(const std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> & tu)
00429 { return static_cast<qx_hash_result>(hash_value(tu)); }
00430 
00431 #ifndef _QX_HASH_NO_STD_NAMESPACE
00432 } // namespace std
00433 #endif // _QX_HASH_NO_STD_NAMESPACE
00434 
00435 #endif // _QX_HASH_VALUE_H_