mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-27 19:25:49 +08:00
Use _v traits variable aliases (C++17 feature)
This commit is contained in:
@@ -43,8 +43,8 @@ namespace BlackGui
|
|||||||
{
|
{
|
||||||
CListModelBaseNonTemplate::m_sortTieBreakers.push_front(ObjectType::keyIndex());
|
CListModelBaseNonTemplate::m_sortTieBreakers.push_front(ObjectType::keyIndex());
|
||||||
|
|
||||||
constexpr bool hasIntegerKey = std::is_base_of<IDatastoreObjectWithIntegerKey, ObjectType>::value && std::is_same<int, KeyType>::value;
|
constexpr bool hasIntegerKey = std::is_base_of_v<IDatastoreObjectWithIntegerKey, ObjectType> && std::is_same_v<int, KeyType>;
|
||||||
constexpr bool hasStringKey = std::is_base_of<IDatastoreObjectWithStringKey, ObjectType>::value && std::is_base_of<QString, KeyType>::value;
|
constexpr bool hasStringKey = std::is_base_of_v<IDatastoreObjectWithStringKey, ObjectType> && std::is_base_of_v<QString, KeyType>;
|
||||||
static_assert(hasIntegerKey || hasStringKey, "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType");
|
static_assert(hasIntegerKey || hasStringKey, "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ namespace BlackMisc
|
|||||||
template <typename T, typename F>
|
template <typename T, typename F>
|
||||||
void tupleForEachPair(T &&tuple, F &&visitor)
|
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());
|
return Private::tupleForEachPairImpl(std::forward<T>(tuple), std::forward<F>(visitor), seq());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace BlackMisc
|
|||||||
char s[1024] {};
|
char s[1024] {};
|
||||||
auto x = strerror_r(errno, s, sizeof(s));
|
auto x = strerror_r(errno, s, sizeof(s));
|
||||||
setErrorString(QString::fromLocal8Bit(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)
|
#elif defined(Q_OS_WIN32)
|
||||||
|
|||||||
@@ -173,14 +173,14 @@ namespace BlackMisc
|
|||||||
template <class AVIO>
|
template <class AVIO>
|
||||||
CModulator<AVIO>::CModulator() : m_name("default")
|
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>
|
template <class AVIO>
|
||||||
CModulator<AVIO>::CModulator(const QString &name, const BlackMisc::PhysicalQuantities::CFrequency &activeFrequency, const BlackMisc::PhysicalQuantities::CFrequency &standbyFrequency) :
|
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)
|
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>
|
template <class AVIO>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace BlackMisc
|
|||||||
namespace Compare
|
namespace Compare
|
||||||
{
|
{
|
||||||
//! Compare arithmetic values
|
//! 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)
|
int compare(T a, T b)
|
||||||
{
|
{
|
||||||
if (a < b) { return -1; }
|
if (a < b) { return -1; }
|
||||||
@@ -29,7 +29,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Compare enumerators
|
//! 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)
|
int compare(T a, T b)
|
||||||
{
|
{
|
||||||
using UT = std::underlying_type_t<T>;
|
using UT = std::underlying_type_t<T>;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace BlackMisc
|
|||||||
//! Such objects should implement \sa ITimestampBased and \sa IDatastoreObjectWithIntegerKey or \sa IDatastoreObjectWithStringKey
|
//! 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>
|
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 hasIntegerKey = std::is_base_of_v<IDatastoreObjectWithIntegerKey, OBJ> && std::is_same_v<int, KEYTYPE>;
|
||||||
static constexpr bool hasStringKey = std::is_base_of<IDatastoreObjectWithStringKey, OBJ>::value && std::is_base_of<QString, KEYTYPE>::value;
|
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");
|
static_assert(hasIntegerKey || hasStringKey, "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, std::string &s);
|
|||||||
/*!
|
/*!
|
||||||
* Operator for streaming enums to QDBusArgument.
|
* 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)
|
QDBusArgument &operator <<(QDBusArgument &arg, const E &value)
|
||||||
{
|
{
|
||||||
arg.beginStructure();
|
arg.beginStructure();
|
||||||
@@ -45,7 +45,7 @@ QDBusArgument &operator <<(QDBusArgument &arg, const E &value)
|
|||||||
/*!
|
/*!
|
||||||
* Operator for streaming enums from QDBusArgument.
|
* 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)
|
const QDBusArgument &operator >>(const QDBusArgument &arg, E &value)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace BlackMisc
|
|||||||
struct TAssociativityTraits<false, false>
|
struct TAssociativityTraits<false, false>
|
||||||
{
|
{
|
||||||
template <class Key, class>
|
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
|
//! \endcond
|
||||||
}
|
}
|
||||||
@@ -475,7 +475,7 @@ namespace BlackMisc
|
|||||||
template <class Map1, class Map2, class F>
|
template <class Map1, class Map2, class F>
|
||||||
void forEachIntersection(const Map1 &map1, const Map2 &map2, F functor)
|
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; }
|
if (map1.empty() || map2.empty()) { return; }
|
||||||
auto it1 = implementationOf(map1).lowerBound(map2.cbegin().key());
|
auto it1 = implementationOf(map1).lowerBound(map2.cbegin().key());
|
||||||
auto end1 = implementationOf(map1).upperBound((map2.cend() - 1).key());
|
auto end1 = implementationOf(map1).upperBound((map2.cend() - 1).key());
|
||||||
|
|||||||
@@ -71,14 +71,14 @@ namespace BlackMisc
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename F>
|
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();
|
init();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
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();
|
return init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,17 +27,17 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Our own version of C++17 std::invoke().
|
// 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)
|
decltype(auto) invoke(F ptr, T && object)
|
||||||
{
|
{
|
||||||
return std::forward<T>(object).*ptr;
|
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)
|
decltype(auto) invoke(F ptr, T && object, Ts && ... args)
|
||||||
{
|
{
|
||||||
return (std::forward<T>(object).*ptr)(std::forward<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)
|
decltype(auto) invoke(F && func, Ts && ... args)
|
||||||
{
|
{
|
||||||
return std::forward<F>(func)(std::forward<Ts>(args)...);
|
return std::forward<F>(func)(std::forward<Ts>(args)...);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace BlackMisc
|
|||||||
OutputIterator &operator *() { return *this; }
|
OutputIterator &operator *() { return *this; }
|
||||||
|
|
||||||
//! Assignment operator performs the output
|
//! 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; }
|
OutputIterator &operator =(T &&value) { m_func(std::forward<T>(value)); return *this; }
|
||||||
|
|
||||||
//! Copy assignment operator
|
//! 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
|
//! 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> *,
|
std::remove_reference_t<undecayed_type> *,
|
||||||
PointerWrapper>::type;
|
PointerWrapper>::type;
|
||||||
|
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ BLACKMISC_EXPORT QJsonValueRef operator >>(QJsonValueRef json, QByteArray &value
|
|||||||
//! \ingroup JSON
|
//! \ingroup JSON
|
||||||
//! @{
|
//! @{
|
||||||
template<class ENUM>
|
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)
|
&operator<<(QJsonObject &json, std::pair<QString, const ENUM &> value)
|
||||||
{
|
{
|
||||||
json.insert(value.first, QJsonValue(static_cast<int>(value.second)));
|
json.insert(value.first, QJsonValue(static_cast<int>(value.second)));
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
template<class ENUM>
|
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)
|
&operator<<(QJsonObject &json, std::pair<BlackMisc::CExplicitLatin1String, const ENUM &> value)
|
||||||
{
|
{
|
||||||
json[value.first] = QJsonValue(static_cast<int>(value.second));
|
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
|
//! \brief Specialized JSON deserialization for enum
|
||||||
//! \ingroup JSON
|
//! \ingroup JSON
|
||||||
template<class ENUM>
|
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)
|
const &operator>>(const QJsonValue &json, ENUM &value)
|
||||||
{
|
{
|
||||||
value = static_cast<ENUM>(json.toInt());
|
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
|
//! \brief Specialized JSON deserialization for enum
|
||||||
//! \ingroup JSON
|
//! \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)
|
QJsonValueRef operator>>(QJsonValueRef json, ENUM &value)
|
||||||
{
|
{
|
||||||
value = static_cast<ENUM>(json.toInt());
|
value = static_cast<ENUM>(json.toInt());
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace BlackMisc
|
|||||||
LockFreeUniqueWriter &operator =(const T &other) { *m_ptr = other; return *this; }
|
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.
|
//! 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.
|
//! LockFreeUniqueWriter cannot be copied.
|
||||||
//! @{
|
//! @{
|
||||||
@@ -137,7 +137,7 @@ namespace BlackMisc
|
|||||||
LockFreeSharedWriter &operator =(const T &other) { *m_ptr = other; return *this; }
|
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.
|
//! 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.
|
//! 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.
|
//! 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)) {}
|
LockFree(const T &other) : m_ptr(std::make_shared<const T>(other)) {}
|
||||||
|
|
||||||
//! Construct by moving from a T.
|
//! 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.
|
//! LockFree cannot be copied or moved.
|
||||||
//! @{
|
//! @{
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace BlackMisc
|
|||||||
* \param pointer The value of pointer is unimportant. Only the static type T is considered.
|
* \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.
|
* 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); }
|
CLogCategoryList(const T *pointer) : CLogCategoryList(fromClass<T>()) { Q_UNUSED(pointer); }
|
||||||
|
|
||||||
//! Return a copy with another category appended.
|
//! Return a copy with another category appended.
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ namespace BlackMisc
|
|||||||
template <typename M, quint64 Flags = 0>
|
template <typename M, quint64 Flags = 0>
|
||||||
constexpr static CMetaMember<M, Flags> makeMetaMember(M ptrToMember, const char *name = nullptr, int index = 0, MetaFlags<Flags> flags = {})
|
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 };
|
return { ptrToMember, name, index, flags };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,14 +70,14 @@ namespace BlackMisc
|
|||||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||||
Derived *derived() { return static_cast<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()); }
|
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>(); }
|
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 {}; }
|
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"); }
|
void myself(const QVariant &) { qFatal("isMyself should have been handled before reaching here"); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace BlackMisc
|
|||||||
Optional() noexcept {}
|
Optional() noexcept {}
|
||||||
|
|
||||||
//! Construct from a value.
|
//! 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));
|
new (m_data.bytes) T(std::move(value));
|
||||||
m_isValid = true;
|
m_isValid = true;
|
||||||
@@ -39,14 +39,14 @@ namespace BlackMisc
|
|||||||
Optional(std::nullptr_t) noexcept {}
|
Optional(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
//! Copy constructor.
|
//! 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); }
|
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
||||||
m_isValid = other.m_isValid;
|
m_isValid = other.m_isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Move constructor.
|
//! 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)); }
|
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
||||||
m_isValid = other.m_isValid;
|
m_isValid = other.m_isValid;
|
||||||
@@ -60,7 +60,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Copy assignment.
|
//! 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();
|
reset();
|
||||||
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
if (other.m_isValid) { new (m_data.bytes) T(*other); }
|
||||||
@@ -69,7 +69,7 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Move assignment.
|
//! 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();
|
reset();
|
||||||
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace BlackMisc
|
|||||||
template<class OBJ, class CONTAINER>
|
template<class OBJ, class CONTAINER>
|
||||||
class IOrderableList
|
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:
|
public:
|
||||||
//! Sort ascending
|
//! Sort ascending
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace BlackMisc
|
|||||||
QString CProcessInfo::processNameFromId(qint64 pid)
|
QString CProcessInfo::processNameFromId(qint64 pid)
|
||||||
{
|
{
|
||||||
char name[1024];
|
char name[1024];
|
||||||
proc_name(pid, name, std::extent<decltype(name)>::value);
|
proc_name(pid, name, std::extent_v<decltype(name)>);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
#elif defined(Q_OS_WIN)
|
#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));
|
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, static_cast<DWORD>(pid));
|
||||||
if (! proc) { return {}; }
|
if (! proc) { return {}; }
|
||||||
wchar_t path[1024];
|
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);
|
CloseHandle(proc);
|
||||||
if (len <= 0) { return {}; }
|
if (len <= 0) { return {}; }
|
||||||
return QFileInfo(QString::fromWCharArray(path)).completeBaseName();
|
return QFileInfo(QString::fromWCharArray(path)).completeBaseName();
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace BlackMisc
|
|||||||
//! Compare with index given by enum
|
//! Compare with index given by enum
|
||||||
template<class EnumType> bool contains(EnumType ev) const
|
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));
|
return this->contains(static_cast<int>(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,14 +136,14 @@ namespace BlackMisc
|
|||||||
//! First element casted to given type, usually the PropertIndex enum
|
//! First element casted to given type, usually the PropertIndex enum
|
||||||
template<class CastType> CastType frontCasted() const
|
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());
|
return static_cast<CastType>(frontToInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Compare with index given by enum
|
//! Compare with index given by enum
|
||||||
template<class EnumType> bool startsWithPropertyIndexEnum(EnumType ev) const
|
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));
|
return this->startsWith(static_cast<int>(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,14 +188,14 @@ namespace BlackMisc
|
|||||||
//! First element casted to given type, usually the PropertIndex enum
|
//! First element casted to given type, usually the PropertIndex enum
|
||||||
template<class CastType> CastType frontCasted() const
|
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());
|
return static_cast<CastType>(frontToInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Compare with index given by enum
|
//! Compare with index given by enum
|
||||||
template<class EnumType> bool startsWithPropertyIndexEnum(EnumType ev) const
|
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));
|
return this->startsWith(static_cast<int>(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ namespace BlackMisc
|
|||||||
bool matchesVariant(const CVariant &value) const;
|
bool matchesVariant(const CVariant &value) const;
|
||||||
|
|
||||||
//! True if this map matches the value
|
//! 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)); }
|
bool matches(const T &value) const { return matchesVariant(CVariant::from(value)); }
|
||||||
|
|
||||||
//! Map
|
//! Map
|
||||||
|
|||||||
@@ -213,12 +213,12 @@ namespace BlackMisc
|
|||||||
//! Create a range from reverse iterators.
|
//! Create a range from reverse iterators.
|
||||||
CRange<const_reverse_iterator> reverse() const
|
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() };
|
return { rbegin(), rend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Implicit conversion to any container of value_type which supports push_back. This will copy elements.
|
//! 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
|
operator T() const
|
||||||
{
|
{
|
||||||
return to<T>();
|
return to<T>();
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace BlackMisc
|
|||||||
virtual void initialize(IDataLink *dataLink) override
|
virtual void initialize(IDataLink *dataLink) override
|
||||||
{
|
{
|
||||||
CGenericListObserver::initialize(dataLink);
|
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.
|
//! Set filter to choose list elements.
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace BlackMisc
|
|||||||
template <typename T, typename F, typename G>
|
template <typename T, typename F, typename G>
|
||||||
QMetaObject::Connection connectOnce(T *sender, F signal, G &&slot)
|
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));
|
return connectOnce(sender, signal, sender, std::forward<G>(slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -382,11 +382,11 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
static QString toQString(double n) { return QString::number(n); }
|
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); }
|
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; }
|
static QString toQString(const T &v) { return v; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace BlackMisc
|
|||||||
//! Such objects should implement \sa ITimestampBased
|
//! Such objects should implement \sa ITimestampBased
|
||||||
template<class OBJ, class CONTAINER> class ITimestampObjectList
|
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:
|
public:
|
||||||
//! Hint if the list is sorted
|
//! Hint if the list is sorted
|
||||||
@@ -451,7 +451,7 @@ namespace BlackMisc
|
|||||||
//! Such objects should implement \sa ITimestampWithOffsetBased
|
//! Such objects should implement \sa ITimestampWithOffsetBased
|
||||||
template<class OBJ, class CONTAINER> class ITimestampWithOffsetObjectList : public ITimestampObjectList<OBJ, CONTAINER>
|
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:
|
public:
|
||||||
//! Hint if the list is sorted
|
//! Hint if the list is sorted
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace BlackMisc
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! \private Dummy that derives from T if T is a class.
|
//! \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 {};
|
struct SyntheticDerived : public T {};
|
||||||
//! \cond
|
//! \cond
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -61,7 +61,7 @@ namespace BlackMisc
|
|||||||
struct TParameter
|
struct TParameter
|
||||||
{
|
{
|
||||||
//! Whether the input parameter type T should be passed by value or by const reference.
|
//! 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -116,14 +116,14 @@ namespace BlackMisc
|
|||||||
//! Construct a variant from a value.
|
//! Construct a variant from a value.
|
||||||
template <typename T> static CVariant fromValue(T &&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)));
|
return CVariant(QVariant::fromValue(std::forward<T>(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Synonym for fromValue().
|
//! Synonym for fromValue().
|
||||||
template <typename T> static CVariant from(T &&value)
|
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)));
|
return CVariant(QVariant::fromValue(std::forward<T>(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace BlackMisc
|
|||||||
static bool equalsPropertyByIndex(const T &object, const QVariant &, CPropertyIndexRef, ...) { throw CVariantException(object, "equalsPropertyByIndex"); }
|
static bool equalsPropertyByIndex(const T &object, const QVariant &, CPropertyIndexRef, ...) { throw CVariantException(object, "equalsPropertyByIndex"); }
|
||||||
|
|
||||||
template <typename T>
|
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>
|
template <typename T>
|
||||||
static int toIcon(const T &object, ...) { throw CVariantException(object, "toIcon"); }
|
static int toIcon(const T &object, ...) { throw CVariantException(object, "toIcon"); }
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ namespace BlackMisc
|
|||||||
IValueObjectMetaInfo *getValueObjectMetaInfo() { return getValueObjectMetaInfo(qMetaTypeId<T>()); }
|
IValueObjectMetaInfo *getValueObjectMetaInfo() { return getValueObjectMetaInfo(qMetaTypeId<T>()); }
|
||||||
|
|
||||||
//! \cond PRIVATE
|
//! \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);
|
void maybeRegisterMetaListConvert(int);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void maybeRegisterMetaListConvert(...) {}
|
void maybeRegisterMetaListConvert(...) {}
|
||||||
|
|||||||
@@ -256,9 +256,9 @@ namespace BlackMisc
|
|||||||
static CWorker *fromTaskImpl(QObject *owner, const QString &name, int typeId, const std::function<QVariant()> &task);
|
static CWorker *fromTaskImpl(QObject *owner, const QString &name, int typeId, const std::function<QVariant()> &task);
|
||||||
|
|
||||||
template <typename F>
|
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>
|
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>
|
template <typename R>
|
||||||
R resultNoWait() { Q_ASSERT(m_result.canConvert<R>()); return m_result.value<R>(); }
|
R resultNoWait() { Q_ASSERT(m_result.canConvert<R>()); return m_result.value<R>(); }
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ namespace XSwiftBus
|
|||||||
//! "safe" cast from integer to void*
|
//! "safe" cast from integer to void*
|
||||||
template <typename T> void *voidptr_cast(T i)
|
template <typename T> void *voidptr_cast(T i)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral<T>::value, "voidptr_cast expects an integer");
|
static_assert(std::is_integral_v<T>, "voidptr_cast expects an integer");
|
||||||
using intptr_type = std::conditional_t<std::is_signed<T>::value, intptr_t, uintptr_t>;
|
using intptr_type = std::conditional_t<std::is_signed_v<T>, intptr_t, uintptr_t>;
|
||||||
return reinterpret_cast<void *>(static_cast<intptr_type>(i));
|
return reinterpret_cast<void *>(static_cast<intptr_type>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ namespace XSwiftBus
|
|||||||
template <typename T> T intptr_cast(void *p)
|
template <typename T> T intptr_cast(void *p)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral<T>::value, "voidptr_cast returns an integer");
|
static_assert(std::is_integral<T>::value, "voidptr_cast returns an integer");
|
||||||
using intptr_type = std::conditional_t<std::is_signed<T>::value, intptr_t, uintptr_t>;
|
using intptr_type = std::conditional_t<std::is_signed_v<T>, intptr_t, uintptr_t>;
|
||||||
return static_cast<T>(reinterpret_cast<intptr_type>(p));
|
return static_cast<T>(reinterpret_cast<intptr_type>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user