QVariant: move the check for std::nullptr_t a bit up in customConstruct
Avoids having to do work after QMetaType::construct() returns. That can't get the tail-call optimization right now because it is a non- inline non-static member function, so the QMetaType must be spilled to the stack. Change-Id: I3859764fed084846bcb0fffd1703a3ffc723f43f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>bb10
parent
27b1026139
commit
8738d9a6a8
|
|
@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPairVariantInterfaceImpl)
|
||||
|
||||
using QtMetaTypePrivate::isVoid;
|
||||
using QtMetaTypePrivate::isInterfaceFor;
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
@ -828,22 +828,22 @@ bool QMetaType::equals(const void *lhs, const void *rhs) const
|
|||
|
||||
bool QMetaType::isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
|
||||
{
|
||||
return !isVoid(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
|
||||
return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
|
||||
}
|
||||
|
||||
bool QMetaType::isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
|
||||
{
|
||||
return !isVoid(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
|
||||
return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
|
||||
}
|
||||
|
||||
bool QMetaType::isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
|
||||
{
|
||||
return !isVoid(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
|
||||
return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
|
||||
}
|
||||
|
||||
bool QMetaType::isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
|
||||
{
|
||||
return !isVoid(iface) && QtMetaTypePrivate::isDestructible(iface);
|
||||
return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isDestructible(iface);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -116,11 +116,12 @@ template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable =
|
|||
template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; };
|
||||
#endif
|
||||
|
||||
inline bool isVoid(const QtPrivate::QMetaTypeInterface *iface)
|
||||
template <typename T> inline bool isInterfaceFor(const QtPrivate::QMetaTypeInterface *iface)
|
||||
{
|
||||
// void is special because it can't be constructed, copied or destroyed,
|
||||
// but iface->flags doesn't set Needs{Construction,Destruction}.
|
||||
return iface->typeId.loadRelaxed() == QMetaType::Void;
|
||||
// typeId for built-in types are fixed and require no registration
|
||||
static_assert(QMetaTypeId2<T>::IsBuiltIn, "This function only works for built-in types");
|
||||
static constexpr int typeId = QtPrivate::BuiltinMetaType<T>::value;
|
||||
return iface->typeId.loadRelaxed() == typeId;
|
||||
}
|
||||
|
||||
template <typename FPointer>
|
||||
|
|
@ -129,7 +130,7 @@ inline bool checkMetaTypeFlagOrPointer(const QtPrivate::QMetaTypeInterface *ifac
|
|||
// helper to the isXxxConstructible & isDestructible functions below: a
|
||||
// meta type has the trait if the trait is trivial or we have the pointer
|
||||
// to perform the operation
|
||||
Q_ASSERT(!isVoid(iface));
|
||||
Q_ASSERT(!isInterfaceFor<void>(iface));
|
||||
Q_ASSERT(iface->size);
|
||||
return ptr != nullptr || (iface->flags & Flag) == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ static bool isValidMetaTypeForVariant(const QtPrivate::QMetaTypeInterface *iface
|
|||
if (!iface || iface->size == 0)
|
||||
return false;
|
||||
|
||||
Q_ASSERT(!isVoid(iface)); // only void should have size 0
|
||||
Q_ASSERT(!isInterfaceFor<void>(iface)); // only void should have size 0
|
||||
if (!isCopyConstructible(iface) || !isDestructible(iface)) {
|
||||
// all meta types must be copyable (because QVariant is) and
|
||||
// destructible (because QVariant owns it)
|
||||
|
|
@ -243,11 +243,15 @@ static void customConstruct(const QtPrivate::QMetaTypeInterface *iface, QVariant
|
|||
using namespace QtMetaTypePrivate;
|
||||
Q_ASSERT(iface);
|
||||
Q_ASSERT(iface->size);
|
||||
Q_ASSERT(!isVoid(iface));
|
||||
Q_ASSERT(!isInterfaceFor<void>(iface));
|
||||
Q_ASSERT(isCopyConstructible(iface));
|
||||
Q_ASSERT(isDestructible(iface));
|
||||
Q_ASSERT(copy || isDefaultConstructible(iface));
|
||||
|
||||
// need to check for nullptr_t here, as this can get called by fromValue(nullptr). fromValue() uses
|
||||
// std::addressof(value) which in this case returns the address of the nullptr object.
|
||||
d->is_null = !copy || isInterfaceFor<std::nullptr_t>(iface);
|
||||
|
||||
void *dst;
|
||||
if (QVariant::Private::canUseInternalSpace(iface)) {
|
||||
d->is_shared = false;
|
||||
|
|
@ -260,10 +264,6 @@ static void customConstruct(const QtPrivate::QMetaTypeInterface *iface, QVariant
|
|||
|
||||
// now ask QMetaType to construct for us
|
||||
QMetaType(iface).construct(dst, copy);
|
||||
|
||||
// need to check for nullptr_t here, as this can get called by fromValue(nullptr). fromValue() uses
|
||||
// std::addressof(value) which in this case returns the address of the nullptr object.
|
||||
d->is_null = !copy || QMetaType(iface) == QMetaType::fromType<std::nullptr_t>();
|
||||
}
|
||||
|
||||
static void customClear(QVariant::Private *d)
|
||||
|
|
|
|||
Loading…
Reference in New Issue