mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-28 20:25:34 +08:00
refs #628 Add mixins which use the metaclass system instead of the tuple system.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "range.h"
|
||||
#include "containerbase.h"
|
||||
#include "typetraits.h"
|
||||
#include "metaclass.h"
|
||||
#include <QHash>
|
||||
#include <utility>
|
||||
#include <initializer_list>
|
||||
@@ -47,6 +48,14 @@ namespace BlackMisc
|
||||
struct DefaultType { static_assert(std::is_void<Key>::value, "Key does not support either QHash or QMap"); };
|
||||
};
|
||||
|
||||
// Work around MSVC2015 bug affecting generic lambda
|
||||
struct Hasher
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(const T &object) { m_hash ^= qHash(object); }
|
||||
uint &m_hash;
|
||||
};
|
||||
|
||||
//! \endcond
|
||||
} // namespace Private
|
||||
|
||||
@@ -475,6 +484,35 @@ namespace BlackMisc
|
||||
static uint baseHash(const void *) { return 0; }
|
||||
static uint baseHash(const CEmpty *) { return 0; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* CRTP class template from which a derived class can inherit common methods dealing with hashing instances by metaclass.
|
||||
*
|
||||
* \tparam Derived Must be registered with BLACK_DECLARE_TUPLE_CONVERSION.
|
||||
*/
|
||||
template <class Derived>
|
||||
class HashByMetaClass
|
||||
{
|
||||
public:
|
||||
//! qHash overload, needed for storing value in a QSet.
|
||||
friend uint qHash(const Derived &value, uint seed = 0)
|
||||
{
|
||||
return ::qHash(hashImpl(value), seed);
|
||||
}
|
||||
|
||||
private:
|
||||
static uint hashImpl(const Derived &value)
|
||||
{
|
||||
uint hash = baseHash(static_cast<const BaseOfT<Derived> *>(&value));
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForHashing>());
|
||||
meta.forEachMember(value, Private::Hasher { hash });
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <typename T> static uint baseHash(const T *base) { return qHash(*base); }
|
||||
static uint baseHash(const void *) { return 0; }
|
||||
static uint baseHash(const CEmpty *) { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user