Use _v traits variable aliases (C++17 feature)

This commit is contained in:
Mat Sutcliffe
2021-04-17 20:43:42 +01:00
parent 6d232756f4
commit 5d67cd9f68
32 changed files with 67 additions and 67 deletions

View File

@@ -176,7 +176,7 @@ namespace BlackMisc
template <typename T, typename F>
void tupleForEachPair(T &&tuple, F &&visitor)
{
using seq = std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value / 2>;
using seq = std::make_index_sequence<std::tuple_size_v<std::decay_t<T>> / 2>;
return Private::tupleForEachPairImpl(std::forward<T>(tuple), std::forward<F>(visitor), seq());
}
}

View File

@@ -134,7 +134,7 @@ namespace BlackMisc
char s[1024] {};
auto x = strerror_r(errno, s, sizeof(s));
setErrorString(QString::fromLocal8Bit(s));
static_assert(std::is_same<decltype(x), int>::value, "Non-standard signature of POSIX function strerror_r, check documentation.");
static_assert(std::is_same_v<decltype(x), int>, "Non-standard signature of POSIX function strerror_r, check documentation.");
}
}
#elif defined(Q_OS_WIN32)

View File

@@ -173,14 +173,14 @@ namespace BlackMisc
template <class AVIO>
CModulator<AVIO>::CModulator() : m_name("default")
{
static_assert(!std::is_polymorphic<AVIO>::value, "Must not use virtual functions for value classes");
static_assert(!std::is_polymorphic_v<AVIO>, "Must not use virtual functions for value classes");
}
template <class AVIO>
CModulator<AVIO>::CModulator(const QString &name, const BlackMisc::PhysicalQuantities::CFrequency &activeFrequency, const BlackMisc::PhysicalQuantities::CFrequency &standbyFrequency) :
m_name(name), m_frequencyActive(activeFrequency), m_frequencyStandby(standbyFrequency)
{
static_assert(!std::is_polymorphic<AVIO>::value, "Must not use virtual functions for value classes");
static_assert(!std::is_polymorphic_v<AVIO>, "Must not use virtual functions for value classes");
}
template <class AVIO>

View File

