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>
This commit is contained in:
parent
de389229fa
commit
3f5b5e4859
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user