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
|
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:
|
public:
|
||||||
static QMetaTypeInterface metaType;
|
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>
|
template<typename T>
|
||||||
QMetaTypeInterface QMetaTypeForType<T>::metaType = {
|
QMetaTypeInterface QMetaTypeForType<T>::metaType = {
|
||||||
/*.revision=*/ 0,
|
/*.revision=*/ 0,
|
||||||
@ -2709,54 +2760,15 @@ QMetaTypeInterface QMetaTypeForType<T>::metaType = {
|
|||||||
/*.alignment=*/ alignof(T),
|
/*.alignment=*/ alignof(T),
|
||||||
/*.flags=*/ QMetaTypeTypeFlags<T>::Flags,
|
/*.flags=*/ QMetaTypeTypeFlags<T>::Flags,
|
||||||
/*.metaObject=*/ MetaObjectForType<T>::value(),
|
/*.metaObject=*/ MetaObjectForType<T>::value(),
|
||||||
/*.name=*/ QT_METATYPE_CONSTEXPRLAMDA( -> const char * {
|
/*.name=*/ getName(),
|
||||||
if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
|
|
||||||
return QMetaTypeId2<T>::name;
|
|
||||||
} else {
|
|
||||||
return name.data();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
/*.typeId=*/ BuiltinMetaType<T>::value,
|
/*.typeId=*/ BuiltinMetaType<T>::value,
|
||||||
/*.ref=*/ Q_REFCOUNT_INITIALIZE_STATIC,
|
/*.ref=*/ Q_REFCOUNT_INITIALIZE_STATIC,
|
||||||
/*.deleteSelf=*/ nullptr,
|
/*.deleteSelf=*/ nullptr,
|
||||||
/*.defaultCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::DefaultCtrFn {
|
/*.defaultCtr=*/ getDefaultCtr<T>(),
|
||||||
if constexpr (std::is_default_constructible_v<T>) {
|
/*.copyCtr=*/ getCopyCtr<T>(),
|
||||||
return [](const QMetaTypeInterface *, void *addr) { new (addr) T(); };
|
/*.moveCtr=*/ getMoveCtr<T>(),
|
||||||
} else {
|
/*.dtor=*/ getDtor<T>(),
|
||||||
return nullptr;
|
/*.legacyRegisterOp=*/ getLegacyRegister<T>()
|
||||||
}
|
|
||||||
}),
|
|
||||||
/*.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;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user