mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
Use if constexpr (C++17 feature)
This commit is contained in:
@@ -57,10 +57,8 @@ namespace BlackMisc
|
||||
result = true;
|
||||
eventLoop.quit();
|
||||
});
|
||||
if (checkInit(init))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if constexpr (std::is_void_v<decltype(init())>) { init(); }
|
||||
else if (init()) { return true; }
|
||||
if (timeoutMs > 0)
|
||||
{
|
||||
QTimer::singleShot(timeoutMs, &eventLoop, &QEventLoop::quit);
|
||||
@@ -68,20 +66,6 @@ namespace BlackMisc
|
||||
eventLoop.exec();
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
static bool checkInit(F init, std::enable_if_t<std::is_void_v<decltype(init())>, int> = 0)
|
||||
{
|
||||
init();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
static bool checkInit(F init, std::enable_if_t<!std::is_void_v<decltype(init())>, int> = 0)
|
||||
{
|
||||
return init();
|
||||
}
|
||||
};
|
||||
} // ns
|
||||
|
||||
|
||||
@@ -82,26 +82,19 @@ namespace BlackMisc
|
||||
return OutputIterator<std::decay_t<F>>(std::forward<F>(func));
|
||||
}
|
||||
|
||||
namespace Private
|
||||
{
|
||||
//! \private
|
||||
template <class T> auto makeInsertIterator(T &container, std::true_type)
|
||||
{
|
||||
return makeOutputIterator([&container](auto &&v) { container.push_back(std::forward<decltype(v)>(v)); });
|
||||
}
|
||||
//! \private
|
||||
template <class T> auto makeInsertIterator(T &container, std::false_type)
|
||||
{
|
||||
return makeOutputIterator([&container](auto &&v) { container.insert(std::forward<decltype(v)>(v)); });
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return an insert iterator appropriate to the container type (uses push_back or insert).
|
||||
*/
|
||||
template <class T> auto makeInsertIterator(T &container)
|
||||
{
|
||||
return Private::makeInsertIterator(container, THasPushBack<T>());
|
||||
if constexpr (THasPushBack<T>::value)
|
||||
{
|
||||
return makeOutputIterator([&container](auto &&v) { container.push_back(std::forward<decltype(v)>(v)); });
|
||||
}
|
||||
else
|
||||
{
|
||||
return makeOutputIterator([&container](auto &&v) { container.insert(std::forward<decltype(v)>(v)); });
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -102,12 +102,6 @@ namespace BlackMisc
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Templates used by the constructor template:
|
||||
*/
|
||||
template <typename T>
|
||||
struct tag {};
|
||||
|
||||
template <typename T>
|
||||
static const CLogCategoryList &fromClass()
|
||||
{
|
||||
@@ -115,27 +109,15 @@ namespace BlackMisc
|
||||
static const auto list = []
|
||||
{
|
||||
CLogCategoryList list;
|
||||
list.appendCategoriesFromMemberFunction(tag<T>(), THasGetLogCategories<T>());
|
||||
list.appendCategoriesFromMetaType(tag<T>(), std::bool_constant<QMetaTypeId<T>::Defined>());
|
||||
list.appendCategoriesFromMetaObject(tag<T>(), std::is_base_of<QObject, T>());
|
||||
if constexpr (THasGetLogCategories<T>::value) { list.push_back(fromQStringList(T::getLogCategories())); }
|
||||
if constexpr (QMetaTypeId<T>::Defined) { list.push_back(QMetaType::typeName(qMetaTypeId<T>())); }
|
||||
if constexpr (std::is_base_of_v<QObject, T>) { list.appendCategoriesFromMetaObject(T::staticMetaObject); }
|
||||
if (list.isEmpty()) { list.push_back(CLogCategories::uncategorized()); }
|
||||
return list;
|
||||
}();
|
||||
return list;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void appendCategoriesFromMemberFunction(tag<T>, std::true_type) { push_back(fromQStringList(T::getLogCategories())); }
|
||||
void appendCategoriesFromMemberFunction(...) {}
|
||||
|
||||
template <typename T>
|
||||
void appendCategoriesFromMetaType(tag<T>, std::true_type) { push_back(QMetaType::typeName(qMetaTypeId<T>())); }
|
||||
void appendCategoriesFromMetaType(...) {}
|
||||
|
||||
template <typename T>
|
||||
void appendCategoriesFromMetaObject(tag<T>, std::true_type) { appendCategoriesFromMetaObject(T::staticMetaObject); }
|
||||
void appendCategoriesFromMetaObject(...) {}
|
||||
|
||||
void appendCategoriesFromMetaObject(const QMetaObject &);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,12 +70,9 @@ namespace BlackMisc
|
||||
template <typename T, typename Flags>
|
||||
static bool membersEqual(const T &a, const T &b, Flags)
|
||||
{
|
||||
return membersEqual(a, b, std::bool_constant<static_cast<bool>(Flags::value & CaseInsensitiveComparison)>());
|
||||
if constexpr (static_cast<bool>(Flags::value & CaseInsensitiveComparison)) { return a.compare(b, Qt::CaseInsensitive) == 0; }
|
||||
else { return a == b; }
|
||||
}
|
||||
template <typename T>
|
||||
static bool membersEqual(const T &a, const T &b, std::true_type) { return a.compare(b, Qt::CaseInsensitive) == 0; }
|
||||
template <typename T>
|
||||
static bool membersEqual(const T &a, const T &b, std::false_type) { return a == b; }
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -135,15 +132,14 @@ namespace BlackMisc
|
||||
template <typename T, typename Flags>
|
||||
static bool membersLess(bool &io_greaterThan, const T &a, const T &b, Flags)
|
||||
{
|
||||
using CaseInsensitive = std::bool_constant<static_cast<bool>(Flags::value & CaseInsensitiveComparison)>;
|
||||
if (io_greaterThan) { return false; }
|
||||
io_greaterThan = membersLess(b, a, CaseInsensitive());
|
||||
return membersLess(a, b, CaseInsensitive());
|
||||
if constexpr (static_cast<bool>(Flags::value & CaseInsensitiveComparison))
|
||||
{
|
||||
io_greaterThan = b.compare(a, Qt::CaseInsensitive) < 0;
|
||||
return a.compare(b, Qt::CaseInsensitive) < 0;
|
||||
}
|
||||
else { io_greaterThan = b < a; return a < b; }
|
||||
}
|
||||
template <typename T>
|
||||
static bool membersLess(const T &a, const T &b, std::true_type) { return a.compare(b, Qt::CaseInsensitive) < 0; }
|
||||
template <typename T>
|
||||
static bool membersLess(const T &a, const T &b, std::false_type) { return a < b; }
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -171,15 +167,10 @@ namespace BlackMisc
|
||||
template <typename T, typename Flags>
|
||||
static int membersCompare(const T &a, const T &b, Flags)
|
||||
{
|
||||
using CaseInsensitive = std::bool_constant<static_cast<bool>(Flags::value & CaseInsensitiveComparison)>;
|
||||
return membersCompare(a, b, CaseInsensitive(), THasCompare<T, T>());
|
||||
if constexpr (static_cast<bool>(Flags::value & CaseInsensitiveComparison)) { return a.compare(b, Qt::CaseInsensitive); }
|
||||
else if constexpr (THasCompare<T, T>::value) { return compare(a, b); }
|
||||
else { return a < b ? -1 : b < a ? 1 : 0; }
|
||||
}
|
||||
template <typename T, typename U>
|
||||
static int membersCompare(const T &a, const T &b, std::true_type, U) { return a.compare(b, Qt::CaseInsensitive); }
|
||||
template <typename T>
|
||||
static int membersCompare(const T &a, const T &b, std::false_type, std::true_type) { return compare(a, b); }
|
||||
template <typename T>
|
||||
static int membersCompare(const T &a, const T &b, std::false_type, std::false_type) { return a < b ? -1 : b < a ? 1 : 0; }
|
||||
};
|
||||
|
||||
} // Mixin
|
||||
|
||||
@@ -26,27 +26,6 @@ namespace BlackMisc
|
||||
*/
|
||||
class LosslessTag {};
|
||||
|
||||
// *INDENT-OFF*
|
||||
namespace Private
|
||||
{
|
||||
//! \cond PRIVATE
|
||||
template <class T, std::enable_if_t<THasMarshallMethods<T>::value, int> = 0>
|
||||
void marshallMember(QDBusArgument &arg, const T &value, std::false_type) { value.marshallToDbus(arg); }
|
||||
template <class T, std::enable_if_t<THasMarshallMethods<T>::value, int> = 0>
|
||||
void marshallMember(QDBusArgument &arg, const T &value, std::true_type) { value.marshallToDbus(arg, LosslessTag()); }
|
||||
template <class T, std::enable_if_t<!THasMarshallMethods<T>::value, int> = 0>
|
||||
void marshallMember(QDBusArgument &arg, const T &value, std::false_type) { arg << value; }
|
||||
|
||||
template <class T, std::enable_if_t<THasMarshallMethods<T>::value, int> = 0>
|
||||
void unmarshallMember(const QDBusArgument &arg, T &value, std::false_type) { value.unmarshallFromDbus(arg); }
|
||||
template <class T, std::enable_if_t<THasMarshallMethods<T>::value, int> = 0>
|
||||
void unmarshallMember(const QDBusArgument &arg, T &value, std::true_type) { value.unmarshallFromDbus(arg, LosslessTag()); }
|
||||
template <class T, std::enable_if_t<!THasMarshallMethods<T>::value, int> = 0>
|
||||
void unmarshallMember(const QDBusArgument &arg, T &value, std::false_type) { arg >> value; }
|
||||
//! \endcond
|
||||
}
|
||||
// *INDENT-ON*
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
/*!
|
||||
@@ -95,8 +74,16 @@ namespace BlackMisc
|
||||
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
using lossless = std::bool_constant<member.has(MetaFlags<LosslessMarshalling>())>;
|
||||
Private::marshallMember(arg, member.in(*this->derived()), lossless());
|
||||
const auto &value = member.in(*this->derived());
|
||||
if constexpr (THasMarshallMethods<std::decay_t<decltype(value)>>::value)
|
||||
{
|
||||
if constexpr (member.has(MetaFlags<LosslessMarshalling>()))
|
||||
{
|
||||
value.marshallToDbus(arg, LosslessTag());
|
||||
}
|
||||
else { value.marshallToDbus(arg); }
|
||||
}
|
||||
else { arg << value; }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,8 +94,16 @@ namespace BlackMisc
|
||||
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
using lossless = std::bool_constant<member.has(MetaFlags<LosslessMarshalling>())>;
|
||||
Private::unmarshallMember(arg, member.in(*this->derived()), lossless());
|
||||
auto &value = member.in(*this->derived());
|
||||
if constexpr (THasMarshallMethods<std::decay_t<decltype(value)>>::value)
|
||||
{
|
||||
if constexpr (member.has(MetaFlags<LosslessMarshalling>()))
|
||||
{
|
||||
value.unmarshallFromDbus(arg, LosslessTag());
|
||||
}
|
||||
else { value.unmarshallFromDbus(arg); }
|
||||
}
|
||||
else { arg >> value; }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -70,15 +70,18 @@ namespace BlackMisc
|
||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||
Derived *derived() { return static_cast<Derived *>(this); }
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_default_constructible_v<T>, int> = 0>
|
||||
QVariant myself() const { return QVariant::fromValue(*derived()); }
|
||||
template <typename T, std::enable_if_t<std::is_default_constructible_v<T>, int> = 0>
|
||||
void myself(const QVariant &variant) { *derived() = variant.value<T>(); }
|
||||
|
||||
template <typename T, std::enable_if_t<! std::is_default_constructible_v<T>, int> = 0>
|
||||
QVariant myself() const { qFatal("isMyself should have been handled before reaching here"); return {}; }
|
||||
template <typename T, std::enable_if_t<! std::is_default_constructible_v<T>, int> = 0>
|
||||
void myself(const QVariant &) { qFatal("isMyself should have been handled before reaching here"); }
|
||||
template <typename T>
|
||||
QVariant myself() const
|
||||
{
|
||||
if constexpr (std::is_default_constructible_v<T>) { return QVariant::fromValue(*derived()); }
|
||||
else { qFatal("isMyself should have been handled before reaching here"); return {}; }
|
||||
}
|
||||
template <typename T>
|
||||
void myself(const QVariant &variant)
|
||||
{
|
||||
if constexpr (std::is_default_constructible_v<T>) { *derived() = variant.value<T>(); }
|
||||
else { qFatal("isMyself should have been handled before reaching here"); }
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QVariant basePropertyByIndex(const T *base, CPropertyIndexRef index) const { return base->propertyByIndex(index); }
|
||||
|
||||
@@ -31,31 +31,6 @@
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CPropertyIndex;
|
||||
|
||||
namespace Private
|
||||
{
|
||||
//! \private
|
||||
template <class T, class X>
|
||||
int compareByProperty(const T &a, const T &b, const CPropertyIndex &index, std::true_type, X)
|
||||
{
|
||||
return a.comparePropertyByIndex(index, b);
|
||||
}
|
||||
//! \private
|
||||
template <class T>
|
||||
int compareByProperty(const T &a, const T &b, const CPropertyIndex &index, std::false_type, std::true_type)
|
||||
{
|
||||
return compare(a.propertyByIndex(index), b.propertyByIndex(index));
|
||||
}
|
||||
//! \private
|
||||
template <class T>
|
||||
int compareByProperty(const T &, const T &, const CPropertyIndex &, std::false_type, std::false_type)
|
||||
{
|
||||
qFatal("Not implemented");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Property index. The index can be nested, that's why it is a sequence
|
||||
* (e.g. PropertyIndexPilot, PropertyIndexRealname).
|
||||
@@ -153,7 +128,15 @@ namespace BlackMisc
|
||||
return [index = *this](const auto & a, const auto & b)
|
||||
{
|
||||
using T = std::decay_t<decltype(a)>;
|
||||
return Private::compareByProperty(a, b, index, THasComparePropertyByIndex<T>(), THasPropertyByIndex<T>());
|
||||
if constexpr (THasComparePropertyByIndex<T>::value)
|
||||
{
|
||||
return a.comparePropertyByIndex(index, b);
|
||||
}
|
||||
else if constexpr (THasPropertyByIndex<T>::value)
|
||||
{
|
||||
return compare(a.propertyByIndex(index), b.propertyByIndex(index));
|
||||
}
|
||||
else { qFatal("Not implemented"); return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,31 +17,6 @@
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CPropertyIndexRef;
|
||||
|
||||
namespace Private
|
||||
{
|
||||
//! \private
|
||||
template <class T, class X>
|
||||
int compareByProperty(const T &a, const T &b, const CPropertyIndexRef &index, std::true_type, X)
|
||||
{
|
||||
return a.comparePropertyByIndex(index, b);
|
||||
}
|
||||
//! \private
|
||||
template <class T>
|
||||
int compareByProperty(const T &a, const T &b, const CPropertyIndexRef &index, std::false_type, std::true_type)
|
||||
{
|
||||
return compare(a.propertyByIndex(index), b.propertyByIndex(index));
|
||||
}
|
||||
//! \private
|
||||
template <class T>
|
||||
int compareByProperty(const T &, const T &, const CPropertyIndexRef &, std::false_type, std::false_type)
|
||||
{
|
||||
qFatal("Not implemented");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Non-owning reference to a CPropertyIndex with a subset of its features.
|
||||
*/
|
||||
@@ -205,7 +180,15 @@ namespace BlackMisc
|
||||
return [index = *this](const auto & a, const auto & b)
|
||||
{
|
||||
using T = std::decay_t<decltype(a)>;
|
||||
return Private::compareByProperty(a, b, index, THasComparePropertyByIndex<T>(), THasPropertyByIndex<T>());
|
||||
if constexpr (THasComparePropertyByIndex<T>::value)
|
||||
{
|
||||
return a.comparePropertyByIndex(index, b);
|
||||
}
|
||||
else if constexpr (THasPropertyByIndex<T>::value)
|
||||
{
|
||||
return compare(a.propertyByIndex(index), b.propertyByIndex(index));
|
||||
}
|
||||
else { qFatal("Not implemented"); return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -151,12 +151,12 @@ namespace BlackMisc
|
||||
|
||||
protected:
|
||||
//! Efficiently compare addresses of two objects. Return false if types are not compatible.
|
||||
//! @{
|
||||
template <typename T, typename U, std::enable_if_t<TIsEqualityComparable<const T *, const U *>::value, int> = 0>
|
||||
static bool equalPointers(const T *a, const U *b) { return a == b; }
|
||||
template <typename T, typename U, std::enable_if_t<! TIsEqualityComparable<const T *, const U *>::value, int> = 0>
|
||||
static bool equalPointers(const T *, const U *) { return false; }
|
||||
//! @}
|
||||
template <typename T, typename U>
|
||||
static bool equalPointers(const T *a, const U *b)
|
||||
{
|
||||
if constexpr (TIsEqualityComparable<const T *, const U *>::value) { return a == b; }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
private:
|
||||
Derived &derived() { return static_cast<Derived &>(*this); }
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace BlackMisc
|
||||
}
|
||||
virtual int getMetaTypeId() const override
|
||||
{
|
||||
return maybeGetMetaTypeId(std::bool_constant<QMetaTypeId<T>::Defined> {});
|
||||
if constexpr (QMetaTypeId<T>::Defined) { return qMetaTypeId<T>(); } else { return QMetaType::UnknownType; }
|
||||
}
|
||||
virtual const void *upCastTo(const void *object, int metaTypeId) const override
|
||||
{
|
||||
@@ -205,9 +205,6 @@ namespace BlackMisc
|
||||
|
||||
static const T &cast(const void *object) { return *static_cast<const T *>(object); }
|
||||
static T &cast(void *object) { return *static_cast<T *>(object); }
|
||||
|
||||
static int maybeGetMetaTypeId(std::true_type) { return qMetaTypeId<T>(); }
|
||||
static int maybeGetMetaTypeId(std::false_type) { return QMetaType::UnknownType; }
|
||||
};
|
||||
|
||||
//! \private Explicit specialization for the terminating case of the recursive CValueObjectMetaInfo::upCastTo.
|
||||
@@ -236,22 +233,26 @@ namespace BlackMisc
|
||||
template <typename T>
|
||||
void maybeRegisterMetaListConvert(...) {}
|
||||
|
||||
template <typename T, bool IsRegisteredMetaType /* = true */>
|
||||
struct MetaTypeHelperImpl
|
||||
{
|
||||
static constexpr int maybeGetMetaTypeId() { return qMetaTypeId<T>(); }
|
||||
static void maybeRegisterMetaType() { qRegisterMetaType<T>(); qDBusRegisterMetaType<T>(); qRegisterMetaTypeStreamOperators<T>(); registerMetaValueType<T>(); maybeRegisterMetaListConvert<T>(0); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MetaTypeHelperImpl<T, /* IsRegisteredMetaType = */ false>
|
||||
struct MetaTypeHelper
|
||||
{
|
||||
static constexpr int maybeGetMetaTypeId() { return QMetaType::UnknownType; }
|
||||
static void maybeRegisterMetaType() {}
|
||||
static constexpr int maybeGetMetaTypeId()
|
||||
{
|
||||
if constexpr (QMetaTypeId<T>::Defined) { return qMetaTypeId<T>(); }
|
||||
else { return QMetaType::UnknownType; }
|
||||
}
|
||||
static void maybeRegisterMetaType()
|
||||
{
|
||||
if constexpr (QMetaTypeId<T>::Defined)
|
||||
{
|
||||
qRegisterMetaType<T>();
|
||||
qDBusRegisterMetaType<T>();
|
||||
qRegisterMetaTypeStreamOperators<T>();
|
||||
registerMetaValueType<T>();
|
||||
maybeRegisterMetaListConvert<T>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using MetaTypeHelper = MetaTypeHelperImpl<T, QMetaTypeId<T>::Defined>;
|
||||
//! \endcond
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,11 @@ namespace BlackMisc
|
||||
static CWorker *fromTask(QObject *owner, const QString &name, F &&task)
|
||||
{
|
||||
int typeId = qMetaTypeId<std::decay_t<decltype(std::forward<F>(task)())>>();
|
||||
return fromTaskImpl(owner, name, typeId, [task = std::forward<F>(task)]() mutable { return fromResultOf(std::move(task), 0); });
|
||||
return fromTaskImpl(owner, name, typeId, [task = std::forward<F>(task)]() mutable
|
||||
{
|
||||
if constexpr (std::is_void_v<decltype(task())>) { std::move(task)(); return QVariant(); }
|
||||
else { return QVariant::fromValue(std::move(task)()); }
|
||||
});
|
||||
}
|
||||
|
||||
//! Connects to a functor to which will be passed the result when the task is finished.
|
||||
@@ -255,11 +259,6 @@ namespace BlackMisc
|
||||
CWorker(const std::function<QVariant()> &task) : m_task(task) {}
|
||||
static CWorker *fromTaskImpl(QObject *owner, const QString &name, int typeId, const std::function<QVariant()> &task);
|
||||
|
||||
template <typename F>
|
||||
static auto fromResultOf(F &&func, std::enable_if_t<std::is_void_v<decltype(func())>, int>) { func(); return QVariant(); }
|
||||
template <typename F>
|
||||
static auto fromResultOf(F &&func, std::enable_if_t<!std::is_void_v<decltype(func())>, int>) { return QVariant::fromValue(func()); }
|
||||
|
||||
template <typename R>
|
||||
R resultNoWait() { Q_ASSERT(m_result.canConvert<R>()); return m_result.value<R>(); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user