mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 10:15:38 +08:00
refs #413, #416 Implemented base_type fallthrough in Mixin::Index so it can be used by more classes.
(cherry picked from commit d97775a232b007061cbfa85b451b0be569127696)
This commit is contained in:
@@ -45,6 +45,26 @@ namespace BlackMisc
|
||||
typedef typename std::conditional<QMetaTypeId<typename BaseOf<T>::type>::Defined, typename BaseOf<T>::type, void>::type type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* If T has a member typedef base_type which has a member propertyByIndex, this trait will obtain it, otherwise void.
|
||||
*/
|
||||
template <class T>
|
||||
class IndexBaseOf
|
||||
{
|
||||
// http://en.wikibooks.org/wiki/More_C++_Idioms/Member_Detector
|
||||
struct Empty {};
|
||||
struct Fallback { int propertyByIndex; };
|
||||
template <int Fallback:: *> struct int_t { typedef int type; };
|
||||
template <typename U> struct Derived : public Fallback, public std::conditional<std::is_void<U>::value, Empty, U>::type {};
|
||||
|
||||
template <typename U> static void test(typename int_t<&Derived<U>::propertyByIndex>::type);
|
||||
template <typename U> static U test(...);
|
||||
|
||||
public:
|
||||
//! Type of T::base_type, or void if not declared.
|
||||
typedef decltype(test<typename BaseOf<T>::type>(0)) type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Alias for typename BaseOf<T>::type.
|
||||
*/
|
||||
@@ -56,6 +76,12 @@ namespace BlackMisc
|
||||
*/
|
||||
template <class T>
|
||||
using MetaBaseOfT = typename MetaBaseOf<T>::type;
|
||||
|
||||
/*!
|
||||
* Alias for typename IndexBaseOf<T>::type.
|
||||
*/
|
||||
template <class T>
|
||||
using IndexBaseOfT = typename IndexBaseOf<T>::type;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace BlackMisc
|
||||
case IndexValueRounded6DigitsWithUnit:
|
||||
return CVariant::from(this->valueRoundedWithUnit(6));
|
||||
default:
|
||||
return Mixin::Index<CPhysicalQuantity<MU, PQ>>::propertyByIndex(index);
|
||||
return Mixin::Index<PQ>::propertyByIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ namespace BlackMisc
|
||||
this->parseFromString(variant.toQString());
|
||||
break;
|
||||
default:
|
||||
Mixin::Index<CPhysicalQuantity<MU, PQ>>::setPropertyByIndex(variant, index);
|
||||
Mixin::Index<PQ>::setPropertyByIndex(variant, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace BlackMisc
|
||||
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::Index<PQ>,
|
||||
public Mixin::MetaTypeAndQList<PQ>,
|
||||
public Mixin::String<PQ>,
|
||||
public Mixin::Icon<CPhysicalQuantity<MU, PQ>>
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace BlackMisc
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
|
||||
/*!
|
||||
* CRTP class template from which a derived class can inherit property indexing functions.
|
||||
*
|
||||
@@ -64,7 +65,39 @@ namespace BlackMisc
|
||||
private:
|
||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||
Derived *derived() { return static_cast<Derived *>(this); }
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_default_constructible<T>::value, int>::type = 0>
|
||||
CVariant myself() const { return CVariant::from(*derived()); }
|
||||
template <typename T, typename std::enable_if<std::is_default_constructible<T>::value, int>::type = 0>
|
||||
void myself(const CVariant &variant) { *derived() = variant.to<T>(); }
|
||||
|
||||
template <typename T, typename std::enable_if<! std::is_default_constructible<T>::value, int>::type = 0>
|
||||
CVariant myself() const { qFatal("isMyself should have been handled before reaching here"); return {}; }
|
||||
template <typename T, typename std::enable_if<! std::is_default_constructible<T>::value, int>::type = 0>
|
||||
void myself(const CVariant &) { qFatal("isMyself should have been handled before reaching here"); }
|
||||
|
||||
template <typename T>
|
||||
CVariant basePropertyByIndex(const T *base, const CPropertyIndex &index) const { return base->propertyByIndex(index); }
|
||||
template <typename T>
|
||||
void baseSetPropertyByIndex(T *base, const CVariant &var, const CPropertyIndex &index) { base->setPropertyByIndex(var, index); }
|
||||
|
||||
CVariant basePropertyByIndex(const void *, const CPropertyIndex &index) const
|
||||
{ qFatal("%s", qPrintable("Property by index not found, index: " + index.toQString())); return {}; }
|
||||
void baseSetPropertyByIndex(void *, const CVariant &, const CPropertyIndex &index)
|
||||
{ qFatal("%s", qPrintable("Property by index not found (setter), index: " + index.toQString())); }
|
||||
};
|
||||
|
||||
/*!
|
||||
* When a derived class and a base class both inherit from Mixin::Index,
|
||||
* the derived class uses this macro to disambiguate the inherited members.
|
||||
*/
|
||||
# define BLACKMISC_DECLARE_USING_MIXIN_INDEX(DERIVED) \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::apply; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::setPropertyByIndex; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::propertyByIndex; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::propertyByIndexAsString; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::equalsPropertyByIndex;
|
||||
|
||||
} // Mixin
|
||||
|
||||
/*!
|
||||
@@ -227,20 +260,19 @@ namespace BlackMisc
|
||||
{
|
||||
if (index.isMyself())
|
||||
{
|
||||
derived()->convertFromCVariant(variant);
|
||||
return;
|
||||
myself<Derived>(variant);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseSetPropertyByIndex(static_cast<IndexBaseOfT<Derived> *>(derived()), variant, index);
|
||||
}
|
||||
|
||||
// not all classes have implemented nesting
|
||||
const QString m = QString("Property by index not found (setter), index: ").append(index.toQString());
|
||||
qFatal("%s", qPrintable(m));
|
||||
}
|
||||
template <class Derived>
|
||||
CVariant Index<Derived>::propertyByIndex(const CPropertyIndex &index) const
|
||||
{
|
||||
if (index.isMyself())
|
||||
{
|
||||
return derived()->toCVariant();
|
||||
return myself<Derived>();
|
||||
}
|
||||
auto i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
@@ -252,18 +284,12 @@ namespace BlackMisc
|
||||
case IndexString:
|
||||
return CVariant(derived()->toQString());
|
||||
default:
|
||||
break;
|
||||
return basePropertyByIndex(static_cast<const IndexBaseOfT<Derived> *>(derived()), index);
|
||||
}
|
||||
|
||||
// not all classes have implemented nesting
|
||||
const QString m = QString("Property by index not found, index: ").append(index.toQString());
|
||||
qFatal("%s", qPrintable(m));
|
||||
return {};
|
||||
}
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user