QxOrm
1.5.0
C++ Object Relational Mapping library
|
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_