I need to use QList<QVariant>
as a key to std::unordered_map
. The purpose of this is to optimize searching over a table of data by making index over the unique key columns.
So I made this code. It's not complete, but lists some basic data types that occur in the table key columns:
#include <unordered_map>
#include <string>
//std::hash
#include <functional>
//std::size_t
#include <cstddef>
// Hashing method for QVariantList
namespace std {
template <>
struct hash<QList<QVariant>>
{
std::size_t operator()(const QList<QVariant>& k) const
{
using std::size_t;
using std::hash;
using std::string;
size_t hash_num = 0;
Q_FOREACH(var, k) {
// Make hash of the primitive value of the QVariant
switch(var.type()) {
case QVariant::String : {
hash_num = hash_num^hash<string>(var.toString().toStdString());
break;
}
case QVariant::Char :
case QVariant::ULongLong :
case QVariant::UInt :
case QVariant::LongLong :
case QVariant::Int : {
hash_num = hash_num^hash<long long>(var.toLongLong());
break;
}
case QVariant::Double : {
hash_num = hash_num^hash<double>(var.toDouble());
break;
}
}
}
return hash_num;
}
};
}
Obviously, I don't like the whole switch
thing. It's pretty long and ugly code and does only account for the basic types. I'd rather make hash of the memory data allocated for the QVariant
's internal data. Or, even better - use some Qt's hashing method.
Is there a semi-reliable* way to hash any QVariant without converting it to primitive type?
*I understand that complex objects might be hiding behind QVariant, but cases where this would lead to collision are rare enough so I don't have to care.