Use if constexpr (C++17 feature)

This commit is contained in:
Mat Sutcliffe
2021-04-17 21:57:20 +01:00
parent 5d67cd9f68
commit d7a461ff7a
11 changed files with 103 additions and 189 deletions

View File

@@ -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

View File

@@ -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; }
});
}

View File

@@ -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); }