QVariant: make many more QtCore types nothrow-copyable
All of those are implicitly-shared Qt data types whose copy constructors can't throw and have wide contracts (there aren't even any assertions for validity in any of them). These are all types with a QVariant implicit constructor, except for QCborValue, which is updated on this list so QJsonValue (which has a QVariant constructor) is also legitimately noexcept. To ensure we haven't made a mistake, the Private constructor checks again. Change-Id: I3859764fed084846bcb0fffd17044d8319a45e1f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
3fcb0237dc
commit
e9c9e9225c
@ -1837,7 +1837,7 @@ QUrl::QUrl() : d(nullptr)
|
||||
/*!
|
||||
Constructs a copy of \a other.
|
||||
*/
|
||||
QUrl::QUrl(const QUrl &other) : d(other.d)
|
||||
QUrl::QUrl(const QUrl &other) noexcept : d(other.d)
|
||||
{
|
||||
if (d)
|
||||
d->ref.ref();
|
||||
@ -3227,7 +3227,7 @@ bool QUrl::operator !=(const QUrl &url) const
|
||||
/*!
|
||||
Assigns the specified \a url to this object.
|
||||
*/
|
||||
QUrl &QUrl::operator =(const QUrl &url)
|
||||
QUrl &QUrl::operator =(const QUrl &url) noexcept
|
||||
{
|
||||
if (!d) {
|
||||
if (url.d) {
|
||||
|
@ -143,8 +143,8 @@ public:
|
||||
#endif
|
||||
|
||||
QUrl();
|
||||
QUrl(const QUrl ©);
|
||||
QUrl &operator =(const QUrl ©);
|
||||
QUrl(const QUrl ©) noexcept;
|
||||
QUrl &operator =(const QUrl ©) noexcept;
|
||||
#ifdef QT_NO_URL_CAST_FROM_STRING
|
||||
explicit QUrl(const QString &url, ParsingMode mode = TolerantMode);
|
||||
#else
|
||||
|
@ -335,13 +335,21 @@ template <typename T> inline
|
||||
QVariant::Private::Private(std::piecewise_construct_t, const T &t)
|
||||
: is_shared(!CanUseInternalSpace<T>), is_null(std::is_same_v<T, std::nullptr_t>)
|
||||
{
|
||||
// confirm noexceptness
|
||||
static constexpr bool isNothrowQVariantConstructible = noexcept(QVariant(t));
|
||||
static constexpr bool isNothrowCopyConstructible = std::is_nothrow_copy_constructible_v<T>;
|
||||
static constexpr bool isNothrowCopyAssignable = std::is_nothrow_copy_assignable_v<T>;
|
||||
|
||||
const QtPrivate::QMetaTypeInterface *iface = QtPrivate::qMetaTypeInterfaceForType<T>();
|
||||
Q_ASSERT((quintptr(iface) & 0x3) == 0);
|
||||
packedType = quintptr(iface) >> 2;
|
||||
|
||||
if constexpr (CanUseInternalSpace<T>) {
|
||||
static_assert(isNothrowQVariantConstructible == isNothrowCopyConstructible);
|
||||
static_assert(isNothrowQVariantConstructible == isNothrowCopyAssignable);
|
||||
new (data.data) T(t);
|
||||
} else {
|
||||
static_assert(!isNothrowQVariantConstructible); // we allocate memory, even if T doesn't
|
||||
data.shared = QVariant::PrivateShared::create(QtPrivate::qMetaTypeInterfaceForType<T>());
|
||||
new (data.shared->data()) T(t);
|
||||
}
|
||||
@ -705,7 +713,7 @@ QVariant::QVariant(const QVariant &p)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVariant::QVariant(const QBitArray &val)
|
||||
\fn QVariant::QVariant(const QBitArray &val) noexcept
|
||||
|
||||
Constructs a new variant with a bitarray value, \a val.
|
||||
*/
|
||||
@ -759,7 +767,7 @@ QVariant::QVariant(const QVariant &p)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVariant::QVariant(const QUrl &val)
|
||||
\fn QVariant::QVariant(const QUrl &val) noexcept
|
||||
|
||||
Constructs a new variant with a url value of \a val.
|
||||
*/
|
||||
@ -821,13 +829,13 @@ QVariant::QVariant(const QVariant &p)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVariant::QVariant(const QLocale &l)
|
||||
\fn QVariant::QVariant(const QLocale &l) noexcept
|
||||
|
||||
Constructs a new variant with a locale value, \a l.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVariant::QVariant(const QRegularExpression &re)
|
||||
\fn QVariant::QVariant(const QRegularExpression &re) noexcept
|
||||
|
||||
\since 5.0
|
||||
|
||||
@ -876,7 +884,7 @@ QVariant::QVariant(double val) noexcept : d(std::piecewise_construct_t{}, val) {
|
||||
QVariant::QVariant(float val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
|
||||
QVariant::QVariant(const QByteArray &val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
QVariant::QVariant(const QBitArray &val) : d(std::piecewise_construct_t{}, val) {}
|
||||
QVariant::QVariant(const QBitArray &val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
QVariant::QVariant(const QString &val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
QVariant::QVariant(QChar val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
QVariant::QVariant(const QStringList &val) noexcept : d(std::piecewise_construct_t{}, val) {}
|
||||
@ -913,17 +921,19 @@ QVariant::QVariant(QSizeF s) noexcept(Private::FitsInInternalSize<sizeof(qreal)
|
||||
: d(std::piecewise_construct_t{}, s) {}
|
||||
#endif
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
QVariant::QVariant(const QUrl &u) : d(std::piecewise_construct_t{}, u) {}
|
||||
QVariant::QVariant(const QUrl &u) noexcept : d(std::piecewise_construct_t{}, u) {}
|
||||
#endif
|
||||
QVariant::QVariant(const QLocale &l) : d(std::piecewise_construct_t{}, l) {}
|
||||
QVariant::QVariant(const QLocale &l) noexcept : d(std::piecewise_construct_t{}, l) {}
|
||||
#if QT_CONFIG(regularexpression)
|
||||
QVariant::QVariant(const QRegularExpression &re) : d(std::piecewise_construct_t{}, re) {}
|
||||
QVariant::QVariant(const QRegularExpression &re) noexcept : d(std::piecewise_construct_t{}, re) {}
|
||||
#endif // QT_CONFIG(regularexpression)
|
||||
QVariant::QVariant(QUuid uuid) noexcept(Private::FitsInInternalSize<16>) : d(std::piecewise_construct_t{}, uuid) {}
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
QVariant::QVariant(const QJsonValue &jsonValue) : d(std::piecewise_construct_t{}, jsonValue) {}
|
||||
QVariant::QVariant(const QJsonObject &jsonObject) : d(std::piecewise_construct_t{}, jsonObject) {}
|
||||
QVariant::QVariant(const QJsonArray &jsonArray) : d(std::piecewise_construct_t{}, jsonArray) {}
|
||||
QVariant::QVariant(const QJsonValue &jsonValue) noexcept(Private::FitsInInternalSize<sizeof(CborValueStandIn)>)
|
||||
: d(std::piecewise_construct_t{}, jsonValue)
|
||||
{ static_assert(sizeof(CborValueStandIn) == sizeof(QJsonValue)); }
|
||||
QVariant::QVariant(const QJsonObject &jsonObject) noexcept : d(std::piecewise_construct_t{}, jsonObject) {}
|
||||
QVariant::QVariant(const QJsonArray &jsonArray) noexcept : d(std::piecewise_construct_t{}, jsonArray) {}
|
||||
QVariant::QVariant(const QJsonDocument &jsonDocument) : d(std::piecewise_construct_t{}, jsonDocument) {}
|
||||
#endif // QT_BOOTSTRAPPED
|
||||
#if QT_CONFIG(itemmodel)
|
||||
|
@ -56,6 +56,7 @@ inline T qvariant_cast(const QVariant &);
|
||||
|
||||
class Q_CORE_EXPORT QVariant
|
||||
{
|
||||
struct CborValueStandIn { qint64 n; void *c; int t; };
|
||||
public:
|
||||
struct PrivateShared
|
||||
{
|
||||
@ -206,7 +207,7 @@ public:
|
||||
QVariant(float f) noexcept;
|
||||
|
||||
QVariant(const QByteArray &bytearray) noexcept;
|
||||
QVariant(const QBitArray &bitarray);
|
||||
QVariant(const QBitArray &bitarray) noexcept;
|
||||
QVariant(const QString &string) noexcept;
|
||||
QVariant(const QStringList &stringlist) noexcept;
|
||||
QVariant(QChar qchar) noexcept;
|
||||
@ -226,19 +227,19 @@ public:
|
||||
QVariant(QRect rect) noexcept(Private::FitsInInternalSize<sizeof(int) * 4>);
|
||||
QVariant(QRectF rect) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 4>);
|
||||
#endif
|
||||
QVariant(const QLocale &locale);
|
||||
QVariant(const QLocale &locale) noexcept;
|
||||
#if QT_CONFIG(regularexpression)
|
||||
QVariant(const QRegularExpression &re);
|
||||
QVariant(const QRegularExpression &re) noexcept;
|
||||
#endif // QT_CONFIG(regularexpression)
|
||||
#if QT_CONFIG(easingcurve)
|
||||
QVariant(const QEasingCurve &easing);
|
||||
#endif
|
||||
QVariant(QUuid uuid) noexcept(Private::FitsInInternalSize<16>);
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
QVariant(const QUrl &url);
|
||||
QVariant(const QJsonValue &jsonValue);
|
||||
QVariant(const QJsonObject &jsonObject);
|
||||
QVariant(const QJsonArray &jsonArray);
|
||||
QVariant(const QUrl &url) noexcept;
|
||||
QVariant(const QJsonValue &jsonValue) noexcept(Private::FitsInInternalSize<sizeof(CborValueStandIn)>);
|
||||
QVariant(const QJsonObject &jsonObject) noexcept;
|
||||
QVariant(const QJsonArray &jsonArray) noexcept;
|
||||
QVariant(const QJsonDocument &jsonDocument);
|
||||
#endif // QT_BOOTSTRAPPED
|
||||
#if QT_CONFIG(itemmodel)
|
||||
|
@ -1805,7 +1805,7 @@ QCborValue::QCborValue(QCborTag tag, const QCborValue &tv)
|
||||
/*!
|
||||
Copies the contents of \a other into this object.
|
||||
*/
|
||||
QCborValue::QCborValue(const QCborValue &other)
|
||||
QCborValue::QCborValue(const QCborValue &other) noexcept
|
||||
: n(other.n), container(other.container), t(other.t)
|
||||
{
|
||||
if (container)
|
||||
@ -1899,7 +1899,7 @@ void QCborValue::dispose()
|
||||
/*!
|
||||
Replaces the contents of this QCborObject with a copy of \a other.
|
||||
*/
|
||||
QCborValue &QCborValue::operator=(const QCborValue &other)
|
||||
QCborValue &QCborValue::operator=(const QCborValue &other) noexcept
|
||||
{
|
||||
n = other.n;
|
||||
assignContainer(container, other.container);
|
||||
|
@ -139,12 +139,12 @@ public:
|
||||
// make sure const char* doesn't go call the bool constructor
|
||||
QCborValue(const void *) = delete;
|
||||
|
||||
QCborValue(const QCborValue &other);
|
||||
QCborValue(const QCborValue &other) noexcept;
|
||||
QCborValue(QCborValue &&other) noexcept
|
||||
: n(other.n), container(qExchange(other.container, nullptr)), t(qExchange(other.t, Undefined))
|
||||
{
|
||||
}
|
||||
QCborValue &operator=(const QCborValue &other);
|
||||
QCborValue &operator=(const QCborValue &other) noexcept;
|
||||
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QCborValue)
|
||||
|
||||
void swap(QCborValue &other) noexcept
|
||||
|
@ -138,11 +138,13 @@ QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args)
|
||||
Since QJsonArray is implicitly shared, the copy is shallow
|
||||
as long as the object doesn't get modified.
|
||||
*/
|
||||
QJsonArray::QJsonArray(const QJsonArray &other)
|
||||
{
|
||||
a = other.a;
|
||||
}
|
||||
QJsonArray::QJsonArray(const QJsonArray &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
\since 5.10
|
||||
|
||||
Move-constructs a QJsonArray from \a other.
|
||||
*/
|
||||
QJsonArray::QJsonArray(QJsonArray &&other) noexcept
|
||||
: a(other.a)
|
||||
{
|
||||
@ -152,18 +154,7 @@ QJsonArray::QJsonArray(QJsonArray &&other) noexcept
|
||||
/*!
|
||||
Assigns \a other to this array.
|
||||
*/
|
||||
QJsonArray &QJsonArray::operator =(const QJsonArray &other)
|
||||
{
|
||||
a = other.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QJsonArray::QJsonArray(QJsonArray &&other)
|
||||
\since 5.10
|
||||
|
||||
Move-constructs a QJsonArray from \a other.
|
||||
*/
|
||||
QJsonArray &QJsonArray::operator =(const QJsonArray &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
\fn QJsonArray &QJsonArray::operator =(QJsonArray &&other)
|
||||
|
@ -23,8 +23,8 @@ public:
|
||||
|
||||
~QJsonArray();
|
||||
|
||||
QJsonArray(const QJsonArray &other);
|
||||
QJsonArray &operator =(const QJsonArray &other);
|
||||
QJsonArray(const QJsonArray &other) noexcept;
|
||||
QJsonArray &operator =(const QJsonArray &other) noexcept;
|
||||
|
||||
QJsonArray(QJsonArray &&other) noexcept;
|
||||
|
||||
|
@ -122,11 +122,13 @@ QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args
|
||||
Since QJsonObject is implicitly shared, the copy is shallow
|
||||
as long as the object does not get modified.
|
||||
*/
|
||||
QJsonObject::QJsonObject(const QJsonObject &other)
|
||||
{
|
||||
o = other.o;
|
||||
}
|
||||
QJsonObject::QJsonObject(const QJsonObject &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
\since 5.10
|
||||
|
||||
Move-constructs a QJsonObject from \a other.
|
||||
*/
|
||||
QJsonObject::QJsonObject(QJsonObject &&other) noexcept
|
||||
: o(other.o)
|
||||
{
|
||||
@ -136,18 +138,8 @@ QJsonObject::QJsonObject(QJsonObject &&other) noexcept
|
||||
/*!
|
||||
Assigns \a other to this object.
|
||||
*/
|
||||
QJsonObject &QJsonObject::operator =(const QJsonObject &other)
|
||||
{
|
||||
o = other.o;
|
||||
return *this;
|
||||
}
|
||||
QJsonObject &QJsonObject::operator =(const QJsonObject &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
\fn QJsonObject::QJsonObject(QJsonObject &&other)
|
||||
\since 5.10
|
||||
|
||||
Move-constructs a QJsonObject from \a other.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QJsonObject &QJsonObject::operator =(QJsonObject &&other)
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
|
||||
~QJsonObject();
|
||||
|
||||
QJsonObject(const QJsonObject &other);
|
||||
QJsonObject &operator =(const QJsonObject &other);
|
||||
QJsonObject(const QJsonObject &other) noexcept;
|
||||
QJsonObject &operator =(const QJsonObject &other) noexcept;
|
||||
|
||||
QJsonObject(QJsonObject &&other) noexcept;
|
||||
|
||||
|
@ -247,15 +247,12 @@ QJsonValue::~QJsonValue() = default;
|
||||
/*!
|
||||
Creates a copy of \a other.
|
||||
*/
|
||||
QJsonValue::QJsonValue(const QJsonValue &other)
|
||||
: value(other.value)
|
||||
{
|
||||
}
|
||||
QJsonValue::QJsonValue(const QJsonValue &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
Assigns the value stored in \a other to this object.
|
||||
*/
|
||||
QJsonValue &QJsonValue::operator =(const QJsonValue &other)
|
||||
QJsonValue &QJsonValue::operator =(const QJsonValue &other) noexcept
|
||||
{
|
||||
QJsonValue copy(other);
|
||||
swap(copy);
|
||||
|
@ -51,8 +51,8 @@ public:
|
||||
|
||||
~QJsonValue();
|
||||
|
||||
QJsonValue(const QJsonValue &other);
|
||||
QJsonValue &operator =(const QJsonValue &other);
|
||||
QJsonValue(const QJsonValue &other) noexcept;
|
||||
QJsonValue &operator =(const QJsonValue &other) noexcept;
|
||||
|
||||
QJsonValue(QJsonValue &&other) noexcept;
|
||||
|
||||
|
@ -1072,10 +1072,7 @@ QLocale::QLocale(Language language, Script script, Territory territory)
|
||||
Constructs a QLocale object as a copy of \a other.
|
||||
*/
|
||||
|
||||
QLocale::QLocale(const QLocale &other)
|
||||
{
|
||||
d = other.d;
|
||||
}
|
||||
QLocale::QLocale(const QLocale &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
Destructor
|
||||
@ -1090,11 +1087,7 @@ QLocale::~QLocale()
|
||||
to this QLocale object.
|
||||
*/
|
||||
|
||||
QLocale &QLocale::operator=(const QLocale &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
QLocale &QLocale::operator=(const QLocale &other) noexcept = default;
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
@ -896,9 +896,9 @@ public:
|
||||
explicit QLocale(QStringView name);
|
||||
QLocale(Language language, Territory territory);
|
||||
QLocale(Language language, Script script = AnyScript, Territory territory = AnyTerritory);
|
||||
QLocale(const QLocale &other);
|
||||
QLocale(const QLocale &other) noexcept;
|
||||
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QLocale)
|
||||
QLocale &operator=(const QLocale &other);
|
||||
QLocale &operator=(const QLocale &other) noexcept;
|
||||
~QLocale();
|
||||
|
||||
void swap(QLocale &other) noexcept { d.swap(other.d); }
|
||||
|
@ -1354,10 +1354,7 @@ QRegularExpression::QRegularExpression(const QString &pattern, PatternOptions op
|
||||
|
||||
\sa operator=()
|
||||
*/
|
||||
QRegularExpression::QRegularExpression(const QRegularExpression &re)
|
||||
: d(re.d)
|
||||
{
|
||||
}
|
||||
QRegularExpression::QRegularExpression(const QRegularExpression &re) noexcept = default;
|
||||
|
||||
/*!
|
||||
\fn QRegularExpression::QRegularExpression(QRegularExpression &&re)
|
||||
@ -1386,11 +1383,7 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QRegularExpressionPrivate)
|
||||
Assigns the regular expression \a re to this object, and returns a reference
|
||||
to the copy. Both the pattern and the pattern options are copied.
|
||||
*/
|
||||
QRegularExpression &QRegularExpression::operator=(const QRegularExpression &re)
|
||||
{
|
||||
d = re.d;
|
||||
return *this;
|
||||
}
|
||||
QRegularExpression &QRegularExpression::operator=(const QRegularExpression &re) noexcept = default;
|
||||
|
||||
/*!
|
||||
\fn void QRegularExpression::swap(QRegularExpression &other)
|
||||
|
@ -50,10 +50,10 @@ public:
|
||||
|
||||
QRegularExpression();
|
||||
explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption);
|
||||
QRegularExpression(const QRegularExpression &re);
|
||||
QRegularExpression(const QRegularExpression &re) noexcept;
|
||||
QRegularExpression(QRegularExpression &&re) = default;
|
||||
~QRegularExpression();
|
||||
QRegularExpression &operator=(const QRegularExpression &re);
|
||||
QRegularExpression &operator=(const QRegularExpression &re) noexcept;
|
||||
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRegularExpression)
|
||||
|
||||
void swap(QRegularExpression &other) noexcept { d.swap(other.d); }
|
||||
|
@ -453,7 +453,7 @@ quint32 QBitArray::toUInt32(QSysInfo::Endian endianness, bool *ok) const noexcep
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*! \fn QBitArray::QBitArray(const QBitArray &other)
|
||||
/*! \fn QBitArray::QBitArray(const QBitArray &other) noexcept
|
||||
|
||||
Constructs a copy of \a other.
|
||||
|
||||
@ -465,7 +465,7 @@ quint32 QBitArray::toUInt32(QSysInfo::Endian endianness, bool *ok) const noexcep
|
||||
\sa operator=()
|
||||
*/
|
||||
|
||||
/*! \fn QBitArray &QBitArray::operator=(const QBitArray &other)
|
||||
/*! \fn QBitArray &QBitArray::operator=(const QBitArray &other) noexcept
|
||||
|
||||
Assigns \a other to this bit array and returns a reference to
|
||||
this bit array.
|
||||
|
@ -21,8 +21,8 @@ class Q_CORE_EXPORT QBitArray
|
||||
public:
|
||||
inline QBitArray() noexcept {}
|
||||
explicit QBitArray(qsizetype size, bool val = false);
|
||||
QBitArray(const QBitArray &other) : d(other.d) {}
|
||||
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
|
||||
QBitArray(const QBitArray &other) noexcept : d(other.d) {}
|
||||
inline QBitArray &operator=(const QBitArray &other) noexcept { d = other.d; return *this; }
|
||||
inline QBitArray(QBitArray &&other) noexcept : d(std::move(other.d)) {}
|
||||
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QBitArray)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user