diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-05-29 14:59:09 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-06-08 12:49:01 +0200 |
commit | 3f5b5e48595b52000421a339d95d1a30d783aed5 (patch) | |
tree | 038c639fa1a7dc695f7ade2a3cb8436105a264d3 /src/corelib/kernel/qmetatype.h | |
parent | de389229fadf3b8c137e534fda5d2c808b94b338 (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.h | 128 |
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> |