refs #584 Moved hash related stuff to dictionary.h

This also means moving Mixin::Icon from CContainerBase one step down the inheritance hierarchy
to resolve what would otherwise have been a circular include dependency.
This commit is contained in:
Mathew Sutcliffe
2016-02-08 00:29:08 +00:00
parent c7a0aa2fb4
commit 3bdcd7e386
12 changed files with 100 additions and 107 deletions

View File

@@ -8,67 +8,8 @@
*/
#include "blackmiscfreefunctions.h"
#include "math/math.h"
#include "geo/geo.h"
#include "audio/audio.h"
#include "input/input.h"
#include "propertyindexlist.h"
#include "propertyindexvariantmap.h"
#include "namevariantpairlist.h"
#include "variantlist.h"
#include "variantmap.h"
#include "valuecache.h"
#include "rgbcolor.h"
#include "countrylist.h"
#include "statusmessagelist.h"
#include "pixmap.h"
#include "iconlist.h"
#include "identifierlist.h"
#include "logpattern.h"
#include <QtNetwork/QHostInfo>
#include <QProcessEnvironment>
#include <QSysInfo>
#include <QProcess>
#include <QBuffer>
void BlackMisc::initResources()
{
initBlackMiscResources();
}
uint BlackMisc::calculateHash(const QList<uint> &values, const char *className)
{
// http://stackoverflow.com/questions/113511/hash-code-implementation/113600#113600
if (values.isEmpty()) return 0;
uint hash = values.first();
for (int i = 1; i < values.size(); i++)
{
hash = 37 * hash + values.at(i);
}
// same values, but different class?
if (className)
{
hash = 37 * hash + qHash(QString(className));
}
return hash;
}
uint BlackMisc::calculateHash(const QList<int> &values, const char *className)
{
QList<uint> list;
uint s = 0;
foreach(int i, values)
{
if (i >= 0)
{
list.append(static_cast<uint>(i));
}
else
{
list.append(static_cast<uint>(i));
list.append(s++);
}
}
return calculateHash(list, className);
}

View File

@@ -38,45 +38,6 @@ namespace BlackMisc
//! Init resources
BLACKMISC_EXPORT void initResources();
namespace Mixin
{
/*!
* CRTP class template from which a derived class can inherit common methods dealing with hashing instances by metatuple.
*
* \tparam Derived Must be registered with BLACK_DECLARE_TUPLE_CONVERSION.
*/
template <class Derived>
class HashByTuple : private Private::EncapsulationBreaker
{
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)
{
return BlackMisc::qHash(toMetaTuple(value)) ^ baseHash(static_cast<const BaseOfT<Derived> *>(&value));
}
template <typename T> static uint baseHash(const T *base) { return qHash(*base); }
static uint baseHash(const void *) { return 0; }
};
} // Mixin
/*!
* \brief Calculate a single hash value based on a list of individual hash values
* \param values
* \param className add a hash value for class name on top
* \return
*/
BLACKMISC_EXPORT uint calculateHash(const QList<uint> &values, const char *className);
//! Hash value, but with int list
BLACKMISC_EXPORT uint calculateHash(const QList<int> &values, const char *className);
//! Own implementation of std::make_unique, a C++14 feature not provided by GCC in C++11 mode
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args &&... args)

View File

