mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-17 19:05:31 +08:00
refs #413 Decomposed comparison operations of CValueObject into mixins.
This commit is contained in:
@@ -102,9 +102,6 @@ namespace BlackMisc
|
|||||||
~CEmpty() = default;
|
~CEmpty() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Dummy comparison.
|
|
||||||
inline int compare(const CEmpty &, const CEmpty &) { return 0; }
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Default policy classes for use by CValueObject.
|
* Default policy classes for use by CValueObject.
|
||||||
*
|
*
|
||||||
@@ -465,6 +462,101 @@ namespace BlackMisc
|
|||||||
static void baseConvertFromJson(CEmpty &, const QJsonObject &) {}
|
static void baseConvertFromJson(CEmpty &, const QJsonObject &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* CRTP class template from which a derived class can inherit operator== implemented by metatuple.
|
||||||
|
*/
|
||||||
|
template <class Derived, bool IsTupleBased = true>
|
||||||
|
class EqualsByTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Equals
|
||||||
|
friend bool operator ==(const Derived &a, const Derived &b) { return equals(a, b); }
|
||||||
|
|
||||||
|
//! Not equal
|
||||||
|
friend bool operator !=(const Derived &a, const Derived &b) { return ! equals(a, b); }
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
template <typename T> static bool baseEquals(const T &a, const T &b) { return a == b; }
|
||||||
|
static bool baseEquals(const CEmpty &, const CEmpty &) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Specialization of EqualsByTuple for classes not registered with the tuple system.
|
||||||
|
*/
|
||||||
|
template <class Derived>
|
||||||
|
class EqualsByTuple<Derived, false>
|
||||||
|
{};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* CRTP class template from which a derived class can inherit operator< implemented by metatuple.
|
||||||
|
*/
|
||||||
|
template <class Derived, bool IsTupleBased = true>
|
||||||
|
class LessThanByTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Less than
|
||||||
|
friend bool operator <(const Derived &a, const Derived &b) { return less(a, b); }
|
||||||
|
|
||||||
|
//! Greater than
|
||||||
|
friend bool operator >(const Derived &a, const Derived &b) { return less(b, a); }
|
||||||
|
|
||||||
|
//! Less than or equal
|
||||||
|
friend bool operator <=(const Derived &a, const Derived &b) { return ! less(b, a); }
|
||||||
|
|
||||||
|
//! Greater than or equal
|
||||||
|
friend bool operator >=(const Derived &a, const Derived &b) { return ! less(a, b); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* 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>
|
||||||
|
class CompareByTuple : private Private::EncapsulationBreaker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Return negative, zero, or positive if a is less than, equal to, or greater than b.
|
||||||
|
friend int compare(const Derived &a, const Derived &b) { return compareImpl(a, b); }
|
||||||
|
|
||||||
|
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));
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Specialization of CompareByTuple for classes not registered with the tuple system.
|
||||||
|
*/
|
||||||
|
template <class Derived>
|
||||||
|
class CompareByTuple<Derived, false>
|
||||||
|
{};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -483,9 +575,9 @@ namespace BlackMisc
|
|||||||
public Mixin::HashByTuple<Derived, Policy::Hash::IsMetaTuple<Derived, Base>::value>,
|
public Mixin::HashByTuple<Derived, Policy::Hash::IsMetaTuple<Derived, Base>::value>,
|
||||||
public Mixin::DBusByTuple<Derived, Policy::DBus::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::JsonByTuple<Derived, Policy::Json::IsMetaTuple<Derived, Base>::value>,
|
||||||
private CValueObjectPolicy<Derived>::Equals::template Ops<Derived, Base>,
|
public Mixin::EqualsByTuple<Derived, Policy::Equals::IsMetaTuple<Derived, Base>::value>,
|
||||||
private CValueObjectPolicy<Derived>::LessThan::template Ops<Derived, Base>,
|
public Mixin::LessThanByTuple<Derived, Policy::LessThan::IsMetaTuple<Derived, Base>::value>,
|
||||||
private CValueObjectPolicy<Derived>::Compare::template Ops<Derived, Base>
|
public Mixin::CompareByTuple<Derived, Policy::Compare::IsMetaTuple<Derived, Base>::value>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
|
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,11 @@ namespace BlackMisc
|
|||||||
friend bool operator !=(const T &a, const T &b) { return !(a == b); }
|
friend bool operator !=(const T &a, const T &b) { return !(a == b); }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \private Detect the policy of T, following inheritance.
|
||||||
|
template <class T, class B, class P = typename CValueObjectPolicy<T>::Equals> struct IsMetaTuple : public std::false_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, MetaTuple> : public std::true_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, Inherit> : public IsMetaTuple<B, typename B::base_type> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LessThan
|
namespace LessThan
|
||||||
@@ -196,6 +201,11 @@ namespace BlackMisc
|
|||||||
friend bool operator <=(const T &a, const T &b) { return !(b < a); }
|
friend bool operator <=(const T &a, const T &b) { return !(b < a); }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \private Detect the policy of T, following inheritance.
|
||||||
|
template <class T, class B, class P = typename CValueObjectPolicy<T>::LessThan> struct IsMetaTuple : public std::false_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, MetaTuple> : public std::true_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, Inherit> : public IsMetaTuple<B, typename B::base_type> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Compare
|
namespace Compare
|
||||||
@@ -248,6 +258,11 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \private Detect the policy of T, following inheritance.
|
||||||
|
template <class T, class B, class P = typename CValueObjectPolicy<T>::Compare> struct IsMetaTuple : public std::false_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, MetaTuple> : public std::true_type {};
|
||||||
|
template <class T, class B> struct IsMetaTuple<T, B, Inherit> : public IsMetaTuple<B, typename B::base_type> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Hash
|
namespace Hash
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ namespace BlackMisc
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
uint qHash(const T &) { return 0; }
|
uint qHash(const T &) { return 0; }
|
||||||
|
|
||||||
|
//! \private Fallback in case compare is not defined for T.
|
||||||
|
template <typename T>
|
||||||
|
int compare(const T &, const T &) { return 0; }
|
||||||
|
|
||||||
//! \private Implementation of IValueObjectMetaInfo representing the set of operations supported by T.
|
//! \private Implementation of IValueObjectMetaInfo representing the set of operations supported by T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct CValueObjectMetaInfo : public IValueObjectMetaInfo
|
struct CValueObjectMetaInfo : public IValueObjectMetaInfo
|
||||||
|
|||||||
@@ -193,9 +193,25 @@ namespace BlackMisc
|
|||||||
//! Equal operator.
|
//! Equal operator.
|
||||||
friend bool operator ==(const CVariant &a, const CVariant &b) { return compare(a, b) == 0; }
|
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.
|
//! Less than operator.
|
||||||
friend bool operator <(const CVariant &a, const CVariant &b) { return compare(a, b) < 0; }
|
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
|
//! \copydoc CValueObject::compare
|
||||||
friend int compare(const CVariant &a, const CVariant &b) { return compareImpl(a, b); }
|
friend int compare(const CVariant &a, const CVariant &b) { return compareImpl(a, b); }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user