@@ -20,7 +20,7 @@ namespace BlackMisc
namespace Compare
{
//! Compare arithmetic values
template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
int compare(T a, T b)
{
if (a < b) { return -1; }
@@ -29,7 +29,7 @@ namespace BlackMisc
}
//! Compare enumerators
template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
int compare(T a, T b)
{
using UT = std::underlying_type_t<T>;

View File

@@ -27,8 +27,8 @@ namespace BlackMisc
//! Such objects should implement \sa ITimestampBased and \sa IDatastoreObjectWithIntegerKey or \sa IDatastoreObjectWithStringKey
template<class OBJ, class CONTAINER, typename KEYTYPE> class IDatastoreObjectList : public ITimestampObjectList<OBJ, CONTAINER>
{
static constexpr bool hasIntegerKey = std::is_base_of<IDatastoreObjectWithIntegerKey, OBJ>::value && std::is_same<int, KEYTYPE>::value;
static constexpr bool hasStringKey = std::is_base_of<IDatastoreObjectWithStringKey, OBJ>::value && std::is_base_of<QString, KEYTYPE>::value;
static constexpr bool hasIntegerKey = std::is_base_of_v<IDatastoreObjectWithIntegerKey, OBJ> && std::is_same_v<int, KEYTYPE>;
static constexpr bool hasStringKey = std::is_base_of_v<IDatastoreObjectWithStringKey, OBJ> && std::is_base_of_v<QString, KEYTYPE>;
static_assert(hasIntegerKey || hasStringKey, "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType");
public:

View File

@@ -33,7 +33,7 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, std::string &s);
/*!
* Operator for streaming enums to QDBusArgument.
*/
template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
template <class E, std::enable_if_t<std::is_enum_v<E>, int> = 0>
QDBusArgument &operator <<(QDBusArgument &arg, const E &value)
{
arg.beginStructure();
@@ -45,7 +45,7 @@ QDBusArgument &operator <<(QDBusArgument &arg, const E &value)
/*!
* Operator for streaming enums from QDBusArgument.
*/
template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
template <class E, std::enable_if_t<std::is_enum_v<E>, int> = 0>
const QDBusArgument &operator >>(const QDBusArgument &arg, E &value)
{
int temp;

View File

@@ -63,7 +63,7 @@ namespace BlackMisc
struct TAssociativityTraits<false, false>
{
template <class Key, class>
struct DefaultType { static_assert(std::is_void<Key>::value, "Key does not support either QHash or QMap"); };
struct DefaultType { static_assert(std::is_void_v<Key>, "Key does not support either QHash or QMap"); };
};
//! \endcond
}
@@ -475,7 +475,7 @@ namespace BlackMisc
template <class Map1, class Map2, class F>
void forEachIntersection(const Map1 &map1, const Map2 &map2, F functor)
{
static_assert(std::is_same<typename Map1::key_type, typename Map2::key_type>::value, "Maps must have the same key type");
static_assert(std::is_same_v<typename Map1::key_type, typename Map2::key_type>, "Maps must have the same key type");
if (map1.empty() || map2.empty()) { return; }
auto it1 = implementationOf(map1).lowerBound(map2.cbegin().key());
auto end1 = implementationOf(map1).upperBound((map2.cend() - 1).key());

View File

@@ -71,14 +71,14 @@ namespace BlackMisc
private:
template <typename F>
static bool checkInit(F init, std::enable_if_t<std::is_void<decltype(init())>::value, int> = 0)
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<decltype(init())>::value, int> = 0)
static bool checkInit(F init, std::enable_if_t<!std::is_void_v<decltype(init())>, int> = 0)
{
return init();
}

View File

@@ -27,17 +27,17 @@ namespace BlackMisc
{
// Our own version of C++17 std::invoke().
template <typename F, typename T, typename = std::enable_if_t<std::is_member_object_pointer<F>::value>>
template <typename F, typename T, typename = std::enable_if_t<std::is_member_object_pointer_v<F>>>
decltype(auto) invoke(F ptr, T && object)
{
return std::forward<T>(object).*ptr;
}
template <typename F, typename T, typename... Ts, typename = std::enable_if_t<std::is_member_function_pointer<F>::value>>
template <typename F, typename T, typename... Ts, typename = std::enable_if_t<std::is_member_function_pointer_v<F>>>
decltype(auto) invoke(F ptr, T && object, Ts && ... args)
{
return (std::forward<T>(object).*ptr)(std::forward<Ts>(args)...);
}
template < typename F, typename... Ts, typename = std::enable_if_t < ! std::is_member_pointer<std::decay_t<F>>::value >>
template < typename F, typename... Ts, typename = std::enable_if_t < ! std::is_member_pointer_v<std::decay_t<F>>>>
decltype(auto) invoke(F && func, Ts && ... args)
{
return std::forward<F>(func)(std::forward<Ts>(args)...);

View File

@@ -55,7 +55,7 @@ namespace BlackMisc
OutputIterator &operator *() { return *this; }
//! Assignment operator performs the output
template <typename T, std::enable_if_t<! std::is_convertible<T, OutputIterator>::value, int> = 0>
template <typename T, std::enable_if_t<! std::is_convertible_v<T, OutputIterator>, int> = 0>
OutputIterator &operator =(T &&value) { m_func(std::forward<T>(value)); return *this; }
//! Copy assignment operator
@@ -135,7 +135,7 @@ namespace BlackMisc
};
//! The type returned by this iterator's arrow operator, which may be a pointer or a pointer-like wrapper object
using pointer = typename std::conditional<std::is_reference<undecayed_type>::value,
using pointer = typename std::conditional<std::is_reference_v<undecayed_type>,
std::remove_reference_t<undecayed_type> *,
PointerWrapper>::type;

View File

@@ -73,14 +73,14 @@ BLACKMISC_EXPORT QJsonValueRef operator >>(QJsonValueRef json, QByteArray &value
//! \ingroup JSON
//! @{
template<class ENUM>
std::enable_if_t<std::is_enum<ENUM>::value, QJsonObject>
std::enable_if_t<std::is_enum_v<ENUM>, QJsonObject>
&operator<<(QJsonObject &json, std::pair<QString, const ENUM &> value)
{
json.insert(value.first, QJsonValue(static_cast<int>(value.second)));
return json;
}
template<class ENUM>
std::enable_if_t<std::is_enum<ENUM>::value, QJsonObject>
std::enable_if_t<std::is_enum_v<ENUM>, QJsonObject>
&operator<<(QJsonObject &json, std::pair<BlackMisc::CExplicitLatin1String, const ENUM &> value)
{
json[value.first] = QJsonValue(static_cast<int>(value.second));
@@ -108,7 +108,7 @@ QJsonObject &operator<<(QJsonObject &json, std::pair<BlackMisc::CExplicitLatin1S
//! \brief Specialized JSON deserialization for enum
//! \ingroup JSON
template<class ENUM>
std::enable_if_t<std::is_enum<ENUM>::value, QJsonValue>
std::enable_if_t<std::is_enum_v<ENUM>, QJsonValue>
const &operator>>(const QJsonValue &json, ENUM &value)
{
value = static_cast<ENUM>(json.toInt());
@@ -126,7 +126,7 @@ const QJsonValue &operator>>(const QJsonValue &json, QFlags<ENUM> &value)
//! \brief Specialized JSON deserialization for enum
//! \ingroup JSON
template<class ENUM, typename = std::enable_if_t<std::is_enum<ENUM>::value>>
template<class ENUM, typename = std::enable_if_t<std::is_enum_v<ENUM>>>
QJsonValueRef operator>>(QJsonValueRef json, ENUM &value)
{
value = static_cast<ENUM>(json.toInt());

View File

@@ -82,7 +82,7 @@ namespace BlackMisc
LockFreeUniqueWriter &operator =(const T &other) { *m_ptr = other; return *this; }
//! Replace the stored value by moving from a T. The change is applied in the destructor.
LockFreeUniqueWriter &operator =(T &&other) noexcept(std::is_nothrow_move_assignable<T>::value) { *m_ptr = std::move(other); return *this; }
LockFreeUniqueWriter &operator =(T &&other) noexcept(std::is_nothrow_move_assignable_v<T>) { *m_ptr = std::move(other); return *this; }
//! LockFreeUniqueWriter cannot be copied.
//! @{
@@ -137,7 +137,7 @@ namespace BlackMisc
LockFreeSharedWriter &operator =(const T &other) { *m_ptr = other; return *this; }
//! Replace the stored value by moving from a T. The change is applied by evaluating in a bool context.
LockFreeSharedWriter &operator =(T &&other) noexcept(std::is_nothrow_move_assignable<T>::value) { *m_ptr = std::move(other); return *this; }
LockFreeSharedWriter &operator =(T &&other) noexcept(std::is_nothrow_move_assignable_v<T>) { *m_ptr = std::move(other); return *this; }
//! Try to overwrite the original object with the new one stored in the writer, and return false on success.
//! If true is returned, then the caller must try again. This would happen if another simultaneous write had occurred.
@@ -206,7 +206,7 @@ namespace BlackMisc
LockFree(const T &other) : m_ptr(std::make_shared<const T>(other)) {}
//! Construct by moving from a T.
LockFree(T &&other) noexcept(std::is_nothrow_move_assignable<T>::value) : m_ptr(std::make_shared<const T>(std::move(other))) {}
LockFree(T &&other) noexcept(std::is_nothrow_move_assignable_v<T>) : m_ptr(std::make_shared<const T>(std::move(other))) {}
//! LockFree cannot be copied or moved.
//! @{

View File

@@ -65,7 +65,7 @@ namespace BlackMisc
* \param pointer The value of pointer is unimportant. Only the static type T is considered.
* It is legal to pass static_cast<T>(nullptr), but in member functions passing the <tt>this</tt> pointer is easier.
*/
template <typename T, typename = std::enable_if_t<std::is_class<T>::value>>
template <typename T, typename = std::enable_if_t<std::is_class_v<T>>>
CLogCategoryList(const T *pointer) : CLogCategoryList(fromClass<T>()) { Q_UNUSED(pointer); }
//! Return a copy with another category appended.

View File

@@ -251,7 +251,7 @@ namespace BlackMisc
template <typename M, quint64 Flags = 0>
constexpr static CMetaMember<M, Flags> makeMetaMember(M ptrToMember, const char *name = nullptr, int index = 0, MetaFlags<Flags> flags = {})
{
static_assert(std::is_member_object_pointer<M>::value, "M must be a pointer to member object");
static_assert(std::is_member_object_pointer_v<M>, "M must be a pointer to member object");
return { ptrToMember, name, index, flags };
}
};

View File

@@ -70,14 +70,14 @@ 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<T>::value, int> = 0>
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<T>::value, int> = 0>
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<T>::value, int> = 0>
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<T>::value, int> = 0>
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>

View File

@@ -29,7 +29,7 @@ namespace BlackMisc
Optional() noexcept {}
//! Construct from a value.
Optional(T value) noexcept(std::is_nothrow_move_constructible<T>::value)
Optional(T value) noexcept(std::is_nothrow_move_constructible_v<T>)
{
new (m_data.bytes) T(std::move(value));
m_isValid = true;
@@ -39,14 +39,14 @@ namespace BlackMisc
Optional(std::nullptr_t) noexcept {}
//! Copy constructor.
Optional(const Optional &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
Optional(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v<T>)
{
if (other.m_isValid) { new (m_data.bytes) T(*other); }
m_isValid = other.m_isValid;
}
//! Move constructor.
Optional(Optional &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
Optional(Optional &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
{
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
m_isValid = other.m_isValid;
@@ -60,7 +60,7 @@ namespace BlackMisc
}
//! Copy assignment.
Optional &operator =(const Optional &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
Optional &operator =(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v<T>)
{
reset();
if (other.m_isValid) { new (m_data.bytes) T(*other); }
@@ -69,7 +69,7 @@ namespace BlackMisc
}
//! Move assignment.
Optional &operator =(Optional &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
Optional &operator =(Optional &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
{
reset();
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }

View File

@@ -21,7 +21,7 @@ namespace BlackMisc
template<class OBJ, class CONTAINER>
class IOrderableList
{
static_assert(std::is_base_of<IOrderable, OBJ>::value, "OBJ needs to implement IOrderable");
static_assert(std::is_base_of_v<IOrderable, OBJ>, "OBJ needs to implement IOrderable");
public:
//! Sort ascending

View File

@@ -39,7 +39,7 @@ namespace BlackMisc
QString CProcessInfo::processNameFromId(qint64 pid)
{
char name[1024];
proc_name(pid, name, std::extent<decltype(name)>::value);
proc_name(pid, name, std::extent_v<decltype(name)>);
return name;
}
#elif defined(Q_OS_WIN)
@@ -48,7 +48,7 @@ namespace BlackMisc
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, static_cast<DWORD>(pid));
if (! proc) { return {}; }
wchar_t path[1024];
auto len = GetModuleFileNameEx(proc, nullptr, path, std::extent<decltype(path)>::value);
auto len = GetModuleFileNameEx(proc, nullptr, path, std::extent_v<decltype(path)>);
CloseHandle(proc);
if (len <= 0) { return {}; }
return QFileInfo(QString::fromWCharArray(path)).completeBaseName();

View File

@@ -123,7 +123,7 @@ namespace BlackMisc
//! Compare with index given by enum
template<class EnumType> bool contains(EnumType ev) const
{
static_assert(std::is_enum<EnumType>::value, "Argument must be an enum");
static_assert(std::is_enum_v<EnumType>, "Argument must be an enum");
return this->contains(static_cast<int>(ev));
}
@@ -136,14 +136,14 @@ namespace BlackMisc
//! First element casted to given type, usually the PropertIndex enum
template<class CastType> CastType frontCasted() const
{
static_assert(std::is_enum<CastType>::value || std::is_integral<CastType>::value, "CastType must be an enum or integer");
static_assert(std::is_enum_v<CastType> || std::is_integral_v<CastType>, "CastType must be an enum or integer");
return static_cast<CastType>(frontToInt());
}
//! Compare with index given by enum
template<class EnumType> bool startsWithPropertyIndexEnum(EnumType ev) const
{
static_assert(std::is_enum<EnumType>::value, "Argument must be an enum");
static_assert(std::is_enum_v<EnumType>, "Argument must be an enum");
return this->startsWith(static_cast<int>(ev));
}

View File

@@ -188,14 +188,14 @@ namespace BlackMisc
//! First element casted to given type, usually the PropertIndex enum
template<class CastType> CastType frontCasted() const
{
static_assert(std::is_enum<CastType>::value || std::is_integral<CastType>::value, "CastType must be an enum or integer");
static_assert(std::is_enum_v<CastType> || std::is_integral_v<CastType>, "CastType must be an enum or integer");
return static_cast<CastType>(frontToInt());
}
//! Compare with index given by enum
template<class EnumType> bool startsWithPropertyIndexEnum(EnumType ev) const
{
static_assert(std::is_enum<EnumType>::value, "Argument must be an enum");
static_assert(std::is_enum_v<EnumType>, "Argument must be an enum");
return this->startsWith(static_cast<int>(ev));
}

View File

@@ -108,7 +108,7 @@ namespace BlackMisc
bool matchesVariant(const CVariant &value) const;
//! True if this map matches the value
template <typename T, typename = std::enable_if_t<!std::is_same<T, CVariant>::value>>
template <typename T, typename = std::enable_if_t<!std::is_same_v<T, CVariant>>>
bool matches(const T &value) const { return matchesVariant(CVariant::from(value)); }
//! Map

View File

@@ -213,12 +213,12 @@ namespace BlackMisc
//! Create a range from reverse iterators.
CRange<const_reverse_iterator> reverse() const
{
static_assert(std::is_same<decltype(*rbegin()), decltype(*begin())>::value, "see https://dev.swift-project.org/T700");
static_assert(std::is_same_v<decltype(*rbegin()), decltype(*begin())>, "see https://dev.swift-project.org/T700");
return { rbegin(), rend() };
}
//! Implicit conversion to any container of value_type which supports push_back. This will copy elements.
template <class T, class = std::enable_if_t<std::is_convertible<value_type, typename T::value_type>::value>>
template <class T, class = std::enable_if_t<std::is_convertible_v<value_type, typename T::value_type>>>
operator T() const
{
return to<T>();

View File

@@ -76,7 +76,7 @@ namespace BlackMisc
virtual void initialize(IDataLink *dataLink) override
{
CGenericListObserver::initialize(dataLink);
if (std::is_same<U, CAnyMatch>::value) { setFilter({}); }
if (std::is_same_v<U, CAnyMatch>) { setFilter({}); }
}
//! Set filter to choose list elements.

View File

@@ -51,7 +51,7 @@ namespace BlackMisc
template <typename T, typename F, typename G>
QMetaObject::Connection connectOnce(T *sender, F signal, G &&slot)
{
static_assert(! std::is_member_pointer<std::decay_t<G>>::value, "If slot is a pointer to member, a receiver must be supplied");
static_assert(! std::is_member_pointer_v<std::decay_t<G>>, "If slot is a pointer to member, a receiver must be supplied");
return connectOnce(sender, signal, sender, std::forward<G>(slot));
}

View File

@@ -382,11 +382,11 @@ namespace BlackMisc
{
static QString toQString(double n) { return QString::number(n); }
};
template <typename T> struct TString<T, std::enable_if_t<std::is_enum<T>::value>>
template <typename T> struct TString<T, std::enable_if_t<std::is_enum_v<T>>>
{
static QString toQString(T e) { return QString::number(e); }
};
template <typename T> struct TString<T, std::enable_if_t<std::is_convertible<T, QString>::value>>
template <typename T> struct TString<T, std::enable_if_t<std::is_convertible_v<T, QString>>>
{
static QString toQString(const T &v) { return v; }
};

View File

@@ -44,7 +44,7 @@ namespace BlackMisc
//! Such objects should implement \sa ITimestampBased
template<class OBJ, class CONTAINER> class ITimestampObjectList
{
static_assert(std::is_base_of<ITimestampBased, OBJ>::value, "OBJ needs to implement ITimestampBased");
static_assert(std::is_base_of_v<ITimestampBased, OBJ>, "OBJ needs to implement ITimestampBased");
public:
//! Hint if the list is sorted
@@ -451,7 +451,7 @@ namespace BlackMisc
//! Such objects should implement \sa ITimestampWithOffsetBased
template<class OBJ, class CONTAINER> class ITimestampWithOffsetObjectList : public ITimestampObjectList<OBJ, CONTAINER>
{
static_assert(std::is_base_of<ITimestampWithOffsetBased, OBJ>::value, "OBJ needs to implement ITimestampBased");
static_assert(std::is_base_of_v<ITimestampWithOffsetBased, OBJ>, "OBJ needs to implement ITimestampBased");
public:
//! Hint if the list is sorted

View File

@@ -37,7 +37,7 @@ namespace BlackMisc
};
//! \private Dummy that derives from T if T is a class.
template <typename T, bool = std::is_class<T>::value>
template <typename T, bool = std::is_class_v<T>>
struct SyntheticDerived : public T {};
//! \cond
template <typename T>
@@ -61,7 +61,7 @@ namespace BlackMisc
struct TParameter
{
//! Whether the input parameter type T should be passed by value or by const reference.
static constexpr ParameterPassBy passBy = (sizeof(T) <= 16 && std::is_trivially_copy_constructible<T>::value && std::is_trivially_destructible<T>::value) ? ParameterPassBy::Value : ParameterPassBy::ConstRef;
static constexpr ParameterPassBy passBy = (sizeof(T) <= 16 && std::is_trivially_copy_constructible_v<T> && std::is_trivially_destructible_v<T>) ? ParameterPassBy::Value : ParameterPassBy::ConstRef;
};
/*!

View File

@@ -116,14 +116,14 @@ namespace BlackMisc
//! Construct a variant from a value.
template <typename T> static CVariant fromValue(T &&value)
{
static_assert(!std::is_same<CVariant, std::decay_t<T>>::value, "CVariant is an illegal type!");
static_assert(!std::is_same_v<CVariant, std::decay_t<T>>, "CVariant is an illegal type!");
return CVariant(QVariant::fromValue(std::forward<T>(value)));
}
//! Synonym for fromValue().
template <typename T> static CVariant from(T &&value)
{
static_assert(!std::is_same<CVariant, std::decay_t<T>>::value, "CVariant is an illegal type!");
static_assert(!std::is_same_v<CVariant, std::decay_t<T>>, "CVariant is an illegal type!");
return CVariant(QVariant::fromValue(std::forward<T>(value)));
}

View File

@@ -127,7 +127,7 @@ namespace BlackMisc
static bool equalsPropertyByIndex(const T &object, const QVariant &, CPropertyIndexRef, ...) { throw CVariantException(object, "equalsPropertyByIndex"); }
template <typename T>
static int toIcon(const T &object, std::enable_if_t < ! std::is_same<T, CVariant>::value, decltype(static_cast<void>(object.toIcon()), 0) >) { return object.toIcon(); }
static int toIcon(const T &object, std::enable_if_t < ! std::is_same_v<T, CVariant>, decltype(static_cast<void>(object.toIcon()), 0) >) { return object.toIcon(); }
template <typename T>
static int toIcon(const T &object, ...) { throw CVariantException(object, "toIcon"); }
@@ -231,7 +231,7 @@ namespace BlackMisc
IValueObjectMetaInfo *getValueObjectMetaInfo() { return getValueObjectMetaInfo(qMetaTypeId<T>()); }
//! \cond PRIVATE
template <typename T, typename = std::enable_if_t<std::is_base_of<CSequence<typename T::value_type>, T>::value && ! std::is_same<typename T::value_type, CVariant>::value>>
template <typename T, typename = std::enable_if_t<std::is_base_of_v<CSequence<typename T::value_type>, T> && ! std::is_same_v<typename T::value_type, CVariant>>>
void maybeRegisterMetaListConvert(int);
template <typename T>
void maybeRegisterMetaListConvert(...) {}

View File

@@ -256,9 +256,9 @@ namespace BlackMisc
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<decltype(func())>::value, int>) { func(); return QVariant(); }
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<decltype(func())>::value, int>) { return QVariant::fromValue(func()); }
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>(); }