@@ -14,6 +14,7 @@
#include "iterator.h"
#include "containerbase.h"
#include "icon.h"
#include <QScopedPointer>
#include <algorithm>
#include <type_traits>
@@ -55,7 +56,9 @@ namespace BlackMisc
* Can take any suitable container class as its implementation at runtime.
*/
template <class T>
class CCollection : public CContainerBase<CCollection, T, Iterators::ConstForwardIterator<T>>
class CCollection :
public CContainerBase<CCollection, T, Iterators::ConstForwardIterator<T>>,
public Mixin::Icon<CCollection<T>>
{
public:
//! \brief STL compatibility

View File

@@ -18,7 +18,6 @@
#include "json.h"
#include "variant.h"
#include "dbus.h"
#include "icon.h"
#include <algorithm>
#include <QStringList>
@@ -56,8 +55,7 @@ namespace BlackMisc
public Mixin::MetaType<C<T>>,
public Mixin::DBusOperators<C<T>>,
public Mixin::JsonOperators<C<T>>,
public Mixin::String<C<T>>,
public Mixin::Icon<C<T>>
public Mixin::String<C<T>>
{
public:

View File

@@ -0,0 +1,47 @@
/* Copyright (C) 2016
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "dictionary.h"
uint BlackMisc::calculateHash(const QList<uint> &values, const char *className)
{
// http://stackoverflow.com/questions/113511/hash-code-implementation/113600#113600
if (values.isEmpty()) return 0;
uint hash = values.first();
for (int i = 1; i < values.size(); i++)
{
hash = 37 * hash + values.at(i);
}
// same values, but different class?
if (className)
{
hash = 37 * hash + qHash(QString(className));
}
return hash;
}
uint BlackMisc::calculateHash(const QList<int> &values, const char *className)
{
QList<uint> list;
uint s = 0;
foreach(int i, values)
{
if (i >= 0)
{
list.append(static_cast<uint>(i));
}
else
{
list.append(static_cast<uint>(i));
list.append(s++);
}
}
return calculateHash(list, className);
}

View File

@@ -468,6 +468,45 @@ namespace BlackMisc
}
}
namespace Mixin
{
/*!
* CRTP class template from which a derived class can inherit common methods dealing with hashing instances by metatuple.
*
* \tparam Derived Must be registered with BLACK_DECLARE_TUPLE_CONVERSION.
*/
template <class Derived>
class HashByTuple : private Private::EncapsulationBreaker
{
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)
{
return BlackMisc::qHash(toMetaTuple(value)) ^ baseHash(static_cast<const BaseOfT<Derived> *>(&value));
}
template <typename T> static uint baseHash(const T *base) { return qHash(*base); }
static uint baseHash(const void *) { return 0; }
};
}
/*!
* \brief Calculate a single hash value based on a list of individual hash values
* \param values
* \param className add a hash value for class name on top
* \return
*/
BLACKMISC_EXPORT uint calculateHash(const QList<uint> &values, const char *className);
//! Hash value, but with int list
BLACKMISC_EXPORT uint calculateHash(const QList<int> &values, const char *className);
} // namespace BlackMisc
#endif // BLACKMISC_DICTIONARY_H

View File

@@ -17,6 +17,7 @@
#include "variant.h"
#include "tuple.h"
#include "inheritancetraits.h"
#include "dictionary.h"
#include <QIcon>
namespace BlackMisc

View File

@@ -9,7 +9,7 @@
#include "blackmisc/pq/pq.h"
#include "blackmisc/comparefunctions.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/dictionary.h"
#include <QCoreApplication>
namespace BlackMisc

View File

@@ -13,7 +13,7 @@
#define BLACKMISC_PROPERTYINDEX_H
#include "blackmiscexport.h"
#include "blackmiscfreefunctions.h"
#include "dictionary.h"
#include "stringutils.h"
#include "variant.h"
#include "dbus.h"

View File

@@ -9,7 +9,7 @@
#include "propertyindexvariantmap.h"
#include "propertyindexlist.h"
#include "blackmiscfreefunctions.h"
#include "dictionary.h"
namespace BlackMisc
{

View File

@@ -14,6 +14,7 @@
#include "iterator.h"
#include "containerbase.h"
#include "icon.h"
#include <QScopedPointer>
#include <algorithm>
#include <type_traits>
@@ -31,7 +32,9 @@ namespace BlackMisc
* Can take any suitable container class as its implementation at runtime.
*/
template <class T>
class CSequence : public CContainerBase<CSequence, T, Iterators::ConstBidirectionalIterator<T>>
class CSequence :
public CContainerBase<CSequence, T, Iterators::ConstBidirectionalIterator<T>>,
public Mixin::Icon<CSequence<T>>
{
public:
//! \brief STL compatibility

View File

@@ -20,7 +20,7 @@
#include "variant.h"
#include "propertyindexvariantmap.h"
#include "iconlist.h"
#include "blackmiscfreefunctions.h"
#include "dictionary.h"
#include "stringutils.h"
#include <QtDBus/QDBusMetaType>
#include <QString>