mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-20 12:35:43 +08:00
refs #345 Extending CValueObjectStdTuple with policy classes to enable it to be used by classes which have different requirements.
This commit is contained in:
@@ -68,4 +68,49 @@
|
|||||||
* \brief Iterator classes for the containers.
|
* \brief Iterator classes for the containers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy
|
||||||
|
* \brief Policy classes for CValueObjectStdTuple.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::MetaType
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::Equals
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::LessThan
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::Compare
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::Hash
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::DBus
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::Json
|
||||||
|
* \copydoc BlackMisc::Policy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace BlackMisc::Policy::Private
|
||||||
|
* \private
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ namespace BlackMisc
|
|||||||
template <> class TupleConverter<T> : TupleConverterBase \
|
template <> class TupleConverter<T> : TupleConverterBase \
|
||||||
{ \
|
{ \
|
||||||
friend class T; \
|
friend class T; \
|
||||||
friend class BlackMisc::CValueObjectStdTuple<T>; \
|
template <class, class> friend class BlackMisc::CValueObjectStdTuple; \
|
||||||
|
friend class BlackMisc::Private::EncapsulationBreaker; \
|
||||||
static_assert(Private::HasEnabledTupleConversion<T>::value, \
|
static_assert(Private::HasEnabledTupleConversion<T>::value, \
|
||||||
"Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \
|
"Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \
|
||||||
static auto toTuple(const T &o) -> decltype(BlackMisc::tie MEMBERS) \
|
static auto toTuple(const T &o) -> decltype(BlackMisc::tie MEMBERS) \
|
||||||
@@ -120,7 +121,8 @@ namespace BlackMisc
|
|||||||
template <class... U> class TupleConverter<T<U...>> : TupleConverterBase \
|
template <class... U> class TupleConverter<T<U...>> : TupleConverterBase \
|
||||||
{ \
|
{ \
|
||||||
friend class T<U...>; \
|
friend class T<U...>; \
|
||||||
friend class BlackMisc::CValueObjectStdTuple<T<U...>>; \
|
template <class, class> friend class BlackMisc::CValueObjectStdTuple; \
|
||||||
|
friend class BlackMisc::Private::EncapsulationBreaker; \
|
||||||
static_assert(Private::HasEnabledTupleConversion<T<U...>>::value, \
|
static_assert(Private::HasEnabledTupleConversion<T<U...>>::value, \
|
||||||
"Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \
|
"Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \
|
||||||
static auto toTuple(const T<U...> &o) -> decltype(BlackMisc::tie MEMBERS) \
|
static auto toTuple(const T<U...> &o) -> decltype(BlackMisc::tie MEMBERS) \
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
class CValueObject;
|
class CValueObject;
|
||||||
|
template <class> class TupleConverter;
|
||||||
|
|
||||||
namespace Private
|
namespace Private
|
||||||
{
|
{
|
||||||
@@ -33,6 +34,17 @@ namespace BlackMisc
|
|||||||
// Inhibit doxygen warnings about missing documentation
|
// Inhibit doxygen warnings about missing documentation
|
||||||
//! \cond PRIVATE
|
//! \cond PRIVATE
|
||||||
|
|
||||||
|
// To allow CValueObjectStdTuple policy classes to use the tuple system
|
||||||
|
class EncapsulationBreaker
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
template <class T>
|
||||||
|
static auto toMetaTuple(T &o) -> decltype(TupleConverter<typename std::decay<T>::type>::toMetaTuple(o))
|
||||||
|
{
|
||||||
|
return TupleConverter<typename std::decay<T>::type>::toMetaTuple(o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Using SFINAE to help detect missing BLACK_ENABLE_TUPLE_CONVERSION macro in static_assert
|
// Using SFINAE to help detect missing BLACK_ENABLE_TUPLE_CONVERSION macro in static_assert
|
||||||
std::false_type hasEnabledTupleConversionHelper(...);
|
std::false_type hasEnabledTupleConversionHelper(...);
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
#include "blackmiscfreefunctions.h"
|
#include "blackmiscfreefunctions.h"
|
||||||
|
#include "valueobject_policy.h"
|
||||||
#include <QtDBus/QDBusMetaType>
|
#include <QtDBus/QDBusMetaType>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
@@ -271,29 +272,68 @@ namespace BlackMisc
|
|||||||
|
|
||||||
//! Parse from string, e.g. 100km/h
|
//! Parse from string, e.g. 100km/h
|
||||||
virtual void parseFromString(const QString &) { qFatal("Not implemented"); }
|
virtual void parseFromString(const QString &) { qFatal("Not implemented"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Default policy classes for use by CValueObjectStdTuple.
|
||||||
|
*
|
||||||
|
* The default policies are inherited from the policies of the base class. There is a specialization
|
||||||
|
* for the terminating case in which the base class is CValueObject.
|
||||||
|
*
|
||||||
|
* Specialize this template to use non-default policies for a particular derived class.
|
||||||
|
* Due to the void default template parameter, specializations can inherit from CValueObjectStdTuplePolicy<>
|
||||||
|
* so that only the policies which differ from the default need be specified.
|
||||||
|
* Policy classes which can be used are defined in namespace BlackMisc::Policy.
|
||||||
|
*/
|
||||||
|
template <class Derived = void> struct CValueObjectStdTuplePolicy
|
||||||
|
{
|
||||||
|
using MetaType = Policy::MetaType::Inherit; //!< Metatype policy
|
||||||
|
using Equals = Policy::Equals::Inherit; //!< Equals policy
|
||||||
|
using LessThan = Policy::LessThan::Inherit; //!< LessThan policy
|
||||||
|
using Compare = Policy::Compare::Inherit; //!< Compare policy
|
||||||
|
using Hash = Policy::Hash::Inherit; //!< Hash policy
|
||||||
|
using DBus = Policy::DBus::Inherit; //!< DBus policy
|
||||||
|
using Json = Policy::Json::Inherit; //!< JSON policy
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Default policy classes for use by CValueObjectStdTuple.
|
||||||
|
*
|
||||||
|
* Specialization for the terminating case in which the base class is CValueObject.
|
||||||
|
*/
|
||||||
|
template <> struct CValueObjectStdTuplePolicy<CValueObject>
|
||||||
|
{
|
||||||
|
using MetaType = Policy::MetaType::Default; //!< Metatype policy
|
||||||
|
using Equals = Policy::Equals::MetaTuple; //!< Equals policy
|
||||||
|
using LessThan = Policy::LessThan::MetaTuple; //!< Less than policy
|
||||||
|
using Compare = Policy::Compare::MetaTuple; //!< Compare policy
|
||||||
|
using Hash = Policy::Hash::MetaTuple; //!< Hash policy
|
||||||
|
using DBus = Policy::DBus::MetaTuple; //!< DBus policy
|
||||||
|
using Json = Policy::Json::MetaTuple; //!< JSon policy
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Standard implementation of CValueObject using meta tuple system.
|
* Standard implementation of CValueObject using meta tuple system.
|
||||||
*
|
*
|
||||||
|
* This uses policy-based design. Specialize the class template CValueObjectStdTuplePolicy
|
||||||
|
* to specify different policy classes.
|
||||||
|
*
|
||||||
* \tparam Derived The class which is inheriting from this one (CRTP).
|
* \tparam Derived The class which is inheriting from this one (CRTP).
|
||||||
* \tparam Base The class which this one shall inherit from (default is CValueObject,
|
* \tparam Base The class which this one shall inherit from (default is CValueObject,
|
||||||
* but this can be changed to create a deeper inheritance hierarchy).
|
* but this can be changed to create a deeper inheritance hierarchy).
|
||||||
*/
|
*/
|
||||||
template <class Derived, class Base = CValueObject> class CValueObjectStdTuple : public Base
|
template <class Derived, class Base = CValueObject> class CValueObjectStdTuple :
|
||||||
|
public Base,
|
||||||
|
private CValueObjectStdTuplePolicy<Derived>::Equals::template Ops<Derived, Base>,
|
||||||
|
private CValueObjectStdTuplePolicy<Derived>::LessThan::template Ops<Derived, Base>
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of<CValueObject, Base>::value, "Base must be derived from CValueObject");
|
static_assert(std::is_base_of<CValueObject, Base>::value, "Base must be derived from CValueObject");
|
||||||
|
|
||||||
friend bool operator ==(const Derived &a, const Derived &b)
|
using MetaTypePolicy = typename CValueObjectStdTuplePolicy<Derived>::MetaType;
|
||||||
{
|
using ComparePolicy = typename CValueObjectStdTuplePolicy<Derived>::Compare;
|
||||||
return equals(a, b);
|
using HashPolicy = typename CValueObjectStdTuplePolicy<Derived>::Hash;
|
||||||
}
|
using DBusPolicy = typename CValueObjectStdTuplePolicy<Derived>::DBus;
|
||||||
|
using JsonPolicy = typename CValueObjectStdTuplePolicy<Derived>::Json;
|
||||||
friend bool operator !=(const Derived &a, const Derived &b)
|
|
||||||
{
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Base class
|
//! Base class
|
||||||
@@ -302,13 +342,13 @@ namespace BlackMisc
|
|||||||
//! \copydoc CValueObject::getValueHash()
|
//! \copydoc CValueObject::getValueHash()
|
||||||
virtual uint getValueHash() const override
|
virtual uint getValueHash() const override
|
||||||
{
|
{
|
||||||
return qHash(TupleConverter<Derived>::toMetaTuple(*derived())) ^ Base::getValueHash();
|
return HashPolicy::hashImpl(*derived()) ^ Base::getValueHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \copydoc CValueObject::toJson
|
//! \copydoc CValueObject::toJson
|
||||||
virtual QJsonObject toJson() const override
|
virtual QJsonObject toJson() const override
|
||||||
{
|
{
|
||||||
QJsonObject json = BlackMisc::serializeJson(TupleConverter<Derived>::toMetaTuple(*derived()));
|
QJsonObject json = JsonPolicy::serializeImpl(*derived());
|
||||||
return Json::appendJsonObject(json, Base::toJson());
|
return Json::appendJsonObject(json, Base::toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +356,7 @@ namespace BlackMisc
|
|||||||
virtual void convertFromJson(const QJsonObject &json) override
|
virtual void convertFromJson(const QJsonObject &json) override
|
||||||
{
|
{
|
||||||
Base::convertFromJson(json);
|
Base::convertFromJson(json);
|
||||||
BlackMisc::deserializeJson(json, TupleConverter<Derived>::toMetaTuple(*derived()));
|
JsonPolicy::deserializeImpl(json, *derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \copydoc CValueObject::toQVariant()
|
//! \copydoc CValueObject::toQVariant()
|
||||||
@@ -334,8 +374,7 @@ namespace BlackMisc
|
|||||||
//! Register metadata
|
//! Register metadata
|
||||||
static void registerMetadata()
|
static void registerMetadata()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<Derived>();
|
MetaTypePolicy::template registerImpl<Derived>();
|
||||||
qDBusRegisterMetaType<Derived>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -371,7 +410,7 @@ namespace BlackMisc
|
|||||||
virtual int compareImpl(const CValueObject &other) const override
|
virtual int compareImpl(const CValueObject &other) const override
|
||||||
{
|
{
|
||||||
const auto &otherDerived = static_cast<const Derived &>(other);
|
const auto &otherDerived = static_cast<const Derived &>(other);
|
||||||
int result = compare(TupleConverter<Derived>::toMetaTuple(*derived()), TupleConverter<Derived>::toMetaTuple(otherDerived));
|
int result = ComparePolicy::compareImpl(*derived(), otherDerived);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
return Base::compareImpl(other);
|
return Base::compareImpl(other);
|
||||||
}
|
}
|
||||||
@@ -380,28 +419,20 @@ namespace BlackMisc
|
|||||||
virtual void marshallToDbus(QDBusArgument &argument) const override
|
virtual void marshallToDbus(QDBusArgument &argument) const override
|
||||||
{
|
{
|
||||||
Base::marshallToDbus(argument);
|
Base::marshallToDbus(argument);
|
||||||
argument << TupleConverter<Derived>::toMetaTuple(*derived());
|
DBusPolicy::marshallImpl(argument, *derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \copydoc CValueObject::unmarshallFromDbus()
|
//! \copydoc CValueObject::unmarshallFromDbus()
|
||||||
virtual void unmarshallFromDbus(const QDBusArgument &argument) override
|
virtual void unmarshallFromDbus(const QDBusArgument &argument) override
|
||||||
{
|
{
|
||||||
Base::unmarshallFromDbus(argument);
|
Base::unmarshallFromDbus(argument);
|
||||||
argument >> TupleConverter<Derived>::toMetaTuple(*derived());
|
DBusPolicy::unmarshallImpl(argument, *derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||||
Derived *derived() { return static_cast<Derived *>(this); }
|
Derived *derived() { return static_cast<Derived *>(this); }
|
||||||
|
|
||||||
// Friend functions are implemented in terms of private static member functions, because
|
|
||||||
// friendship is not transitive: friends of CValueObjectStdTuple are not friends of TupleConverter.
|
|
||||||
static bool equals(const Derived &a, const Derived &b)
|
|
||||||
{
|
|
||||||
if (&a == &b) { return true; }
|
|
||||||
return TupleConverter<Derived>::toMetaTuple(a) == TupleConverter<Derived>::toMetaTuple(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallbacks in case Derived is not a registered meta type
|
// fallbacks in case Derived is not a registered meta type
|
||||||
template <class T> using IsRegisteredQMetaType = std::integral_constant<bool, QMetaTypeId<T>::Defined>;
|
template <class T> using IsRegisteredQMetaType = std::integral_constant<bool, QMetaTypeId<T>::Defined>;
|
||||||
static int maybeGetMetaTypeId(std::true_type) { return qMetaTypeId<Derived>(); }
|
static int maybeGetMetaTypeId(std::true_type) { return qMetaTypeId<Derived>(); }
|
||||||
|
|||||||
341
src/blackmisc/valueobject_policy.h
Normal file
341
src/blackmisc/valueobject_policy.h
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
/* Copyright (C) 2014
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_VALUEOBJECT_POLICY_H
|
||||||
|
#define BLACKMISC_VALUEOBJECT_POLICY_H
|
||||||
|
|
||||||
|
#include "tuple.h"
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QDBusMetaType>
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
template <class>
|
||||||
|
struct CValueObjectStdTuplePolicy;
|
||||||
|
|
||||||
|
namespace Policy
|
||||||
|
{
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
//! \private Alias for the policy of the base class of T
|
||||||
|
template <class T>
|
||||||
|
using Inherit = CValueObjectStdTuplePolicy<typename T::base_type>;
|
||||||
|
|
||||||
|
//! \private
|
||||||
|
using BlackMisc::Private::EncapsulationBreaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MetaType
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple default registerMetadata policy
|
||||||
|
struct Default
|
||||||
|
{
|
||||||
|
//! Register with QMetaType
|
||||||
|
template <class T, class...>
|
||||||
|
static void registerImpl() { qRegisterMetaType<T>(); qDBusRegisterMetaType<T>(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple registerMetadata policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! Register with QMetaType
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static void registerImpl() { Private::Inherit<Base>::MetaType::template registerImpl<T, typename Base::base_type>(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple registerMetadata policy which also registers QList<T>
|
||||||
|
struct DefaultAndQList
|
||||||
|
{
|
||||||
|
//! Register with QMetaType
|
||||||
|
template <class T, class...>
|
||||||
|
static void registerImpl() { Default::registerImpl<T>(); Default::registerImpl<QList<T>>(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Equals
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class which should not have an equals operator
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops {};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple equals operator policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class Base>
|
||||||
|
struct Ops : public CValueObjectStdTuplePolicy<Base>::Equals::template Ops<T, typename Base::base_type> {};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class whose meta tuple members can be compared by the equals operator
|
||||||
|
struct MetaTuple
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! Equals operator
|
||||||
|
friend bool operator ==(const T &a, const T &b) { return Private::EncapsulationBreaker::toMetaTuple(a) == Private::EncapsulationBreaker::toMetaTuple(b); }
|
||||||
|
|
||||||
|
//! Not equals operator
|
||||||
|
friend bool operator !=(const T &a, const T &b) { return !(a == b); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Some classes define their own custom equals operator; this policy provides a not equals operator which simply negates the result
|
||||||
|
struct OwnEquals
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops
|
||||||
|
{
|
||||||
|
//! Not equals operator; class T already has its own equals operator
|
||||||
|
friend bool operator !=(const T &a, const T &b) { return !(a == b); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace LessThan
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class which should not have a less than operator
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops {};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple less than operator policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class Base>
|
||||||
|
struct Ops : public CValueObjectStdTuplePolicy<Base>::LessThan::template Ops<T, typename Base::base_type> {};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class whose meta tuple members can be compared by the less than operator
|
||||||
|
struct MetaTuple
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! Less than operator
|
||||||
|
friend bool operator <(const T &a, const T &b) { return Private::EncapsulationBreaker::toMetaTuple(a) < Private::EncapsulationBreaker::toMetaTuple(b); }
|
||||||
|
|
||||||
|
//! Greater than operator
|
||||||
|
friend bool operator >(const T &a, const T &b) { return b < a; }
|
||||||
|
|
||||||
|
//! Greater or equal operator
|
||||||
|
friend bool operator >=(const T &a, const T &b) { return !(a < b); }
|
||||||
|
|
||||||
|
//! Less or equal operator
|
||||||
|
friend bool operator <=(const T &a, const T &b) { return !(b < a); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Some classes define their own custom less than operator; this policy implements other comparison operators in terms of this one
|
||||||
|
struct OwnLessThan
|
||||||
|
{
|
||||||
|
//! Inner class template which actually bestows the operators via the Barton-Nackman trick
|
||||||
|
template <class T, class>
|
||||||
|
struct Ops
|
||||||
|
{
|
||||||
|
//! Greater than operator; class T already has its own less than operator
|
||||||
|
friend bool operator >(const T &a, const T &b) { return b < a; }
|
||||||
|
|
||||||
|
//! Greater or equal operator; class T already has its own less than operator
|
||||||
|
friend bool operator >=(const T &a, const T &b) { return !(a < b); }
|
||||||
|
|
||||||
|
//! Less or equal operator; class T already has its own less than operator
|
||||||
|
friend bool operator <=(const T &a, const T &b) { return !(b < a); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Compare
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class without polymorphic comparison support
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! Policy implementation of CValueObject::compareImpl
|
||||||
|
template <class T, class...>
|
||||||
|
static bool compareImpl(const T &, const T &) { qFatal("Not implemented"); return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple polymorphic comparison policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! Policy implementation of CValueObject::compareImpl
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static bool compareImpl(const T &a, const T &b) { return Private::Inherit<Base>::Compare::template compareImpl<T, typename Base::base_type>(a, b); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class with default metatuple-based polymorphic comparison support
|
||||||
|
struct MetaTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! Policy implementation of CValueObject::compareImpl
|
||||||
|
template <class T, class...>
|
||||||
|
static bool compareImpl(const T &a, const T &b) { return compare(Private::EncapsulationBreaker::toMetaTuple(a), Private::EncapsulationBreaker::toMetaTuple(b)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class which implements its own custom poylymorphic comparison support
|
||||||
|
struct Own
|
||||||
|
{
|
||||||
|
//! Policy implementation of CValueObject::compareImpl
|
||||||
|
template <class T, class...>
|
||||||
|
static bool compareImpl(const T &, const T &) { return 0; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Hash
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class without hashing support
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::getHashValue
|
||||||
|
template <class T, class...>
|
||||||
|
static uint hashImpl(const T &) { qFatal("Not implemented"); return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple hashing policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::getHashValue
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static uint hashImpl(const T &obj) { return Private::Inherit<Base>::Hash::template hashImpl<T, typename Base::base_type>(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class with default metatuple-based hashing support
|
||||||
|
struct MetaTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::getHashValue
|
||||||
|
template <class T, class...>
|
||||||
|
static uint hashImpl(const T &obj) { return qHash(Private::EncapsulationBreaker::toMetaTuple(obj)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class which implements its own custom hashing support
|
||||||
|
struct Own
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::getHashValue
|
||||||
|
template <class T, class...>
|
||||||
|
static uint hashImpl(const T &) { return 0; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DBus
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class without DBus marshalling support
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::marshallToDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void marshallImpl(QDBusArgument &, const T &) { qFatal("Not implemented"); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::CValueObject::unmarshallFromDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void unmarshallImpl(const QDBusArgument &, T &) { qFatal("Not implemented"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple marshalling policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::marshallToDbus
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static void marshallImpl(QDBusArgument &arg, const T &obj) { Private::Inherit<Base>::DBus::template marshallImpl<T, typename Base::base_type>(arg, obj); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::CValueObject::unmarshallFromDbus
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static void unmarshallImpl(const QDBusArgument &arg, T &obj) { return Private::Inherit<Base>::DBus::template unmarshallImpl<T, typename Base::base_type>(arg, obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class with default metatuple-based DBus marshalling support
|
||||||
|
struct MetaTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::marshallToDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void marshallImpl(QDBusArgument &arg, const T &obj) { arg << Private::EncapsulationBreaker::toMetaTuple(obj); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::CValueObject::unmarshallFromDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void unmarshallImpl(const QDBusArgument &arg, T &obj) { arg >> Private::EncapsulationBreaker::toMetaTuple(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class which implements its own custom DBus marshalling support
|
||||||
|
struct Own
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::CValueObject::marshallToDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void marshallImpl(QDBusArgument &, const T &) {}
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::CValueObject::unmarshallFromDbus
|
||||||
|
template <class T, class...>
|
||||||
|
static void unmarshallImpl(const QDBusArgument &, T &) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Json
|
||||||
|
{
|
||||||
|
//! CValueObjectStdTuple policy for a class without JSON support
|
||||||
|
struct None
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::serializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static QJsonObject serializeImpl(const T &) { qFatal("Not implemented"); return {}; }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::deserializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static void deserializeImpl(const QJsonObject &, T &) { qFatal("Not implemented"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple JSON policy which inherits the policy of the base class
|
||||||
|
struct Inherit
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::serializeJson
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static QJsonObject serializeImpl(const T &obj) { return Private::Inherit<Base>::Json::template serializeImpl<T, typename Base::base_type>(obj); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::deserializeJson
|
||||||
|
template <class T, class Base = T>
|
||||||
|
static void deserializeImpl(const QJsonObject &json, T &obj) { Private::Inherit<Base>::Json::template deserializeImpl<T, typename Base::base_type>(json, obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class with default metatuple-based JSON support
|
||||||
|
struct MetaTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::serializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static QJsonObject serializeImpl(const T &obj) { return BlackMisc::serializeJson(Private::EncapsulationBreaker::toMetaTuple(obj)); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::deserializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static void deserializeImpl(const QJsonObject &json, T &obj) { BlackMisc::deserializeJson(json, Private::EncapsulationBreaker::toMetaTuple(obj)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! CValueObjectStdTuple policy for a class which implements its own custom JSON support
|
||||||
|
struct Own
|
||||||
|
{
|
||||||
|
//! \copydoc BlackMisc::serializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static QJsonObject serializeImpl(const T &) { return {}; }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::deserializeJson
|
||||||
|
template <class T, class...>
|
||||||
|
static void deserializeImpl(const QJsonObject &, T &) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user