diff --git a/src/blackmisc/eventloop.h b/src/blackmisc/eventloop.h index 65117af44..83209e05f 100644 --- a/src/blackmisc/eventloop.h +++ b/src/blackmisc/eventloop.h @@ -57,10 +57,8 @@ namespace BlackMisc result = true; eventLoop.quit(); }); - if (checkInit(init)) - { - return true; - } + if constexpr (std::is_void_v) { 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 - static bool checkInit(F init, std::enable_if_t, int> = 0) - { - init(); - return false; - } - - template - static bool checkInit(F init, std::enable_if_t, int> = 0) - { - return init(); - } }; } // ns diff --git a/src/blackmisc/iterator.h b/src/blackmisc/iterator.h index 8d7808788..164e8774b 100644 --- a/src/blackmisc/iterator.h +++ b/src/blackmisc/iterator.h @@ -82,26 +82,19 @@ namespace BlackMisc return OutputIterator>(std::forward(func)); } - namespace Private - { - //! \private - template auto makeInsertIterator(T &container, std::true_type) - { - return makeOutputIterator([&container](auto &&v) { container.push_back(std::forward(v)); }); - } - //! \private - template auto makeInsertIterator(T &container, std::false_type) - { - return makeOutputIterator([&container](auto &&v) { container.insert(std::forward(v)); }); - } - } - /*! * Return an insert iterator appropriate to the container type (uses push_back or insert). */ template auto makeInsertIterator(T &container) { - return Private::makeInsertIterator(container, THasPushBack()); + if constexpr (THasPushBack::value) + { + return makeOutputIterator([&container](auto &&v) { container.push_back(std::forward(v)); }); + } + else + { + return makeOutputIterator([&container](auto &&v) { container.insert(std::forward(v)); }); + } } /*! diff --git a/src/blackmisc/logcategorylist.h b/src/blackmisc/logcategorylist.h index b1f637c44..62e97c8a7 100644 --- a/src/blackmisc/logcategorylist.h +++ b/src/blackmisc/logcategorylist.h @@ -102,12 +102,6 @@ namespace BlackMisc QString convertToQString(bool i18n = false) const; private: - /* - * Templates used by the constructor template: - */ - template - struct tag {}; - template static const CLogCategoryList &fromClass() { @@ -115,27 +109,15 @@ namespace BlackMisc static const auto list = [] { CLogCategoryList list; - list.appendCategoriesFromMemberFunction(tag(), THasGetLogCategories()); - list.appendCategoriesFromMetaType(tag(), std::bool_constant::Defined>()); - list.appendCategoriesFromMetaObject(tag(), std::is_base_of()); + if constexpr (THasGetLogCategories::value) { list.push_back(fromQStringList(T::getLogCategories())); } + if constexpr (QMetaTypeId::Defined) { list.push_back(QMetaType::typeName(qMetaTypeId())); } + if constexpr (std::is_base_of_v) { list.appendCategoriesFromMetaObject(T::staticMetaObject); } if (list.isEmpty()) { list.push_back(CLogCategories::uncategorized()); } return list; }(); return list; } - template - void appendCategoriesFromMemberFunction(tag, std::true_type) { push_back(fromQStringList(T::getLogCategories())); } - void appendCategoriesFromMemberFunction(...) {} - - template - void appendCategoriesFromMetaType(tag, std::true_type) { push_back(QMetaType::typeName(qMetaTypeId())); } - void appendCategoriesFromMetaType(...) {} - - template - void appendCategoriesFromMetaObject(tag, std::true_type) { appendCategoriesFromMetaObject(T::staticMetaObject); } - void appendCategoriesFromMetaObject(...) {} - void appendCategoriesFromMetaObject(const QMetaObject &); }; } diff --git a/src/blackmisc/mixin/mixincompare.h b/src/blackmisc/mixin/mixincompare.h index 5ba85d395..e3fd7d193 100644 --- a/src/blackmisc/mixin/mixincompare.h +++ b/src/blackmisc/mixin/mixincompare.h @@ -70,12 +70,9 @@ namespace BlackMisc template static bool membersEqual(const T &a, const T &b, Flags) { - return membersEqual(a, b, std::bool_constant(Flags::value & CaseInsensitiveComparison)>()); + if constexpr (static_cast(Flags::value & CaseInsensitiveComparison)) { return a.compare(b, Qt::CaseInsensitive) == 0; } + else { return a == b; } } - template - static bool membersEqual(const T &a, const T &b, std::true_type) { return a.compare(b, Qt::CaseInsensitive) == 0; } - template - static bool membersEqual(const T &a, const T &b, std::false_type) { return a == b; } }; /*! @@ -135,15 +132,14 @@ namespace BlackMisc template static bool membersLess(bool &io_greaterThan, const T &a, const T &b, Flags) { - using CaseInsensitive = std::bool_constant(Flags::value & CaseInsensitiveComparison)>; if (io_greaterThan) { return false; } - io_greaterThan = membersLess(b, a, CaseInsensitive()); - return membersLess(a, b, CaseInsensitive()); + if constexpr (static_cast(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 - static bool membersLess(const T &a, const T &b, std::true_type) { return a.compare(b, Qt::CaseInsensitive) < 0; } - template - static bool membersLess(const T &a, const T &b, std::false_type) { return a < b; } }; /*! @@ -171,15 +167,10 @@ namespace BlackMisc template static int membersCompare(const T &a, const T &b, Flags) { - using CaseInsensitive = std::bool_constant(Flags::value & CaseInsensitiveComparison)>; - return membersCompare(a, b, CaseInsensitive(), THasCompare()); + if constexpr (static_cast(Flags::value & CaseInsensitiveComparison)) { return a.compare(b, Qt::CaseInsensitive); } + else if constexpr (THasCompare::value) { return compare(a, b); } + else { return a < b ? -1 : b < a ? 1 : 0; } } - template - static int membersCompare(const T &a, const T &b, std::true_type, U) { return a.compare(b, Qt::CaseInsensitive); } - template - static int membersCompare(const T &a, const T &b, std::false_type, std::true_type) { return compare(a, b); } - template - static int membersCompare(const T &a, const T &b, std::false_type, std::false_type) { return a < b ? -1 : b < a ? 1 : 0; } }; } // Mixin diff --git a/src/blackmisc/mixin/mixindbus.h b/src/blackmisc/mixin/mixindbus.h index eb86d550a..2bac088f9 100644 --- a/src/blackmisc/mixin/mixindbus.h +++ b/src/blackmisc/mixin/mixindbus.h @@ -26,27 +26,6 @@ namespace BlackMisc */ class LosslessTag {}; - // *INDENT-OFF* - namespace Private - { - //! \cond PRIVATE - template ::value, int> = 0> - void marshallMember(QDBusArgument &arg, const T &value, std::false_type) { value.marshallToDbus(arg); } - template ::value, int> = 0> - void marshallMember(QDBusArgument &arg, const T &value, std::true_type) { value.marshallToDbus(arg, LosslessTag()); } - template ::value, int> = 0> - void marshallMember(QDBusArgument &arg, const T &value, std::false_type) { arg << value; } - - template ::value, int> = 0> - void unmarshallMember(const QDBusArgument &arg, T &value, std::false_type) { value.unmarshallFromDbus(arg); } - template ::value, int> = 0> - void unmarshallMember(const QDBusArgument &arg, T &value, std::true_type) { value.unmarshallFromDbus(arg, LosslessTag()); } - template ::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().without(MetaFlags()); meta.forEachMember([ &, this ](auto member) { - using lossless = std::bool_constant())>; - Private::marshallMember(arg, member.in(*this->derived()), lossless()); + const auto &value = member.in(*this->derived()); + if constexpr (THasMarshallMethods>::value) + { + if constexpr (member.has(MetaFlags())) + { + value.marshallToDbus(arg, LosslessTag()); + } + else { value.marshallToDbus(arg); } + } + else { arg << value; } }); } @@ -107,8 +94,16 @@ namespace BlackMisc constexpr auto meta = introspect().without(MetaFlags()); meta.forEachMember([ &, this ](auto member) { - using lossless = std::bool_constant())>; - Private::unmarshallMember(arg, member.in(*this->derived()), lossless()); + auto &value = member.in(*this->derived()); + if constexpr (THasMarshallMethods>::value) + { + if constexpr (member.has(MetaFlags())) + { + value.unmarshallFromDbus(arg, LosslessTag()); + } + else { value.unmarshallFromDbus(arg); } + } + else { arg >> value; } }); } diff --git a/src/blackmisc/mixin/mixinindex.h b/src/blackmisc/mixin/mixinindex.h index df4bed403..74aa5c3e8 100644 --- a/src/blackmisc/mixin/mixinindex.h +++ b/src/blackmisc/mixin/mixinindex.h @@ -70,15 +70,18 @@ namespace BlackMisc const Derived *derived() const { return static_cast(this); } Derived *derived() { return static_cast(this); } - template , int> = 0> - QVariant myself() const { return QVariant::fromValue(*derived()); } - template , int> = 0> - void myself(const QVariant &variant) { *derived() = variant.value(); } - - template , int> = 0> - QVariant myself() const { qFatal("isMyself should have been handled before reaching here"); return {}; } - template , int> = 0> - void myself(const QVariant &) { qFatal("isMyself should have been handled before reaching here"); } + template + QVariant myself() const + { + if constexpr (std::is_default_constructible_v) { return QVariant::fromValue(*derived()); } + else { qFatal("isMyself should have been handled before reaching here"); return {}; } + } + template + void myself(const QVariant &variant) + { + if constexpr (std::is_default_constructible_v) { *derived() = variant.value(); } + else { qFatal("isMyself should have been handled before reaching here"); } + } template QVariant basePropertyByIndex(const T *base, CPropertyIndexRef index) const { return base->propertyByIndex(index); } diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index db61379d1..c0357efc0 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -31,31 +31,6 @@ namespace BlackMisc { - class CPropertyIndex; - - namespace Private - { - //! \private - template - int compareByProperty(const T &a, const T &b, const CPropertyIndex &index, std::true_type, X) - { - return a.comparePropertyByIndex(index, b); - } - //! \private - template - 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 - 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; - return Private::compareByProperty(a, b, index, THasComparePropertyByIndex(), THasPropertyByIndex()); + if constexpr (THasComparePropertyByIndex::value) + { + return a.comparePropertyByIndex(index, b); + } + else if constexpr (THasPropertyByIndex::value) + { + return compare(a.propertyByIndex(index), b.propertyByIndex(index)); + } + else { qFatal("Not implemented"); return 0; } }; } diff --git a/src/blackmisc/propertyindexref.h b/src/blackmisc/propertyindexref.h index 6171cc70e..521ae7513 100644 --- a/src/blackmisc/propertyindexref.h +++ b/src/blackmisc/propertyindexref.h @@ -17,31 +17,6 @@ namespace BlackMisc { - class CPropertyIndexRef; - - namespace Private - { - //! \private - template - int compareByProperty(const T &a, const T &b, const CPropertyIndexRef &index, std::true_type, X) - { - return a.comparePropertyByIndex(index, b); - } - //! \private - template - 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 - 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; - return Private::compareByProperty(a, b, index, THasComparePropertyByIndex(), THasPropertyByIndex()); + if constexpr (THasComparePropertyByIndex::value) + { + return a.comparePropertyByIndex(index, b); + } + else if constexpr (THasPropertyByIndex::value) + { + return compare(a.propertyByIndex(index), b.propertyByIndex(index)); + } + else { qFatal("Not implemented"); return 0; } }; } diff --git a/src/blackmisc/range.h b/src/blackmisc/range.h index 0c5772066..78ebc3667 100644 --- a/src/blackmisc/range.h +++ b/src/blackmisc/range.h @@ -151,12 +151,12 @@ namespace BlackMisc protected: //! Efficiently compare addresses of two objects. Return false if types are not compatible. - //! @{ - template ::value, int> = 0> - static bool equalPointers(const T *a, const U *b) { return a == b; } - template ::value, int> = 0> - static bool equalPointers(const T *, const U *) { return false; } - //! @} + template + static bool equalPointers(const T *a, const U *b) + { + if constexpr (TIsEqualityComparable::value) { return a == b; } + else { return false; } + } private: Derived &derived() { return static_cast(*this); } diff --git a/src/blackmisc/variantprivate.h b/src/blackmisc/variantprivate.h index e33807d3f..9aa73ec27 100644 --- a/src/blackmisc/variantprivate.h +++ b/src/blackmisc/variantprivate.h @@ -171,7 +171,7 @@ namespace BlackMisc } virtual int getMetaTypeId() const override { - return maybeGetMetaTypeId(std::bool_constant::Defined> {}); + if constexpr (QMetaTypeId::Defined) { return qMetaTypeId(); } 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(object); } static T &cast(void *object) { return *static_cast(object); } - - static int maybeGetMetaTypeId(std::true_type) { return qMetaTypeId(); } - 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 void maybeRegisterMetaListConvert(...) {} - template - struct MetaTypeHelperImpl - { - static constexpr int maybeGetMetaTypeId() { return qMetaTypeId(); } - static void maybeRegisterMetaType() { qRegisterMetaType(); qDBusRegisterMetaType(); qRegisterMetaTypeStreamOperators(); registerMetaValueType(); maybeRegisterMetaListConvert(0); } - }; - template - struct MetaTypeHelperImpl + struct MetaTypeHelper { - static constexpr int maybeGetMetaTypeId() { return QMetaType::UnknownType; } - static void maybeRegisterMetaType() {} + static constexpr int maybeGetMetaTypeId() + { + if constexpr (QMetaTypeId::Defined) { return qMetaTypeId(); } + else { return QMetaType::UnknownType; } + } + static void maybeRegisterMetaType() + { + if constexpr (QMetaTypeId::Defined) + { + qRegisterMetaType(); + qDBusRegisterMetaType(); + qRegisterMetaTypeStreamOperators(); + registerMetaValueType(); + maybeRegisterMetaListConvert(0); + } + } }; - - template - using MetaTypeHelper = MetaTypeHelperImpl::Defined>; //! \endcond } } diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 0c32ee7a5..3a5f0f0d8 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -211,7 +211,11 @@ namespace BlackMisc static CWorker *fromTask(QObject *owner, const QString &name, F &&task) { int typeId = qMetaTypeId(task)())>>(); - return fromTaskImpl(owner, name, typeId, [task = std::forward(task)]() mutable { return fromResultOf(std::move(task), 0); }); + return fromTaskImpl(owner, name, typeId, [task = std::forward(task)]() mutable + { + if constexpr (std::is_void_v) { 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 &task) : m_task(task) {} static CWorker *fromTaskImpl(QObject *owner, const QString &name, int typeId, const std::function &task); - template - static auto fromResultOf(F &&func, std::enable_if_t, int>) { func(); return QVariant(); } - template - static auto fromResultOf(F &&func, std::enable_if_t, int>) { return QVariant::fromValue(func()); } - template R resultNoWait() { Q_ASSERT(m_result.canConvert()); return m_result.value(); }