summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-05-29 14:59:09 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-06-08 12:49:01 +0200
commit3f5b5e48595b52000421a339d95d1a30d783aed5 (patch)
tree038c639fa1a7dc695f7ade2a3cb8436105a264d3 /src/corelib/kernel/qmetatype.h
parentde389229fadf3b8c137e534fda5d2c808b94b338 (diff)
Use static function instead of lambda to workaround a MSVC compiler bug
The seemingly useless template parameters are needed to avoid a (distinct) bug in MSVC 2019 < 16.6, and should be removed once we have a newer version in the CI. Task-number: QTBUG-82945 Fixes: QTBUG-83600 Change-Id: I5b22a2259aa16ae90eca7d4f3bd2e4fa1116a73b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h128
1 files changed, 70 insertions, 58 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 3c7781c850..6939adb678 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2682,26 +2682,77 @@ struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
{
};
-template<typename T>
+template<typename S>
class QMetaTypeForType
{
- static const decltype(typenameHelper<T>()) name;
+ static const decltype(typenameHelper<S>()) name;
+
+ template<typename T>
+ static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr()
+ {
+ if constexpr (std::is_default_constructible_v<T>) {
+ return [](const QMetaTypeInterface *, void *addr) { new (addr) T(); };
+ } else {
+ return nullptr;
+ }
+ }
+
+ template<typename T>
+ static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr()
+ {
+ if constexpr (std::is_copy_constructible_v<T>) {
+ return [](const QMetaTypeInterface *, void *addr, const void *other) {
+ new (addr) T(*reinterpret_cast<const T *>(other));
+ };
+ } else {
+ return nullptr;
+ }
+ }
+
+ template<typename T>
+ static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr()
+ {
+ if constexpr (std::is_move_constructible_v<T>) {
+ return [](const QMetaTypeInterface *, void *addr, void *other) {
+ new (addr) T(std::move(*reinterpret_cast<T *>(other)));
+ };
+ } else {
+ return nullptr;
+ }
+ }
+
+ template<typename T>
+ static constexpr QMetaTypeInterface::DtorFn getDtor()
+ {
+ if constexpr (std::is_destructible_v<T>)
+ return [](const QMetaTypeInterface *, void *addr) { reinterpret_cast<T *>(addr)->~T(); };
+ else
+ return nullptr;
+ }
+
+ template<typename T>
+ static constexpr QMetaTypeInterface::LegacyRegisterOp getLegacyRegister()
+ {
+ if constexpr (QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn) {
+ return []() { QMetaTypeId2<T>::qt_metatype_id(); };
+ } else {
+ return nullptr;
+ }
+ }
+
+ static constexpr const char *getName()
+ {
+ if constexpr (bool(QMetaTypeId2<S>::IsBuiltIn)) {
+ return QMetaTypeId2<S>::name;
+ } else {
+ return name.data();
+ }
+ }
public:
static QMetaTypeInterface metaType;
};
-#ifdef Q_CC_CLANG
-// Workaround for https://bugs.llvm.org/show_bug.cgi?id=44554 : Every lambda used for initializing
-// static members need a different signature for explicit instentiation
-#define QT_METATYPE_CONSTEXPRLAMDA(...) [](std::integral_constant<int, __COUNTER__> = {}) constexpr __VA_ARGS__ ()
-#elif defined(Q_CC_MSVC)
-// Workaround a bug with 'if constexpr' not working in lambda that are not generic in MSVC
-#define QT_METATYPE_CONSTEXPRLAMDA(...) [](auto) constexpr __VA_ARGS__ (0)
-#else
-#define QT_METATYPE_CONSTEXPRLAMDA(...) []() constexpr __VA_ARGS__ ()
-#endif
-
template<typename T>
QMetaTypeInterface QMetaTypeForType<T>::metaType = {
/*.revision=*/ 0,
@@ -2709,54 +2760,15 @@ QMetaTypeInterface QMetaTypeForType<T>::metaType = {
/*.alignment=*/ alignof(T),
/*.flags=*/ QMetaTypeTypeFlags<T>::Flags,
/*.metaObject=*/ MetaObjectForType<T>::value(),
- /*.name=*/ QT_METATYPE_CONSTEXPRLAMDA( -> const char * {
- if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
- return QMetaTypeId2<T>::name;
- } else {
- return name.data();
- }
- }),
+ /*.name=*/ getName(),
/*.typeId=*/ BuiltinMetaType<T>::value,
/*.ref=*/ Q_REFCOUNT_INITIALIZE_STATIC,
/*.deleteSelf=*/ nullptr,
- /*.defaultCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::DefaultCtrFn {
- if constexpr (std::is_default_constructible_v<T>) {
- return [](const QMetaTypeInterface *, void *addr) { new (addr) T(); };
- } else {
- return nullptr;
- }
- }),
- /*.copyCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::CopyCtrFn {
- if constexpr (std::is_copy_constructible_v<T>) {
- return [](const QMetaTypeInterface *, void *addr, const void *other) {
- new (addr) T(*reinterpret_cast<const T *>(other));
- };
- } else {
- return nullptr;
- }
- }),
- /*.moveCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::MoveCtrFn {
- if constexpr (std::is_move_constructible_v<T>) {
- return [](const QMetaTypeInterface *, void *addr, void *other) {
- new (addr) T(std::move(*reinterpret_cast<T *>(other)));
- };
- } else {
- return nullptr;
- }
- }),
- /*.dtor=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::DtorFn {
- if constexpr (std::is_destructible_v<T>)
- return [](const QMetaTypeInterface *, void *addr) { reinterpret_cast<T *>(addr)->~T(); };
- else
- return nullptr;
- }),
- /*.legacyRegisterOp=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::LegacyRegisterOp {
- if constexpr (QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn) {
- return []() { QMetaTypeId2<T>::qt_metatype_id(); };
- } else {
- return nullptr;
- }
- })
+ /*.defaultCtr=*/ getDefaultCtr<T>(),
+ /*.copyCtr=*/ getCopyCtr<T>(),
+ /*.moveCtr=*/ getMoveCtr<T>(),
+ /*.dtor=*/ getDtor<T>(),
+ /*.legacyRegisterOp=*/ getLegacyRegister<T>()
};
template<typename T>