QVariant: optimize copying for trivially copyable payloads

If the payload is trivially copyable and is using the internal space,
then it's already been copied by the copying of QVariant::Private. No
further work is needed.

Change-Id: I3859764fed084846bcb0fffd170446a4e474efb7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
Thiago Macieira 2022-07-22 15:17:16 -07:00
parent 011570285a
commit b665ffbce2
1 changed files with 16 additions and 16 deletions

View File

@ -281,6 +281,20 @@ static void customClear(QVariant::Private *d)
}
}
static QVariant::Private clonePrivate(const QVariant::Private &other)
{
QVariant::Private d = other;
if (d.is_shared) {
d.data.shared->ref.ref();
} else if (const QtPrivate::QMetaTypeInterface *iface = d.typeInterface()) {
Q_ASSERT(d.canUseInternalSpace(iface));
// if not trivially copyable, ask to copy
if (iface->copyCtr)
QtMetaTypePrivate::copyConstruct(iface, d.data.data, other.data.data);
}
return d;
}
} // anonymous used to hide QVariant handlers
@ -512,15 +526,8 @@ QVariant::~QVariant()
*/
QVariant::QVariant(const QVariant &p)
: d(p.d)
: d(clonePrivate(p.d))
{
if (d.is_shared) {
d.data.shared->ref.ref();
} else if (const QtPrivate::QMetaTypeInterface *iface = d.typeInterface()) {
// ask QMetaType to copy for us
Q_ASSERT(d.canUseInternalSpace(iface));
d.type().construct(d.data.data, p.constData());
}
}
/*!
@ -1004,14 +1011,7 @@ QVariant &QVariant::operator=(const QVariant &variant)
return *this;
clear();
if (variant.d.is_shared) {
variant.d.data.shared->ref.ref();
d = variant.d;
} else {
d = variant.d;
d.type().construct(d.data.data, variant.constData());
}
d = clonePrivate(variant.d);
return *this;
}