refs #413 All value classes which had custom policies shall inherit from mixins instead.

This commit is contained in:
Mathew Sutcliffe
2015-05-03 23:34:06 +01:00
parent 9becc1c666
commit 36a2e1a2bb
38 changed files with 658 additions and 664 deletions

View File

@@ -18,33 +18,33 @@
namespace BlackMisc
{
namespace Aviation { class CAdfSystem; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CAdfSystem> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
using Equals = Policy::Equals::None;
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::Own;
};
namespace Aviation
{
//! ADF system ("for NDBs")
class BLACKMISC_EXPORT CAdfSystem : public CValueObject<CAdfSystem, CModulator<CAdfSystem>>
class BLACKMISC_EXPORT CAdfSystem :
public CModulator<CAdfSystem>,
public Mixin::MetaType<CAdfSystem>,
public Mixin::JsonOperators<CAdfSystem>
{
public:
//! Base type
using base_type = CModulator<CAdfSystem>;
using Mixin::MetaType<CAdfSystem>::registerMetadata;
using Mixin::MetaType<CAdfSystem>::getMetaTypeId;
using Mixin::MetaType<CAdfSystem>::isA;
using Mixin::MetaType<CAdfSystem>::toCVariant;
using Mixin::MetaType<CAdfSystem>::toQVariant;
using Mixin::MetaType<CAdfSystem>::convertFromCVariant;
using Mixin::MetaType<CAdfSystem>::convertFromQVariant;
//! Default constructor
CAdfSystem() = default;
//! Constructor
CAdfSystem(const QString &name, const PhysicalQuantities::CFrequency &activeFrequency, const PhysicalQuantities::CFrequency &standbyFrequency = CModulator::FrequencyNotSet()):
CValueObject(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency)
CModulator(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency)
{ }
//! Valid aviation frequency?

View File

@@ -19,7 +19,7 @@ namespace BlackMisc
namespace Aviation
{
CAltitude::CAltitude(const QString &altitudeAsString, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode) : CValueObject(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel)
CAltitude::CAltitude(const QString &altitudeAsString, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode) : CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel)
{
this->parseFromString(altitudeAsString, mode);
}

View File

@@ -17,27 +17,46 @@
namespace BlackMisc
{
namespace Aviation { class CAltitude; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CAltitude> : public CValueObjectPolicy<>
{
using Equals = Policy::Equals::MetaTuple;
using Compare = Policy::Compare::MetaTuple;
using Hash = Policy::Hash::MetaTuple;
using DBus = Policy::DBus::MetaTuple;
using Json = Policy::Json::MetaTuple;
};
namespace Aviation
{
/*!
* Altitude as used in aviation, can be AGL or MSL altitude
* \remarks Intentionally allowing +/- CLength , and >= / <= CLength.
*/
class BLACKMISC_EXPORT CAltitude : public CValueObject<CAltitude, PhysicalQuantities::CLength>
class BLACKMISC_EXPORT CAltitude :
public PhysicalQuantities::CLength,
public Mixin::MetaTypeAndQList<CAltitude>,
public Mixin::EqualsByTuple<CAltitude>,
public Mixin::CompareByTuple<CAltitude>,
public Mixin::HashByTuple<CAltitude>,
public Mixin::DBusByTuple<CAltitude>,
public Mixin::JsonByTuple<CAltitude>,
public Mixin::String<CAltitude>,
public Mixin::Icon<CAltitude>
{
public:
//! Base type
using base_type = PhysicalQuantities::CLength;
using Mixin::MetaTypeAndQList<CAltitude>::registerMetadata;
using Mixin::MetaTypeAndQList<CAltitude>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CAltitude>::isA;
using Mixin::MetaTypeAndQList<CAltitude>::toCVariant;
using Mixin::MetaTypeAndQList<CAltitude>::toQVariant;
using Mixin::MetaTypeAndQList<CAltitude>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CAltitude>::convertFromQVariant;
using Mixin::String<CAltitude>::toQString;
using Mixin::String<CAltitude>::toFormattedQString;
using Mixin::String<CAltitude>::toStdString;
using Mixin::String<CAltitude>::stringForStreaming;
using Mixin::DBusByTuple<CAltitude>::marshallToDbus;
using Mixin::DBusByTuple<CAltitude>::unmarshallFromDbus;
using Mixin::JsonByTuple<CAltitude>::toJson;
using Mixin::JsonByTuple<CAltitude>::convertFromJson;
using Mixin::Icon<CAltitude>::toIcon;
using Mixin::Icon<CAltitude>::toPixmap;
/*!
* Enum type to distinguish between MSL and AGL
*/
@@ -52,16 +71,16 @@ namespace BlackMisc
QString convertToQString(bool i18n = false) const;
//! Default constructor: 0 Altitude true
CAltitude() : CValueObject(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel) {}
CAltitude() : CLength(0, BlackMisc::PhysicalQuantities::CLengthUnit::m()), m_datum(MeanSeaLevel) {}
//! Constructor
CAltitude(double value, ReferenceDatum datum, const BlackMisc::PhysicalQuantities::CLengthUnit &unit) : CValueObject(value, unit), m_datum(datum) {}
CAltitude(double value, ReferenceDatum datum, const BlackMisc::PhysicalQuantities::CLengthUnit &unit) : CLength(value, unit), m_datum(datum) {}
//! Altitude as string
CAltitude(const QString &altitudeAsString, BlackMisc::PhysicalQuantities::CPqString::SeparatorMode mode = BlackMisc::PhysicalQuantities::CPqString::SeparatorsLocale);
//! Constructor by CLength
CAltitude(BlackMisc::PhysicalQuantities::CLength altitude, ReferenceDatum datum) : CValueObject(altitude), m_datum(datum) {}
CAltitude(BlackMisc::PhysicalQuantities::CLength altitude, ReferenceDatum datum) : CLength(altitude), m_datum(datum) {}
//! AGL Above ground level?
bool isAboveGroundLevel() const { return AboveGround == this->m_datum; }

View File

@@ -16,19 +16,18 @@
namespace BlackMisc
{
namespace Aviation { class CAvionicsBase; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CAvionicsBase> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::None;
};
namespace Aviation
{
//! Base class for avionics
class BLACKMISC_EXPORT CAvionicsBase : public CValueObject<CAvionicsBase>
class BLACKMISC_EXPORT CAvionicsBase :
public Mixin::HashByTuple<CAvionicsBase>,
public Mixin::DBusByTuple<CAvionicsBase>,
public Mixin::JsonByTuple<CAvionicsBase>,
public Mixin::EqualsByTuple<CAvionicsBase>,
public Mixin::LessThanByTuple<CAvionicsBase>,
public Mixin::CompareByTuple<CAvionicsBase>,
public Mixin::String<CAvionicsBase>
{
protected:
QString m_name; //!< name of the unit

View File

@@ -17,25 +17,27 @@
namespace BlackMisc
{
namespace Aviation { class CComSystem; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CComSystem> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::Own;
};
namespace Aviation
{
//! COM system (aka "radio")
class BLACKMISC_EXPORT CComSystem : public CValueObject<CComSystem, CModulator<CComSystem>>
class BLACKMISC_EXPORT CComSystem :
public CModulator<CComSystem>,
public Mixin::MetaType<CComSystem>,
public Mixin::JsonOperators<CComSystem>
{
public:
//! Base type
using base_type = CModulator<CComSystem>;
using Mixin::MetaType<CComSystem>::registerMetadata;
using Mixin::MetaType<CComSystem>::getMetaTypeId;
using Mixin::MetaType<CComSystem>::isA;
using Mixin::MetaType<CComSystem>::toCVariant;
using Mixin::MetaType<CComSystem>::toQVariant;
using Mixin::MetaType<CComSystem>::convertFromCVariant;
using Mixin::MetaType<CComSystem>::convertFromQVariant;
//! Channel spacing frequency
enum ChannelSpacing
{
@@ -56,7 +58,7 @@ namespace BlackMisc
//! Constructor
CComSystem(const QString &name, const BlackMisc::PhysicalQuantities::CFrequency &activeFrequency, const BlackMisc::PhysicalQuantities::CFrequency &standbyFrequency = CModulator::FrequencyNotSet()):
CValueObject(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency)
CModulator(name, activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency)
{ }
//! Set active frequency

View File

@@ -17,27 +17,43 @@
namespace BlackMisc
{
namespace Aviation { class CHeading; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CHeading> : public CValueObjectPolicy<>
{
using Equals = Policy::Equals::MetaTuple;
using Compare = Policy::Compare::MetaTuple;
using Hash = Policy::Hash::MetaTuple;
using DBus = Policy::DBus::MetaTuple;
using Json = Policy::Json::MetaTuple;
};
namespace Aviation
{
/*!
* \brief Heading as used in aviation, can be true or magnetic heading
* \remarks Intentionally allowing +/- CAngle , and >= / <= CAngle.
*/
class BLACKMISC_EXPORT CHeading : public CValueObject<CHeading, PhysicalQuantities::CAngle>
class BLACKMISC_EXPORT CHeading :
public PhysicalQuantities::CAngle,
public Mixin::MetaTypeAndQList<CHeading>,
public Mixin::EqualsByTuple<CHeading>,
public Mixin::CompareByTuple<CHeading>,
public Mixin::HashByTuple<CHeading>,
public Mixin::DBusByTuple<CHeading>,
public Mixin::JsonByTuple<CHeading>,
public Mixin::String<CHeading>
{
public:
//! Base type
using base_type = PhysicalQuantities::CAngle;
using Mixin::MetaTypeAndQList<CHeading>::registerMetadata;
using Mixin::MetaTypeAndQList<CHeading>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CHeading>::isA;
using Mixin::MetaTypeAndQList<CHeading>::toCVariant;
using Mixin::MetaTypeAndQList<CHeading>::toQVariant;
using Mixin::MetaTypeAndQList<CHeading>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CHeading>::convertFromQVariant;
using Mixin::String<CHeading>::toQString;
using Mixin::String<CHeading>::toFormattedQString;
using Mixin::String<CHeading>::toStdString;
using Mixin::String<CHeading>::stringForStreaming;
using Mixin::DBusByTuple<CHeading>::marshallToDbus;
using Mixin::DBusByTuple<CHeading>::unmarshallFromDbus;
using Mixin::JsonByTuple<CHeading>::toJson;
using Mixin::JsonByTuple<CHeading>::convertFromJson;
//! Enum type to distinguish between true north and magnetic north
enum ReferenceNorth
{
@@ -49,13 +65,13 @@ namespace BlackMisc
QString convertToQString(bool i18n = false) const;
//! \brief Default constructor: 0 heading true
CHeading() : CValueObject(0, BlackMisc::PhysicalQuantities::CAngleUnit::rad()), m_north(Magnetic) {}
CHeading() : CAngle(0, BlackMisc::PhysicalQuantities::CAngleUnit::rad()), m_north(Magnetic) {}
//! \brief Constructor
CHeading(double value, ReferenceNorth north, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CValueObject(value, unit), m_north(north) {}
CHeading(double value, ReferenceNorth north, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CAngle(value, unit), m_north(north) {}
//! \brief Constructor by CAngle
CHeading(CAngle heading, ReferenceNorth north) : CValueObject(heading), m_north(north) {}
CHeading(CAngle heading, ReferenceNorth north) : CAngle(heading), m_north(north) {}
//! \brief Magnetic heading?
bool isMagneticHeading() const { return Magnetic == this->m_north; }

View File

@@ -17,32 +17,33 @@
namespace BlackMisc
{
namespace Aviation { class CNavSystem; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CNavSystem> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
using Equals = Policy::Equals::None;
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::Own;
};
namespace Aviation
{
//! NAV system (radio navigation)
class BLACKMISC_EXPORT CNavSystem : public CValueObject<CNavSystem, CModulator<CNavSystem>>
class BLACKMISC_EXPORT CNavSystem :
public CModulator<CNavSystem>,
public Mixin::MetaType<CNavSystem>,
public Mixin::JsonOperators<CNavSystem>
{
public:
//! Base type
using base_type = CModulator<CNavSystem>;
using Mixin::MetaType<CNavSystem>::registerMetadata;
using Mixin::MetaType<CNavSystem>::getMetaTypeId;
using Mixin::MetaType<CNavSystem>::isA;
using Mixin::MetaType<CNavSystem>::toCVariant;
using Mixin::MetaType<CNavSystem>::toQVariant;
using Mixin::MetaType<CNavSystem>::convertFromCVariant;
using Mixin::MetaType<CNavSystem>::convertFromQVariant;
//! Default constructor
CNavSystem() = default;
//! Constructor
CNavSystem(const QString &name, const BlackMisc::PhysicalQuantities::CFrequency &activeFrequency, const BlackMisc::PhysicalQuantities::CFrequency &standbyFrequency):
CValueObject(name, activeFrequency, standbyFrequency)
CModulator(name, activeFrequency, standbyFrequency)
{ }
//! Set active frequency

View File

@@ -17,28 +17,44 @@
namespace BlackMisc
{
namespace Aviation { class CTrack; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CTrack> : public CValueObjectPolicy<>
{
using Equals = Policy::Equals::MetaTuple;
using Compare = Policy::Compare::MetaTuple;
using Hash = Policy::Hash::MetaTuple;
using DBus = Policy::DBus::MetaTuple;
using Json = Policy::Json::MetaTuple;
};
namespace Aviation
{
/*!
* \brief Track as used in aviation, can be true or magnetic Track
* \remarks Intentionally allowing +/- BlackMisc::PhysicalQuantities::CAngle ,
* and >= / <= CAngle.
*/
class BLACKMISC_EXPORT CTrack : public CValueObject<CTrack, PhysicalQuantities::CAngle>
class BLACKMISC_EXPORT CTrack :
public PhysicalQuantities::CAngle,
public Mixin::MetaTypeAndQList<CTrack>,
public Mixin::EqualsByTuple<CTrack>,
public Mixin::CompareByTuple<CTrack>,
public Mixin::HashByTuple<CTrack>,
public Mixin::DBusByTuple<CTrack>,
public Mixin::JsonByTuple<CTrack>,
public Mixin::String<CTrack>
{
public:
//! Base type
using base_type = PhysicalQuantities::CAngle;
using Mixin::MetaTypeAndQList<CTrack>::registerMetadata;
using Mixin::MetaTypeAndQList<CTrack>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CTrack>::isA;
using Mixin::MetaTypeAndQList<CTrack>::toCVariant;
using Mixin::MetaTypeAndQList<CTrack>::toQVariant;
using Mixin::MetaTypeAndQList<CTrack>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CTrack>::convertFromQVariant;
using Mixin::String<CTrack>::toQString;
using Mixin::String<CTrack>::toFormattedQString;
using Mixin::String<CTrack>::toStdString;
using Mixin::String<CTrack>::stringForStreaming;
using Mixin::DBusByTuple<CTrack>::marshallToDbus;
using Mixin::DBusByTuple<CTrack>::unmarshallFromDbus;
using Mixin::JsonByTuple<CTrack>::toJson;
using Mixin::JsonByTuple<CTrack>::convertFromJson;
/*!
* Enum type to distinguish between true north and magnetic north
*/
@@ -49,13 +65,13 @@ namespace BlackMisc
};
//! \brief Default constructor: 0 Track magnetic
CTrack() : CValueObject(0, BlackMisc::PhysicalQuantities::CAngleUnit::rad()), m_north(Magnetic) {}
CTrack() : CAngle(0, BlackMisc::PhysicalQuantities::CAngleUnit::rad()), m_north(Magnetic) {}
//! \brief Constructor
CTrack(double value, ReferenceNorth north, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CValueObject(value, unit), m_north(north) {}
CTrack(double value, ReferenceNorth north, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CAngle(value, unit), m_north(north) {}
//! \brief Constructor by CAngle
CTrack(BlackMisc::PhysicalQuantities::CAngle track, ReferenceNorth north) : CValueObject(track), m_north(north) {}
CTrack(BlackMisc::PhysicalQuantities::CAngle track, ReferenceNorth north) : CAngle(track), m_north(north) {}
//! \brief Magnetic Track?
bool isMagneticTrack() const

View File

@@ -18,14 +18,6 @@
namespace BlackMisc
{
namespace Aviation { class CTransponder; }
//! \private
template <> struct CValueObjectPolicy<Aviation::CTransponder> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
};
namespace Aviation
{
//! Transponder

View File

@@ -18,7 +18,6 @@
*/
void BlackMisc::PhysicalQuantities::registerMetadata()
{
CMeasurementUnit::registerMetadata();
CAcceleration::registerMetadata();
CAccelerationUnit::registerMetadata();
CAngle::registerMetadata();

View File

@@ -42,22 +42,18 @@ namespace BlackMisc
static QString stringify(QString str, bool /*i18n*/) { return str; }
};
// forward declaration
template <template <class> class C, class T, class CIt>
class CContainerBase;
//! \private
template <template <class> class C, class T, class CIt>
struct CValueObjectPolicy<CContainerBase<C, T, CIt>> : public CValueObjectLegacy
{
using MetaType = Policy::MetaType::None;
};
/*!
* \brief Base class for CCollection and CSequence adding mutating operations and CValueObject facility on top of CRangeBase.
*/
template <template <class> class C, class T, class CIt>
class CContainerBase : public CValueObject<CContainerBase<C, T, CIt>>, public CRangeBase<C<T>, CIt>
class CContainerBase :
public CRangeBase<C<T>, CIt>,
public Mixin::MetaType<C<T>>,
public Mixin::DBusOperators<C<T>>,
public Mixin::JsonOperators<C<T>>,
public Mixin::String<C<T>>,
public Mixin::Index<C<T>>,
public Mixin::Icon<C<T>>
{
public:
@@ -112,12 +108,6 @@ namespace BlackMisc
}
public:
//! \copydoc BlackMisc::CValueObject::toQVariant
QVariant toQVariant() const { return QVariant::fromValue(derived()); }
//! \copydoc CValueObject::convertFromQVariant
void convertFromQVariant(const QVariant &variant) { BlackMisc::setFromQVariant< C<T> >(&derived(), variant); }
//! Simplifies composition, returns 0 for performance
friend uint qHash(const C<T> &) { return 0; }

View File

@@ -74,18 +74,12 @@ namespace BlackMisc
struct AssociativityTraits : public Private::AssociativityTraits<Private::ADL::SupportsQHash<Key>::value, Private::ADL::SupportsQMap<Key>::value>
{};
// forward declaration
template<class Key, class Value, template <class...> class Impl = AssociativityTraits<Key>::template DefaultType>
class CDictionary;
//! \private
template <class Key, class Value, template <class...> class Impl>
struct CValueObjectPolicy<CDictionary<Key, Value, Impl>> : public CValueObjectLegacy
{};
//! Associative container with value semantics, chooses a sensible default implementation container type
template<class Key, class Value, template <class...> class Impl /*= AssociativityTraits<Key>::template DefaultType*/>
class CDictionary : public CValueObject<CDictionary<Key, Value, Impl>>
template<class Key, class Value, template <class...> class Impl = AssociativityTraits<Key>::template DefaultType>
class CDictionary :
public Mixin::DBusOperators<CDictionary<Key, Value, Impl>>,
public Mixin::JsonOperators<CDictionary<Key, Value, Impl>>,
public Mixin::String<CDictionary<Key, Value, Impl>>
{
//! \copydoc BlackMisc::CValueObject::compare
friend int compare(const CDictionary &a, const CDictionary &b)

View File

@@ -55,7 +55,7 @@ namespace BlackMisc
}
}
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Event::CEventHotkeyFunction, (o.m_eventOriginator, o.m_hotkeyFunc))
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Event::CEventHotkeyFunction, (attr(o.m_eventOriginator, flags<DisabledForJson>()), o.m_hotkeyFunc))
Q_DECLARE_METATYPE(BlackMisc::Event::CEventHotkeyFunction)
#endif // BLACKMISC_EVENTHOTKEY_H

View File

@@ -20,19 +20,20 @@
namespace BlackMisc
{
namespace Event { class COriginator; }
//! \private
template <> struct CValueObjectPolicy<Event::COriginator> : public CValueObjectPolicy<>
{
using Json = Policy::Json::None;
};
namespace Event
{
//! Value object encapsulating information about the originiator
class BLACKMISC_EXPORT COriginator : public CValueObject<COriginator>
class BLACKMISC_EXPORT COriginator :
public Mixin::MetaType<COriginator>,
public Mixin::HashByTuple<COriginator>,
public Mixin::DBusByTuple<COriginator>,
public Mixin::EqualsByTuple<COriginator>,
public Mixin::LessThanByTuple<COriginator>,
public Mixin::CompareByTuple<COriginator>,
public Mixin::Index<COriginator>,
public Mixin::String<COriginator>,
public Mixin::Icon<COriginator>
{
public:
//! Default constructor.

View File

@@ -113,17 +113,17 @@ namespace BlackMisc
template <class LATorLON>
CEarthAngle<LATorLON>::CEarthAngle()
: CEarthAngle::CValueObject(0.0, BlackMisc::PhysicalQuantities::CAngleUnit::deg())
: PhysicalQuantities::CAngle(0.0, BlackMisc::PhysicalQuantities::CAngleUnit::deg())
{ }
template <class LATorLON>
CEarthAngle<LATorLON>::CEarthAngle(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit)
: CEarthAngle::CValueObject(value, unit)
: PhysicalQuantities::CAngle(value, unit)
{ }
template <class LATorLON>
CEarthAngle<LATorLON>::CEarthAngle(const BlackMisc::PhysicalQuantities::CAngle &angle)
: CEarthAngle::CValueObject(angle)
: PhysicalQuantities::CAngle(angle)
{ }
template <class LATorLON>

View File

@@ -16,14 +16,6 @@
namespace BlackMisc
{
namespace Geo { template <class> class CEarthAngle; }
//! \private
template <class LATorLON> struct CValueObjectPolicy<Geo::CEarthAngle<LATorLON>> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::None;
};
namespace Geo
{
@@ -33,7 +25,7 @@ namespace BlackMisc
/*!
* Base class for latitude / longitude
*/
template <class LATorLON> class CEarthAngle : public CValueObject<CEarthAngle<LATorLON>, PhysicalQuantities::CAngle>
template <class LATorLON> class CEarthAngle : public PhysicalQuantities::CAngle
{
public:
//! Plus operator +=

View File

@@ -18,20 +18,32 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<Geo::CLatitude> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
};
namespace Geo
{
//! Latitude
class BLACKMISC_EXPORT CLatitude : public CValueObject<CLatitude, CEarthAngle<CLatitude>>
class BLACKMISC_EXPORT CLatitude :
public CEarthAngle<CLatitude>,
public Mixin::MetaType<CLatitude>,
public Mixin::String<CLatitude>,
public Mixin::DBusOperators<CLatitude>
{
public:
//! Base type
using base_type = CEarthAngle<CLatitude>;
using Mixin::MetaType<CLatitude>::registerMetadata;
using Mixin::MetaType<CLatitude>::getMetaTypeId;
using Mixin::MetaType<CLatitude>::isA;
using Mixin::MetaType<CLatitude>::toCVariant;
using Mixin::MetaType<CLatitude>::toQVariant;
using Mixin::MetaType<CLatitude>::convertFromCVariant;
using Mixin::MetaType<CLatitude>::convertFromQVariant;
using Mixin::String<CLatitude>::toQString;
using Mixin::String<CLatitude>::toFormattedQString;
using Mixin::String<CLatitude>::toStdString;
using Mixin::String<CLatitude>::stringForStreaming;
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const
{
@@ -47,10 +59,10 @@ namespace BlackMisc
CLatitude() = default;
//! Constructor
explicit CLatitude(const BlackMisc::PhysicalQuantities::CAngle &angle) : CValueObject(angle) {}
explicit CLatitude(const BlackMisc::PhysicalQuantities::CAngle &angle) : CEarthAngle(angle) {}
//! Init by double value
CLatitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CValueObject(value, unit) {}
CLatitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CEarthAngle(value, unit) {}
};
}

View File

@@ -17,20 +17,32 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<Geo::CLongitude> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::Default;
};
namespace Geo
{
//! Longitude
class BLACKMISC_EXPORT CLongitude : public CValueObject<CLongitude, CEarthAngle<CLongitude>>
class BLACKMISC_EXPORT CLongitude :
public CEarthAngle<CLongitude>,
public Mixin::MetaType<CLongitude>,
public Mixin::String<CLongitude>,
public Mixin::DBusOperators<CLongitude>
{
public:
//! Base type
using base_type = CEarthAngle<CLongitude>;
using Mixin::MetaType<CLongitude>::registerMetadata;
using Mixin::MetaType<CLongitude>::getMetaTypeId;
using Mixin::MetaType<CLongitude>::isA;
using Mixin::MetaType<CLongitude>::toCVariant;
using Mixin::MetaType<CLongitude>::toQVariant;
using Mixin::MetaType<CLongitude>::convertFromCVariant;
using Mixin::MetaType<CLongitude>::convertFromQVariant;
using Mixin::String<CLongitude>::toQString;
using Mixin::String<CLongitude>::toFormattedQString;
using Mixin::String<CLongitude>::toStdString;
using Mixin::String<CLongitude>::stringForStreaming;
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const
{
@@ -44,10 +56,10 @@ namespace BlackMisc
CLongitude() = default;
//! Constructor
explicit CLongitude(const BlackMisc::PhysicalQuantities::CAngle &angle) : CValueObject(angle) {}
explicit CLongitude(const BlackMisc::PhysicalQuantities::CAngle &angle) : CEarthAngle(angle) {}
//! Init by double value
CLongitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CValueObject(value, unit) {}
CLongitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit) : CEarthAngle(value, unit) {}
};
}

View File

@@ -21,22 +21,16 @@ namespace BlackMisc
class CLogCategory;
class CLogCategoryList;
class CLogPattern;
//! \private
template <> struct CValueObjectPolicy<CLogPattern> : public CValueObjectPolicy<>
{
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::None;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::None;
};
/*!
* Value class for matching log messages based on their categories.
*/
class BLACKMISC_EXPORT CLogPattern : public CValueObject<CLogPattern>
class BLACKMISC_EXPORT CLogPattern :
public Mixin::MetaType<CLogPattern>,
public Mixin::EqualsByTuple<CLogPattern>,
public Mixin::DBusOperators<CLogPattern>,
public Mixin::Index<CLogPattern>,
public Mixin::String<CLogPattern>,
public Mixin::Icon<CLogPattern>
{
public:
//! Default constructed CLogPattern will match any message.

View File

@@ -145,7 +145,7 @@ namespace BlackMisc
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CClient, (
o.m_user,
o.m_model,
attr(o.m_capabilities, flags<DisabledForComparison>()),
attr(o.m_capabilities, flags<DisabledForComparison | DisabledForJson>()),
o.m_server,
o.m_voiceCapabilities
))

View File

@@ -17,28 +17,21 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CAcceleration> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
//! Acceleration
class BLACKMISC_EXPORT CAcceleration : public CValueObject<CAcceleration, CPhysicalQuantity<CAccelerationUnit, CAcceleration>>
class BLACKMISC_EXPORT CAcceleration : public CPhysicalQuantity<CAccelerationUnit, CAcceleration>
{
public:
//! Default constructor
CAcceleration() : CValueObject(0, CAccelerationUnit::defaultUnit()) {}
CAcceleration() : CPhysicalQuantity(0, CAccelerationUnit::defaultUnit()) {}
//! Init by double value
CAcceleration(double value, const CAccelerationUnit &unit) : CValueObject(value, unit) {}
CAcceleration(double value, const CAccelerationUnit &unit) : CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CAcceleration(const QString &unitString) : CValueObject(unitString) {}
CAcceleration(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -18,34 +18,28 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CAngle> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
//! Physical unit angle (radians, degrees)
class BLACKMISC_EXPORT CAngle : public CValueObject<CAngle, CPhysicalQuantity<CAngleUnit, CAngle>>
class BLACKMISC_EXPORT CAngle : public CPhysicalQuantity<CAngleUnit, CAngle>
{
public:
//! Default constructor
CAngle() : CValueObject(0, CAngleUnit::defaultUnit()) {}
CAngle() : CPhysicalQuantity(0, CAngleUnit::defaultUnit()) {}
//! Init by double value
CAngle(double value, const CAngleUnit &unit): CValueObject(value, unit) {}
CAngle(double value, const CAngleUnit &unit): CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CAngle(const QString &unitString) : CValueObject(unitString) {}
CAngle(const QString &unitString) : CPhysicalQuantity(unitString) {}
/*!
* \brief Init as sexagesimal degrees, minutes, seconds
* The sign of all parameters must be the same, either all positive or all negative.
*/
CAngle(int degrees, int minutes, double seconds) :
CValueObject(
CPhysicalQuantity(
degrees + minutes / 100.0 + seconds / 10000.0,
CAngleUnit::sexagesimalDeg()) {}
@@ -54,7 +48,7 @@ namespace BlackMisc
* The sign of both parameters must be the same, either both positive or both negative.
*/
CAngle(int degrees, double minutes) :
CValueObject(
CPhysicalQuantity(
degrees + minutes / 100.0,
CAngleUnit::sexagesimalDegMin()) {}

View File

@@ -17,32 +17,26 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CFrequency> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Physical unit frequency
*/
class BLACKMISC_EXPORT CFrequency : public CValueObject<CFrequency, CPhysicalQuantity<CFrequencyUnit, CFrequency>>
class BLACKMISC_EXPORT CFrequency : public CPhysicalQuantity<CFrequencyUnit, CFrequency>
{
public:
//! Default constructor
CFrequency() : CValueObject(0, CFrequencyUnit::defaultUnit()) {}
CFrequency() : CPhysicalQuantity(0, CFrequencyUnit::defaultUnit()) {}
//! Init by double value
CFrequency(double value, const CFrequencyUnit &unit) : CValueObject(value, unit) {}
CFrequency(double value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit) {}
//! Init by int value converted to double
CFrequency(int value, const CFrequencyUnit &unit) : CFrequency(double(value), unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CFrequency(const QString &unitString) : CValueObject(unitString) {}
CFrequency(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}
}

View File

@@ -17,28 +17,21 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CLength> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
//! Physical unit length (length)
class BLACKMISC_EXPORT CLength : public CValueObject<CLength, CPhysicalQuantity<CLengthUnit, CLength>>
class BLACKMISC_EXPORT CLength : public CPhysicalQuantity<CLengthUnit, CLength>
{
public:
//! Default constructor
CLength() : CValueObject(0, CLengthUnit::defaultUnit()) {}
CLength() : CPhysicalQuantity(0, CLengthUnit::defaultUnit()) {}
//! Init by double value
CLength(double value, const CLengthUnit &unit) : CValueObject(value, unit) {}
CLength(double value, const CLengthUnit &unit) : CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CLength(const QString &unitString) : CValueObject(unitString) {}
CLength(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -17,30 +17,23 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CMass> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Mass
*/
class BLACKMISC_EXPORT CMass : public CValueObject<CMass, CPhysicalQuantity<CMassUnit, CMass>>
class BLACKMISC_EXPORT CMass : public CPhysicalQuantity<CMassUnit, CMass>
{
public:
//! Default constructor
CMass() : CValueObject(0, CMassUnit::defaultUnit()) {}
CMass() : CPhysicalQuantity(0, CMassUnit::defaultUnit()) {}
//! Init by double value
CMass(double value, const CMassUnit &unit) : CValueObject(value, unit) {}
CMass(double value, const CMassUnit &unit) : CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CMass(const QString &unitString) : CValueObject(unitString) {}
CMass(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -28,26 +28,15 @@
namespace BlackMisc
{
namespace PhysicalQuantities { class CMeasurementUnit; }
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CMeasurementUnit> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
using Equals = Policy::Equals::None;
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::None;
};
namespace PhysicalQuantities
{
/*!
* Base class for all units, such as meter, hertz.
*/
class BLACKMISC_EXPORT CMeasurementUnit : public CValueObject<CMeasurementUnit>
class BLACKMISC_EXPORT CMeasurementUnit :
public Mixin::String<CMeasurementUnit>,
public Mixin::Icon<CMeasurementUnit>
{
protected:
/*!
@@ -387,6 +376,4 @@ namespace BlackMisc
}
}
Q_DECLARE_METATYPE(BlackMisc::PhysicalQuantities::CMeasurementUnit)
#endif // guard

View File

@@ -376,7 +376,7 @@ namespace BlackMisc
case IndexValueRounded6DigitsWithUnit:
return CVariant::from(this->valueRoundedWithUnit(6));
default:
return CValueObject<CPhysicalQuantity<MU, PQ>>::propertyByIndex(index);
return Mixin::Index<CPhysicalQuantity<MU, PQ>>::propertyByIndex(index);
}
}
@@ -405,7 +405,7 @@ namespace BlackMisc
this->parseFromString(variant.toQString());
break;
default:
CValueObject<CPhysicalQuantity<MU, PQ>>::setPropertyByIndex(variant, index);
Mixin::Index<CPhysicalQuantity<MU, PQ>>::setPropertyByIndex(variant, index);
break;
}
}

View File

@@ -28,7 +28,7 @@ namespace BlackMisc
{
namespace PhysicalQuantities
{
template <class, class> class CPhysicalQuantity;
class CLength;
class CPressure;
class CFrequency;
@@ -38,26 +38,17 @@ namespace BlackMisc
class CTime;
class CPressure;
class CAcceleration;
}
//! \private
template <class MU, class PQ> struct CValueObjectPolicy<PhysicalQuantities::CPhysicalQuantity<MU, PQ>> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::None;
using Equals = Policy::Equals::None;
using LessThan = Policy::LessThan::None;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::Own;
};
namespace PhysicalQuantities
{
/*!
* A physical quantity such as "5m", "20s", "1500ft/s"
*/
template <class MU, class PQ> class CPhysicalQuantity : public CValueObject<CPhysicalQuantity<MU, PQ>>
template <class MU, class PQ> class CPhysicalQuantity :
public Mixin::DBusOperators<CPhysicalQuantity<MU, PQ>>,
public Mixin::JsonOperators<CPhysicalQuantity<MU, PQ>>,
public Mixin::Index<CPhysicalQuantity<MU, PQ>>,
public Mixin::MetaTypeAndQList<PQ>,
public Mixin::String<PQ>,
public Mixin::Icon<CPhysicalQuantity<MU, PQ>>
{
//! \copydoc CValueObject::compare
friend int compare(const PQ &a, const PQ &b) { return compareImpl(a, b); }

View File

@@ -17,30 +17,23 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CPressure> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Physical unit distance
*/
class BLACKMISC_EXPORT CPressure : public CValueObject<CPressure, CPhysicalQuantity<CPressureUnit, CPressure>>
class BLACKMISC_EXPORT CPressure : public CPhysicalQuantity<CPressureUnit, CPressure>
{
public:
//! Default constructor
CPressure() : CValueObject(0, CPressureUnit::defaultUnit()) {}
CPressure() : CPhysicalQuantity(0, CPressureUnit::defaultUnit()) {}
//! Init by double value
CPressure(double value, const CPressureUnit &unit) : CValueObject(value, unit) {}
CPressure(double value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CPressure(const QString &unitString) : CValueObject(unitString) {}
CPressure(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -17,30 +17,23 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CSpeed> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Speed class, e.g. "m/s", "NM/h", "km/h", "ft/s"
*/
class BLACKMISC_EXPORT CSpeed : public CValueObject<CSpeed, CPhysicalQuantity<CSpeedUnit, CSpeed>>
class BLACKMISC_EXPORT CSpeed : public CPhysicalQuantity<CSpeedUnit, CSpeed>
{
public:
//! Default constructor
CSpeed() : CValueObject(0, CSpeedUnit::defaultUnit()) {}
CSpeed() : CPhysicalQuantity(0, CSpeedUnit::defaultUnit()) {}
//! Init by double value
CSpeed(double value, const CSpeedUnit &unit) : CValueObject(value, unit) {}
CSpeed(double value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CSpeed(const QString &unitString) : CValueObject(unitString) {}
CSpeed(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -17,30 +17,23 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CTemperature> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Physical unit temperature
*/
class BLACKMISC_EXPORT CTemperature : public CValueObject<CTemperature, CPhysicalQuantity<CTemperatureUnit, CTemperature>>
class BLACKMISC_EXPORT CTemperature : public CPhysicalQuantity<CTemperatureUnit, CTemperature>
{
public:
//! Default constructor
CTemperature() : CValueObject(0, CTemperatureUnit::defaultUnit()) {}
CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::defaultUnit()) {}
//! Init by double value
CTemperature(double value, const CTemperatureUnit &unit): CValueObject(value, unit) {}
CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit) {}
//! \copydoc CPhysicalQuantity(const QString &unitString)
CTemperature(const QString &unitString) : CValueObject(unitString) {}
CTemperature(const QString &unitString) : CPhysicalQuantity(unitString) {}
};
}

View File

@@ -13,7 +13,7 @@ namespace BlackMisc
{
namespace PhysicalQuantities
{
CTime::CTime(int hours, int minutes, int seconds) : CValueObject(0, CTimeUnit::nullUnit())
CTime::CTime(int hours, int minutes, int seconds) : CPhysicalQuantity(0, CTimeUnit::nullUnit())
{
bool negative = (hours < 0);
double value = qAbs(hours) + minutes / 100.0 + seconds / 10000.0;
@@ -34,7 +34,7 @@ namespace BlackMisc
}
}
CTime::CTime(const QTime &time, bool negative) : CValueObject(0, CTimeUnit::nullUnit())
CTime::CTime(const QTime &time, bool negative) : CPhysicalQuantity(0, CTimeUnit::nullUnit())
{
CTime converted(time.hour(), time.minute(), time.second());
(*this) = converted;

View File

@@ -17,20 +17,13 @@
namespace BlackMisc
{
//! \private
template <> struct CValueObjectPolicy<PhysicalQuantities::CTime> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::DefaultAndQList;
};
namespace PhysicalQuantities
{
/*!
* Time class, e.g. "ms", "hour", "s", "day"
*/
class BLACKMISC_EXPORT CTime : public CValueObject<CTime, CPhysicalQuantity<CTimeUnit, CTime>>
class BLACKMISC_EXPORT CTime : public CPhysicalQuantity<CTimeUnit, CTime>
{
public:
//! Parts
@@ -42,10 +35,10 @@ namespace BlackMisc
};
//! Default constructor
CTime() : CValueObject(0, CTimeUnit::defaultUnit()) {}
CTime() : CPhysicalQuantity(0, CTimeUnit::defaultUnit()) {}
//! Init by double value
CTime(double value, const CTimeUnit &unit) : CValueObject(value, unit) {}
CTime(double value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit) {}
//! By hours, minutes, seconds
CTime(int hours, int minutes, int seconds = 0);
@@ -54,7 +47,7 @@ namespace BlackMisc
CTime(const QTime &time, bool negative = false);
//! \copydoc CPhysicalQuantity(const QString &unitString)
CTime(const QString &unitString) : CValueObject(0, CTimeUnit::nullUnit()) { this->parseFromString(unitString); }
CTime(const QString &unitString) : CPhysicalQuantity(0, CTimeUnit::nullUnit()) { this->parseFromString(unitString); }
//! From string hh:mm, or hh:mm:ss, or time units such as s, min
void parseFromString(const QString &time);

View File

@@ -35,17 +35,21 @@ namespace BlackMisc
{
//! Specialized class for distance units (meter, foot, nautical miles).
class BLACKMISC_EXPORT CLengthUnit : public CValueObject<CLengthUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CLengthUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CLengthUnit>,
public Mixin::DBusOperators<CLengthUnit>,
public Mixin::Index<CLengthUnit>
{
private:
template <class Converter>
CLengthUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
//! null constructor
CLengthUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
struct NauticalMilesToMeters { static double factor() { return 1852.0; } };
@@ -55,8 +59,19 @@ namespace BlackMisc
typedef One MetersToMeters;
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CLengthUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CLengthUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CLengthUnit>::isA;
using Mixin::MetaTypeAndQList<CLengthUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CLengthUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CLengthUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CLengthUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CLengthUnit() : CValueObject(defaultUnit()) {}
CLengthUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CLengthUnit &defaultUnit() { return m(); }
@@ -145,24 +160,39 @@ namespace BlackMisc
};
//! Specialized class for angles (degrees, radian).
class BLACKMISC_EXPORT CAngleUnit : public CValueObject<CAngleUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CAngleUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CAngleUnit>,
public Mixin::DBusOperators<CAngleUnit>,
public Mixin::Index<CAngleUnit>
{
private:
template <class Converter>
CAngleUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CAngleUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
struct RadiansToDegrees { static double factor() { return 180.0 / M_PI; } };
typedef One DegreesToDegrees;
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CAngleUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CAngleUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CAngleUnit>::isA;
using Mixin::MetaTypeAndQList<CAngleUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CAngleUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CAngleUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CAngleUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CAngleUnit() : CValueObject(defaultUnit()) {}
CAngleUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CAngleUnit &defaultUnit() { return deg(); }
@@ -235,23 +265,38 @@ namespace BlackMisc
};
//! Specialized class for frequency (hertz, mega hertz, kilo hertz).
class BLACKMISC_EXPORT CFrequencyUnit : public CValueObject<CFrequencyUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CFrequencyUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CFrequencyUnit>,
public Mixin::DBusOperators<CFrequencyUnit>,
public Mixin::Index<CFrequencyUnit>
{
private:
template <class Converter>
CFrequencyUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CFrequencyUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
typedef One HertzToHertz;
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::isA;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CFrequencyUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CFrequencyUnit() : CValueObject(defaultUnit()) {}
CFrequencyUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CFrequencyUnit &defaultUnit() { return Hz(); }
@@ -316,24 +361,39 @@ namespace BlackMisc
};
//! Specialized class for mass units (kg, lbs).
class BLACKMISC_EXPORT CMassUnit : public CValueObject<CMassUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CMassUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CMassUnit>,
public Mixin::DBusOperators<CMassUnit>,
public Mixin::Index<CMassUnit>
{
private:
template <class Converter>
CMassUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CMassUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
typedef Milli<One> GramsToKilograms;
struct PoundsToKilograms { static double factor() { return 0.45359237; } };
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CMassUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CMassUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CMassUnit>::isA;
using Mixin::MetaTypeAndQList<CMassUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CMassUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CMassUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CMassUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CMassUnit() : CValueObject(defaultUnit()) {}
CMassUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CMassUnit &defaultUnit() { return kg(); }
@@ -406,16 +466,20 @@ namespace BlackMisc
};
//! Specialized class for pressure (psi, hPa, bar).
class BLACKMISC_EXPORT CPressureUnit : public CValueObject<CPressureUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CPressureUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CPressureUnit>,
public Mixin::DBusOperators<CPressureUnit>,
public Mixin::Index<CPressureUnit>
{
private:
template <class Converter>
CPressureUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CPressureUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
typedef Centi<One> PascalsToHectopascals;
@@ -424,8 +488,19 @@ namespace BlackMisc
struct MillimetersToHectopascals { static double factor() { return 860.142806; } };
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CPressureUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CPressureUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CPressureUnit>::isA;
using Mixin::MetaTypeAndQList<CPressureUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CPressureUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CPressureUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CPressureUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CPressureUnit() : CValueObject(defaultUnit()) {}
CPressureUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CPressureUnit &defaultUnit() { return hPa(); }
@@ -513,16 +588,20 @@ namespace BlackMisc
};
//! Specialized class for temperatur units (kelvin, centidegree).
class BLACKMISC_EXPORT CTemperatureUnit : public CValueObject<CTemperatureUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CTemperatureUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CTemperatureUnit>,
public Mixin::DBusOperators<CTemperatureUnit>,
public Mixin::Index<CTemperatureUnit>
{
private:
template <class Converter>
CTemperatureUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CTemperatureUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
struct KelvinToCentigrade
@@ -537,8 +616,19 @@ namespace BlackMisc
};
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::isA;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CTemperatureUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CTemperatureUnit() : CValueObject(defaultUnit()) {}
CTemperatureUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CTemperatureUnit &defaultUnit() { return C(); }
@@ -595,16 +685,20 @@ namespace BlackMisc
};
//! Specialized class for speed units (m/s, ft/s, NM/h).
class BLACKMISC_EXPORT CSpeedUnit : public CValueObject<CSpeedUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CSpeedUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CSpeedUnit>,
public Mixin::DBusOperators<CSpeedUnit>,
public Mixin::Index<CSpeedUnit>
{
private:
template <class Converter>
CSpeedUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CSpeedUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
struct KnotsToMps { static double factor() { return 1852.0 / 3600.0; } };
@@ -613,9 +707,19 @@ namespace BlackMisc
struct FtPerMinToMps { static double factor() { return 0.3048 / 60.0; } };
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CSpeedUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CSpeedUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CSpeedUnit>::isA;
using Mixin::MetaTypeAndQList<CSpeedUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CSpeedUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CSpeedUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CSpeedUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CSpeedUnit() : CValueObject(defaultUnit()) {}
CSpeedUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CSpeedUnit &defaultUnit() { return m_s(); }
@@ -696,16 +800,20 @@ namespace BlackMisc
};
//! Specialized class for time units (ms, hour, min).
class BLACKMISC_EXPORT CTimeUnit : public CValueObject<CTimeUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CTimeUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CTimeUnit>,
public Mixin::DBusOperators<CTimeUnit>,
public Mixin::Index<CTimeUnit>
{
private:
template <class Converter>
CTimeUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CTimeUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
typedef One SecondsToSeconds;
@@ -714,9 +822,19 @@ namespace BlackMisc
struct MinutesToSeconds { static double factor() { return 60.0; } };
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CTimeUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CTimeUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CTimeUnit>::isA;
using Mixin::MetaTypeAndQList<CTimeUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CTimeUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CTimeUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CTimeUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CTimeUnit() : CValueObject(defaultUnit()) {}
CTimeUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CTimeUnit &defaultUnit() { return s(); }
@@ -821,23 +939,38 @@ namespace BlackMisc
};
//! Specialized class for acceleration units (m/s2, ft/s2).
class BLACKMISC_EXPORT CAccelerationUnit : public CValueObject<CAccelerationUnit, CMeasurementUnit>
class BLACKMISC_EXPORT CAccelerationUnit :
public CMeasurementUnit,
public Mixin::MetaTypeAndQList<CAccelerationUnit>,
public Mixin::DBusOperators<CAccelerationUnit>,
public Mixin::Index<CAccelerationUnit>
{
private:
template <class Converter>
CAccelerationUnit(const QString &name, const QString &symbol, const Converter &converter, int displayDigits = 2, double epsilon = 1E-9) :
CValueObject(name, symbol, converter, displayDigits, epsilon)
CMeasurementUnit(name, symbol, converter, displayDigits, epsilon)
{}
CAccelerationUnit(const QString &name, const QString &symbol, std::nullptr_t) :
CValueObject(name, symbol, nullptr)
CMeasurementUnit(name, symbol, nullptr)
{}
struct FeetToMeters { static double factor() { return 0.3048; } };
public:
//! Base type
using base_type = CMeasurementUnit;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::registerMetadata;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::getMetaTypeId;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::isA;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::toCVariant;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::toQVariant;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::convertFromCVariant;
using Mixin::MetaTypeAndQList<CAccelerationUnit>::convertFromQVariant;
//! Default constructor, required for Qt Metasystem
CAccelerationUnit() : CValueObject(defaultUnit()) {}
CAccelerationUnit() : CMeasurementUnit(defaultUnit()) {}
//! Default unit
static const CAccelerationUnit &defaultUnit() { return m_s2(); }

View File

@@ -28,20 +28,19 @@ namespace BlackMisc
// forward declaration
class CPropertyIndex;
class CPropertyIndexList;
class CPropertyIndexVariantMap;
//! \private
template <> struct CValueObjectPolicy<CPropertyIndexVariantMap> : public CValueObjectLegacy {};
/*!
* Specialized value object compliant map for variants,
* based on indexes
*/
class BLACKMISC_EXPORT CPropertyIndexVariantMap : public CValueObject<CPropertyIndexVariantMap>
class BLACKMISC_EXPORT CPropertyIndexVariantMap :
public Mixin::MetaType<CPropertyIndexVariantMap>,
public Mixin::DBusOperators<CPropertyIndexVariantMap>,
public Mixin::Index<CPropertyIndexVariantMap>,
public Mixin::String<CPropertyIndexVariantMap>,
public Mixin::Icon<CPropertyIndexVariantMap>
{
public:
/*!
* Constructor
* \param wildcard when used in search, for setting values irrelevant

View File

@@ -41,11 +41,6 @@ namespace BlackMisc
class CVariant;
class CEmpty;
//! Traits class to test whether a class is derived from CValueObject.
//! \todo TemplateIsBaseOf gives incorrect result due to ambiguity if there is more than one specialization of CValueObject which is a base of T.
template <class T>
using IsValueObject = typename std::is_base_of<CEmpty, T>::type;
/*!
* This registers the value type T with the BlackMisc meta type system,
* making it available for use with the extended feature set of BlackMisc::CVariant.
@@ -149,7 +144,7 @@ namespace BlackMisc
/*!
* CRTP class template from which a derived class can inherit common methods dealing with the metatype of the class.
*/
template <class Derived>
template <class Derived, class... AdditionalTypes>
class MetaType
{
public:
@@ -157,6 +152,8 @@ namespace BlackMisc
static void registerMetadata()
{
Private::MetaTypeHelper<Derived>::maybeRegisterMetaType();
[](...){}((qRegisterMetaType<AdditionalTypes>(), qDBusRegisterMetaType<AdditionalTypes>(), 0)...);
}
//! Returns the Qt meta type ID of this object.
@@ -170,7 +167,7 @@ namespace BlackMisc
{
if (metaTypeId == QMetaType::UnknownType) { return false; }
if (metaTypeId == getMetaTypeId()) { return true; }
return baseIsA(static_cast<const typename Derived::base_type *>(derived()), metaTypeId);
return baseIsA(static_cast<const MetaBaseOfT<Derived> *>(derived()), metaTypeId);
}
//! Method to return CVariant
@@ -200,13 +197,20 @@ namespace BlackMisc
Derived *derived() { return static_cast<Derived *>(this); }
template <typename Base2> static bool baseIsA(const Base2 *base, int metaTypeId) { return base->isA(metaTypeId); }
static bool baseIsA(const CEmpty *, int) { return false; }
static bool baseIsA(const void *, int) { return false; }
};
/*!
* Variant of MetaType mixin which also registers QList<Derived> with the type system.
*/
template <class Derived>
class MetaTypeAndQList : public MetaType<Derived, QList<Derived>>
{};
/*!
* CRTP class template from which a derived class can inherit common methods dealing with hashing instances by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
template <class Derived>
class HashByTuple : private Private::EncapsulationBreaker
{
public:
@@ -219,25 +223,18 @@ namespace BlackMisc
private:
static uint hashImpl(const Derived &value)
{
return BlackMisc::qHash(toMetaTuple(value)) ^ baseHash(static_cast<const typename Derived::base_type &>(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 CEmpty &) { return 0; }
template <typename T> static uint baseHash(const T *base) { return qHash(*base); }
static uint baseHash(const void *) { return 0; }
};
/*!
* Specialization of HashByTuple for classes not registered with the tuple system.
* CRTP class template which will generate marshalling operators for a derived class with its own marshalling implementation.
*/
template <class Derived>
class HashByTuple<Derived, false>
{};
/*!
* CRTP class template from which a derived class can inherit common methods dealing with marshalling instances by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
class DBusByTuple : private Private::EncapsulationBreaker
class DBusOperators
{
public:
//! Unmarshalling operator >>, DBus to object
@@ -257,11 +254,19 @@ namespace BlackMisc
arg.endStructure();
return arg;
}
};
/*!
* CRTP class template from which a derived class can inherit common methods dealing with marshalling instances by metatuple.
*/
template <class Derived>
class DBusByTuple : public DBusOperators<Derived>, private Private::EncapsulationBreaker
{
public:
//! Marshall without begin/endStructure, for when composed within another object
void marshallToDbus(QDBusArgument &arg) const
{
baseMarshall(static_cast<const typename Derived::base_type &>(*derived()), arg);
baseMarshall(static_cast<const BaseOfT<Derived> *>(derived()), arg);
using BlackMisc::operator<<;
arg << Private::EncapsulationBreaker::toMetaTuple(*derived());
}
@@ -269,7 +274,7 @@ namespace BlackMisc
//! Unmarshall without begin/endStructure, for when composed within another object
void unmarshallFromDbus(const QDBusArgument &arg)
{
baseUnmarshall(static_cast<typename Derived::base_type &>(*derived()), arg);
baseUnmarshall(static_cast<BaseOfT<Derived> *>(derived()), arg);
using BlackMisc::operator>>;
arg >> Private::EncapsulationBreaker::toMetaTuple(*derived());
}
@@ -278,58 +283,17 @@ namespace BlackMisc
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
template <typename T> static void baseMarshall(const T &base, QDBusArgument &arg) { base.marshallToDbus(arg); }
template <typename T> static void baseUnmarshall(T &base, const QDBusArgument &arg) { base.unmarshallFromDbus(arg); }
static void baseMarshall(const CEmpty &, QDBusArgument &) {}
static void baseUnmarshall(CEmpty &, const QDBusArgument &) {}
template <typename T> static void baseMarshall(const T *base, QDBusArgument &arg) { base->marshallToDbus(arg); }
template <typename T> static void baseUnmarshall(T *base, const QDBusArgument &arg) { base->unmarshallFromDbus(arg); }
static void baseMarshall(const void *, QDBusArgument &) {}
static void baseUnmarshall(void *, const QDBusArgument &) {}
};
/*!
* Specialization of DBusByTuple for classes not registered with the tuple system.
* CRTP class template which will generate marshalling operators for a derived class with its own marshalling implementation.
*/
template <class Derived>
class DBusByTuple<Derived, false>
{
public:
//! Unmarshalling operator >>, DBus to object
friend const QDBusArgument &operator>>(const QDBusArgument &arg, Derived &obj)
{
arg.beginStructure();
obj.unmarshallFromDbus(arg);
arg.endStructure();
return arg;
}
//! Marshalling operator <<, object to DBus
friend QDBusArgument &operator<<(QDBusArgument &arg, const Derived &obj)
{
arg.beginStructure();
obj.marshallToDbus(arg);
arg.endStructure();
return arg;
}
//! Do nothing
void marshallToDbus(QDBusArgument &arg) const { baseMarshall(static_cast<const typename Derived::base_type &>(*derived()), arg); }
//! Do nothing
void unmarshallFromDbus(const QDBusArgument &arg) { baseUnmarshall(static_cast<typename Derived::base_type &>(*derived()), arg); }
private:
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
template <typename T> static void baseMarshall(const T &base, QDBusArgument &arg) { base.marshallToDbus(arg); }
template <typename T> static void baseUnmarshall(T &base, const QDBusArgument &arg) { base.unmarshallFromDbus(arg); }
static void baseMarshall(const CEmpty &, QDBusArgument &) {}
static void baseUnmarshall(CEmpty &, const QDBusArgument &) {}
};
/*!
* CRTP class template from which a derived class can inherit common methods dealing with JSON by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
class JsonByTuple : private Private::EncapsulationBreaker
class JsonOperators
{
public:
//! operator >> for JSON
@@ -366,18 +330,26 @@ namespace BlackMisc
json.insert(value.first, QJsonValue(value.second.toJson()));
return json;
}
};
/*!
* CRTP class template from which a derived class can inherit common methods dealing with JSON by metatuple.
*/
template <class Derived>
class JsonByTuple : public JsonOperators<Derived>, private Private::EncapsulationBreaker
{
public:
//! Cast to JSON object
QJsonObject toJson() const
{
QJsonObject json = BlackMisc::serializeJson(Private::EncapsulationBreaker::toMetaTuple(*derived()));
return Json::appendJsonObject(json, baseToJson(static_cast<const typename Derived::base_type &>(*derived())));
return Json::appendJsonObject(json, baseToJson(static_cast<const BaseOfT<Derived> *>(derived())));
}
//! Assign from JSON object
void convertFromJson(const QJsonObject &json)
{
baseConvertFromJson(static_cast<typename Derived::base_type &>(*derived()), json);
baseConvertFromJson(static_cast<BaseOfT<Derived> *>(derived()), json);
BlackMisc::deserializeJson(json, Private::EncapsulationBreaker::toMetaTuple(*derived()));
}
@@ -385,74 +357,30 @@ namespace BlackMisc
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
template <typename T> static QJsonObject baseToJson(const T &base) { return base.toJson(); }
template <typename T> static void baseConvertFromJson(T &base, const QJsonObject &json) { base.convertFromJson(json); }
static QJsonObject baseToJson(const CEmpty &) { return {}; }
static void baseConvertFromJson(CEmpty &, const QJsonObject &) {}
template <typename T> static QJsonObject baseToJson(const T *base) { return base->toJson(); }
template <typename T> static void baseConvertFromJson(T *base, const QJsonObject &json) { base->convertFromJson(json); }
static QJsonObject baseToJson(const void *) { return {}; }
static void baseConvertFromJson(void *, const QJsonObject &) {}
};
/*!
* Specialization of JsonByTuple for classes not registered with the tuple system.
* CRTP class template from which a derived class can inherit operator== implemented using its compare function.
*/
template <class Derived>
class JsonByTuple<Derived, false>
class EqualsByCompare
{
public:
//! operator >> for JSON
friend const QJsonObject &operator>>(const QJsonObject &json, Derived &obj)
{
obj.convertFromJson(json);
return json;
}
//! Equals
friend bool operator ==(const Derived &a, const Derived &b) { return compare(a, b) == 0; }
//! operator >> for JSON
friend const QJsonValue &operator>>(const QJsonValue &json, Derived &obj)
{
obj.convertFromJson(json.toObject());
return json;
}
//! operator >> for JSON
friend const QJsonValueRef &operator>>(const QJsonValueRef &json, Derived &obj)
{
obj.convertFromJson(json.toObject());
return json;
}
//! operator << for JSON
friend QJsonArray &operator<<(QJsonArray &json, const Derived &obj)
{
json.append(obj.toJson());
return json;
}
//! operator << for JSON
friend QJsonObject &operator<<(QJsonObject &json, const std::pair<QString, const Derived &> &value)
{
json.insert(value.first, QJsonValue(value.second.toJson()));
return json;
}
//! Do nothing
QJsonObject toJson() const { return baseToJson(static_cast<const typename Derived::base_type &>(*derived())); }
//! Do nothing
void convertFromJson(const QJsonObject &json) { baseConvertFromJson(static_cast<typename Derived::base_type &>(*derived()), json); }
private:
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
template <typename T> static QJsonObject baseToJson(const T &base) { return base.toJson(); }
template <typename T> static void baseConvertFromJson(T &base, const QJsonObject &json) { base.convertFromJson(json); }
static QJsonObject baseToJson(const CEmpty &) { return {}; }
static void baseConvertFromJson(CEmpty &, const QJsonObject &) {}
//! Not equal
friend bool operator !=(const Derived &a, const Derived &b) { return compare(a, b) != 0; }
};
/*!
* CRTP class template from which a derived class can inherit operator== implemented by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
template <class Derived>
class EqualsByTuple : private Private::EncapsulationBreaker
{
public:
@@ -465,24 +393,36 @@ namespace BlackMisc
private:
static bool equals(const Derived &a, const Derived &b)
{
using Base = typename Derived::base_type;
return toMetaTuple(a) == toMetaTuple(b) && baseEquals(static_cast<const Base &>(a), static_cast<const Base &>(b));
return toMetaTuple(a) == toMetaTuple(b) && baseEquals(static_cast<const BaseOfT<Derived> *>(&a), static_cast<const BaseOfT<Derived> *>(&b));
}
template <typename T> static bool baseEquals(const T &a, const T &b) { return a == b; }
static bool baseEquals(const CEmpty &, const CEmpty &) { return true; }
template <typename T> static bool baseEquals(const T *a, const T *b) { return *a == *b; }
static bool baseEquals(const void *, const void *) { return true; }
};
/*!
* Specialization of EqualsByTuple for classes not registered with the tuple system.
* CRTP class template from which a derived class can inherit operator< implemented using its compare function.
*/
template <class Derived>
class EqualsByTuple<Derived, false>
{};
class LessThanByCompare
{
public:
//! Less than
friend bool operator <(const Derived &a, const Derived &b) { return compare(a, b) < 0; }
//! Greater than
friend bool operator >(const Derived &a, const Derived &b) { return compare(a, b) > 0; }
//! Less than or equal
friend bool operator <=(const Derived &a, const Derived &b) { return compare(a, b) <= 0; }
//! Greater than or equal
friend bool operator >=(const Derived &a, const Derived &b) { return compare(a, b) >= 0; }
};
/*!
* CRTP class template from which a derived class can inherit operator< implemented by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
template <class Derived>
class LessThanByTuple : private Private::EncapsulationBreaker
{
public:
@@ -501,25 +441,17 @@ namespace BlackMisc
private:
static bool less(const Derived &a, const Derived &b)
{
using Base = typename Derived::base_type;
if (baseLess(static_cast<const Base &>(a), static_cast<const Base &>(b))) { return true; }
if (baseLess(static_cast<const BaseOfT<Derived> *>(&a), static_cast<const BaseOfT<Derived> *>(&b))) { return true; }
return toMetaTuple(a) < toMetaTuple(b);
}
template <typename T> static bool baseLess(const T &a, const T &b) { return a < b; }
static bool baseLess(const CEmpty &, const CEmpty &) { return false; }
template <typename T> static bool baseLess(const T *a, const T *b) { return *a < *b; }
static bool baseLess(const void *, const void *) { return false; }
};
/*!
* Specialization of LessThanByTuple for classes not registered with the tuple system.
*/
template <class Derived>
class LessThanByTuple<Derived, false>
{};
/*!
* CRTP class template from which a derived class can inherit non-member compare() implemented by metatuple.
*/
template <class Derived, bool IsTupleBased = true>
template <class Derived>
class CompareByTuple : private Private::EncapsulationBreaker
{
public:
@@ -529,21 +461,14 @@ namespace BlackMisc
private:
static int compareImpl(const Derived &a, const Derived &b)
{
int baseCmp = baseCompare(static_cast<const typename Derived::base_type &>(a), static_cast<const typename Derived::base_type &>(b));
int baseCmp = baseCompare(static_cast<const BaseOfT<Derived> *>(&a), static_cast<const BaseOfT<Derived> *>(&b));
if (baseCmp) { return baseCmp; }
return BlackMisc::compare(toMetaTuple(a), toMetaTuple(b));
}
template <typename T> static int baseCompare(const T &a, const T &b) { return compare(a, b); }
static int baseCompare(const CEmpty &, const CEmpty &) { return 0; }
template <typename T> static int baseCompare(const T *a, const T *b) { return compare(*a, *b); }
static int baseCompare(const void *, const void *) { return 0; }
};
/*!
* Specialization of CompareByTuple for classes not registered with the tuple system.
*/
template <class Derived>
class CompareByTuple<Derived, false>
{};
/*!
* CRTP class template from which a derived class can inherit string streaming operations.
*/
@@ -606,10 +531,18 @@ namespace BlackMisc
/*!
* CRTP class template from which a derived class can inherit property indexing functions.
*/
template <class Derived, bool BaseIsEmpty = true>
template <class Derived>
class Index
{
public:
//! Base class enums
enum ColumnIndex
{
IndexPixmap = 10, // manually set to avoid circular dependencies
IndexIcon,
IndexString
};
//! Update by variant map
//! \return number of values changed, with skipEqualValues equal values will not be changed
CPropertyIndexList apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false); // implemented later due to cyclic include dependency
@@ -632,33 +565,8 @@ namespace BlackMisc
};
/*!
* Specialization of Index for classes further down an inheritance hierarchy.
* CRTP class template from which a derived class can inherit icon-related functions.
*/
template <class Derived>
class Index<Derived, false>
{
public:
//! Update by variant map
//! \return number of values changed, with skipEqualValues equal values will not be changed
CPropertyIndexList apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false); // implemented later due to cyclic include dependency
//! Set property by index
void setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) { derived()->Derived::base_type::setPropertyByIndex(variant, index); }
//! Property by index
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; // implemented later due to cyclic include dependency
//! Property by index as String
QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const { return derived()->Derived::base_type::propertyByIndexAsString(index, i18n); }
//! Is given variant equal to value of property index?
bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const { return derived()->Derived::base_type::equalsPropertyByIndex(compareValue, index); }
private:
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
};
template <class Derived, CIcons::IconIndex IconIndex = CIcons::StandardIconUnknown16>
class Icon
{
@@ -689,30 +597,20 @@ namespace BlackMisc
template <class Derived, class Base /*= CEmpty*/> class CValueObject :
public Base,
public Mixin::MetaType<Derived>,
public Mixin::HashByTuple<Derived, Policy::Hash::IsMetaTuple<Derived, Base>::value>,
public Mixin::DBusByTuple<Derived, Policy::DBus::IsMetaTuple<Derived, Base>::value>,
public Mixin::JsonByTuple<Derived, Policy::Json::IsMetaTuple<Derived, Base>::value>,
public Mixin::EqualsByTuple<Derived, Policy::Equals::IsMetaTuple<Derived, Base>::value>,
public Mixin::LessThanByTuple<Derived, Policy::LessThan::IsMetaTuple<Derived, Base>::value>,
public Mixin::CompareByTuple<Derived, Policy::Compare::IsMetaTuple<Derived, Base>::value>,
public Mixin::HashByTuple<Derived>,
public Mixin::DBusByTuple<Derived>,
public Mixin::JsonByTuple<Derived>,
public Mixin::EqualsByTuple<Derived>,
public Mixin::LessThanByTuple<Derived>,
public Mixin::CompareByTuple<Derived>,
public Mixin::String<Derived>,
public Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>,
public Mixin::Index<Derived>,
public Mixin::Icon<Derived>
{
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
public:
//! Base class
using base_type = Base;
//! Base class enums
enum ColumnIndex
{
IndexPixmap = 10, // manually set to avoid circular dependencies
IndexIcon,
IndexString
};
//! \copydoc BlackMisc::Mixin::String::toQString
using Mixin::String<Derived>::toQString;
@@ -723,7 +621,7 @@ namespace BlackMisc
using Mixin::String<Derived>::toStdString;
//! \copydoc BlackMisc::Mixin::Index::apply
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::apply;
using Mixin::Index<Derived>::apply;
//! \copydoc BlackMisc::Mixin::MetaType::toCVariant
using Mixin::MetaType<Derived>::toCVariant;
@@ -732,10 +630,10 @@ namespace BlackMisc
using Mixin::MetaType<Derived>::convertFromCVariant;
//! \copydoc BlackMisc::Mixin::JsonByTuple::toJson
using Mixin::JsonByTuple<Derived, Policy::Json::IsMetaTuple<Derived, Base>::value>::toJson;
using Mixin::JsonByTuple<Derived>::toJson;
//! \copydoc BlackMisc::Mixin::JsonByTuple::convertFromJson
using Mixin::JsonByTuple<Derived, Policy::Json::IsMetaTuple<Derived, Base>::value>::convertFromJson;
using Mixin::JsonByTuple<Derived>::convertFromJson;
//! \copydoc BlackMisc::Mixin::MetaType::toQVariant
using Mixin::MetaType<Derived>::toQVariant;
@@ -744,16 +642,16 @@ namespace BlackMisc
using Mixin::MetaType<Derived>::convertFromQVariant;
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::setPropertyByIndex;
using Mixin::Index<Derived>::setPropertyByIndex;
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::propertyByIndex;
using Mixin::Index<Derived>::propertyByIndex;
//! \copydoc BlackMisc::Mixin::Index::propertyByIndexAsString
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::propertyByIndexAsString;
using Mixin::Index<Derived>::propertyByIndexAsString;
//! \copydoc BlackMisc::Mixin::Index::equalsPropertyByIndex
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::equalsPropertyByIndex;
using Mixin::Index<Derived>::equalsPropertyByIndex;
//! \copydoc BlackMisc::Mixin::Icon::toIcon
using Mixin::Icon<Derived>::toIcon;
@@ -793,10 +691,10 @@ namespace BlackMisc
using Mixin::String<Derived>::stringForStreaming;
//! \copydoc BlackMisc::Mixin::DBusByTuple::marshallToDbus
using Mixin::DBusByTuple<Derived, Policy::DBus::IsMetaTuple<Derived, Base>::value>::marshallToDbus;
using Mixin::DBusByTuple<Derived>::marshallToDbus;
//! \copydoc BlackMisc::Mixin::DBusByTuple::unmarshallFromDbus
using Mixin::DBusByTuple<Derived, Policy::DBus::IsMetaTuple<Derived, Base>::value>::unmarshallFromDbus;
using Mixin::DBusByTuple<Derived>::unmarshallFromDbus;
};
} // namespace
@@ -812,28 +710,18 @@ namespace BlackMisc
{
namespace Mixin
{
template <class Derived>
CVariant MetaType<Derived>::toCVariant() const
template <class Derived, class... AdditionalTypes>
CVariant MetaType<Derived, AdditionalTypes...>::toCVariant() const
{
return CVariant(derived()->toQVariant());
}
template <class Derived>
void MetaType<Derived>::convertFromCVariant(const CVariant &variant)
template <class Derived, class... AdditionalTypes>
void MetaType<Derived, AdditionalTypes...>::convertFromCVariant(const CVariant &variant)
{
derived()->convertFromQVariant(variant.getQVariant());
}
template <class Derived>
CPropertyIndexList Index<Derived, false>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
{
return derived()->Derived::base_type::apply(indexMap, skipEqualValues);
}
template <class Derived>
CVariant Index<Derived, false>::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
return derived()->Derived::base_type::propertyByIndex(index);
}
template <class Derived, bool BaseIsEmpty>
CPropertyIndexList Index<Derived, BaseIsEmpty>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
CPropertyIndexList Index<Derived>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
{
if (indexMap.isEmpty()) return {};
@@ -853,8 +741,8 @@ namespace BlackMisc
}
return changed;
}
template <class Derived, bool BaseIsEmpty>
void Index<Derived, BaseIsEmpty>::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index)
template <class Derived>
void Index<Derived>::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index)
{
if (index.isMyself())
{
@@ -866,22 +754,21 @@ namespace BlackMisc
const QString m = QString("Property by index not found (setter), index: ").append(index.toQString());
qFatal("%s", qPrintable(m));
}
template <class Derived, bool BaseIsEmpty>
CVariant Index<Derived, BaseIsEmpty>::propertyByIndex(const CPropertyIndex &index) const
template <class Derived>
CVariant Index<Derived>::propertyByIndex(const CPropertyIndex &index) const
{
if (index.isMyself())
{
return derived()->toCVariant();
}
using Base = CValueObject<Derived, typename Derived::base_type>;
auto i = index.frontCasted<typename CValueObject<Derived, typename Derived::base_type>::ColumnIndex>();
auto i = index.frontCasted<ColumnIndex>();
switch (i)
{
case Base::IndexIcon:
case IndexIcon:
return CVariant::from(derived()->toIcon());
case Base::IndexPixmap:
case IndexPixmap:
return CVariant::from(derived()->toPixmap());
case Base::IndexString:
case IndexString:
return CVariant(derived()->toQString());
default:
break;
@@ -892,14 +779,14 @@ namespace BlackMisc
qFatal("%s", qPrintable(m));
return {};
}
template <class Derived, bool BaseIsEmpty>
QString Index<Derived, BaseIsEmpty>::propertyByIndexAsString(const CPropertyIndex &index, bool i18n) const
template <class Derived>
QString Index<Derived>::propertyByIndexAsString(const CPropertyIndex &index, bool i18n) const
{
// default implementation, requires propertyByIndex
return derived()->propertyByIndex(index).toQString(i18n);
}
template <class Derived, bool BaseIsEmpty>
bool Index<Derived, BaseIsEmpty>::equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const
template <class Derived>
bool Index<Derived>::equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const
{
return derived()->propertyByIndex(index) == compareValue;
}

View File

@@ -28,6 +28,44 @@ namespace BlackMisc
template <typename T>
void registerMetaValueType();
/*!
* If T has a member typedef base_type, this trait will obtain it, otherwise void.
*/
template <class T>
class BaseOf
{
//template <typename U> static typename U::base_type *test(int);
template <typename U> static typename U::base_type *test(typename std::enable_if<! std::is_same<typename U::base_type, CEmpty>::value, int>::type);
template <typename U> static void *test(...);
public:
//! The declared base_type of T, or void if there is none.
typedef typename std::remove_pointer<decltype(test<T>(0))>::type type;
};
/*!
* It T has a member typedef base_type which is a registered metatype, this trait will obtain it, otherwise void.
*/
template <class T>
class MetaBaseOf
{
public:
//! Type of T::base_type, or void if not declared.
typedef typename std::conditional<QMetaTypeId<typename BaseOf<T>::type>::Defined, typename BaseOf<T>::type, void>::type type;
};
/*!
* Alias for typename BaseOf<T>::type.
*/
template <class T>
using BaseOfT = typename BaseOf<T>::type;
/*!
* Alias for typename MetaBaseOf<T>::type.
*/
template <class T>
using MetaBaseOfT = typename MetaBaseOf<T>::type;
namespace Private
{
//! \private Needed so we can copy forward-declared CVariant.
@@ -63,21 +101,30 @@ namespace BlackMisc
template <typename T>
struct CValueObjectMetaInfo : public IValueObjectMetaInfo
{
// http://en.wikibooks.org/wiki/More_C++_Idioms/Member_Detector
struct Fallback { int toJson, convertFromJson; };
template <int Fallback:: *> struct int_t { typedef int type; };
template <typename U> struct Derived : public U, public Fallback {};
template <typename U> static QJsonObject toJsonHelper(const U &, typename int_t<&Derived<U>::toJson>::type) { return {}; }
template <typename U> static QJsonObject toJsonHelper(const U &object, ...) { return object.toJson(); }
template <typename U> static void convertFromJsonHelper(const QJsonObject &, U &, typename int_t<&Derived<U>::convertFromJson>::type) {}
template <typename U> static void convertFromJsonHelper(const QJsonObject &json, U &object, ...) { object.convertFromJson(json); }
virtual QString toQString(const void *object, bool i18n) const override
{
return cast(object).toQString(i18n);
}
virtual QJsonObject toJson(const void *object) const override
{
return cast(object).toJson();
return toJsonHelper(cast(object), 0);
}
virtual void convertFromJson(const QJsonObject &json, void *object) const override
{
cast(object).convertFromJson(json);
convertFromJsonHelper(json, cast(object), 0);
}
virtual void unmarshall(const QDBusArgument &arg, void *object) const override
{
arg >> cast(object);
cast(object).unmarshallFromDbus(arg);
}
virtual uint getValueHash(const void *object) const override
{
@@ -89,8 +136,8 @@ namespace BlackMisc
}
virtual const void *upCastTo(const void *object, int metaTypeId) const override
{
const auto base = static_cast<const void *>(static_cast<const typename T::base_type *>(&cast(object)));
return metaTypeId == getMetaTypeId() ? object : CValueObjectMetaInfo<typename T::base_type>{}.upCastTo(base, metaTypeId);
const auto base = static_cast<const void *>(static_cast<const MetaBaseOfT<T> *>(&cast(object)));
return metaTypeId == getMetaTypeId() ? object : CValueObjectMetaInfo<MetaBaseOfT<T>>{}.upCastTo(base, metaTypeId);
}
virtual int compareImpl(const void *lhs, const void *rhs) const override
{
@@ -122,7 +169,7 @@ namespace BlackMisc
//! \private Explicit specialization for the terminating case of the recursive CValueObjectMetaInfo::upCastTo.
template <>
struct CValueObjectMetaInfo<CEmpty>
struct CValueObjectMetaInfo<void>
{
const void *upCastTo(const void *, int) const
{

View File

@@ -26,35 +26,29 @@ class QDBusArgument;
namespace BlackMisc
{
class CVariant;
//! \private
template <> struct CValueObjectPolicy<CVariant> : public CValueObjectPolicy<>
{
using MetaType = Policy::MetaType::QMetaTypeAndDBusOnly;
using Equals = Policy::Equals::OwnEquals;
using LessThan = Policy::LessThan::OwnLessThan;
using Compare = Policy::Compare::None;
using Hash = Policy::Hash::Own;
using DBus = Policy::DBus::Own;
using Json = Policy::Json::Own;
};
/*!
* Wrapper around QVariant which provides transparent access to CValueObject methods
* of the contained object if it is registered with BlackMisc::registerMetaValueType.
*/
class BLACKMISC_EXPORT CVariant : public CValueObject<CVariant>
class BLACKMISC_EXPORT CVariant :
public Mixin::MetaType<CVariant>,
public Mixin::EqualsByCompare<CVariant>,
public Mixin::LessThanByCompare<CVariant>,
public Mixin::DBusOperators<CVariant>,
public Mixin::JsonOperators<CVariant>,
public Mixin::Index<CVariant>,
public Mixin::String<CVariant>,
public Mixin::Icon<CVariant>
{
public:
//! Default constructor.
CVariant() {}
//! Copy constructor.
CVariant(const CVariant &other) : CValueObject(other), m_v(other.m_v) {}
CVariant(const CVariant &) = default;
//! Move constructor.
CVariant(CVariant &&other) : CValueObject(std::move(other)), m_v(std::move(other.m_v)) {}
CVariant(CVariant &&other) : m_v(std::move(other.m_v)) {}
//! Construct from a QVariant.
CVariant(const QVariant &var) : m_v(var) {}
@@ -190,28 +184,6 @@ namespace BlackMisc
//! \copydoc CValueObject::unmarshallFromDbus
void unmarshallFromDbus(const QDBusArgument &argument);
//! Equal operator.
friend bool operator ==(const CVariant &a, const CVariant &b) { return compare(a, b) == 0; }
//! Not equal operator.
//! \todo temporary, remove after refactoring
friend bool operator !=(const CVariant &a, const CVariant &b) { return compare(a, b) != 0; }
//! Less than operator.
friend bool operator <(const CVariant &a, const CVariant &b) { return compare(a, b) < 0; }
//! Greater than operator.
//! \todo temporary, remove after refactoring
friend bool operator >(const CVariant &a, const CVariant &b) { return compare(a, b) > 0; }
//! Less than or equal operator.
//! \todo temporary, remove after refactoring
friend bool operator <=(const CVariant &a, const CVariant &b) { return compare(a, b) <= 0; }
//! Greater than or equal operator.
//! \todo temporary, remove after refactoring
friend bool operator >=(const CVariant &a, const CVariant &b) { return compare(a, b) >= 0; }
//! \copydoc CValueObject::compare
friend int compare(const CVariant &a, const CVariant &b) { return compareImpl(a, b); }