QPointer: ensure construction from nullptr is constinit'able
Construction from nullptr wasn't, before, because it was using the QPointer(T*) constructor, which cannot be constexpr. Add a constexpr QPointer(std::nullptr_t) constructor to enable this use-case. This requires to mark the (T*) constructor as Q_WEAK_OVERLOAD, otherwise legacy construction from a literal 0 would be ambiguous. No documentation changes needed, as the set of valid expressions (apart from constinit'ing) has not changed. Mention the nullptr ctor, though, without \since. Add a test to confirm that contruction from derived still works. Change-Id: If9d5281f6eca0c408a69f03fecba64a70a0c9cf0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
c0ba4ad49d
commit
1219dbcd12
@ -76,6 +76,7 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <class T> QPointer<T>::QPointer()
|
\fn template <class T> QPointer<T>::QPointer()
|
||||||
|
\fn template <class T> QPointer<T>::QPointer(std::nullptr_t)
|
||||||
|
|
||||||
Constructs a guarded pointer with value \nullptr.
|
Constructs a guarded pointer with value \nullptr.
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ public:
|
|||||||
Q_NODISCARD_CTOR
|
Q_NODISCARD_CTOR
|
||||||
QPointer() noexcept = default;
|
QPointer() noexcept = default;
|
||||||
Q_NODISCARD_CTOR
|
Q_NODISCARD_CTOR
|
||||||
|
constexpr QPointer(std::nullptr_t) noexcept : QPointer{} {}
|
||||||
|
Q_WEAK_OVERLOAD
|
||||||
|
Q_NODISCARD_CTOR
|
||||||
inline QPointer(T *p) : wp(p, true) { }
|
inline QPointer(T *p) : wp(p, true) { }
|
||||||
// compiler-generated copy/move ctor/assignment operators are fine!
|
// compiler-generated copy/move ctor/assignment operators are fine!
|
||||||
// compiler-generated dtor is fine!
|
// compiler-generated dtor is fine!
|
||||||
|
@ -39,15 +39,22 @@ private slots:
|
|||||||
// check that nullptr QPointer construction is Q_CONSTINIT:
|
// check that nullptr QPointer construction is Q_CONSTINIT:
|
||||||
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file1;
|
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file1;
|
||||||
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file2 = {};
|
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file2 = {};
|
||||||
|
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file3 = nullptr;
|
||||||
|
[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file4 = 0; // legacy nullptr
|
||||||
|
|
||||||
void tst_QPointer::constructors()
|
void tst_QPointer::constructors()
|
||||||
{
|
{
|
||||||
|
struct Derived : QObject {};
|
||||||
|
Derived derived;
|
||||||
|
|
||||||
QPointer<QObject> p1;
|
QPointer<QObject> p1;
|
||||||
QPointer<QObject> p2(this);
|
QPointer<QObject> p2(this);
|
||||||
QPointer<QObject> p3(p2);
|
QPointer<QObject> p3(p2);
|
||||||
|
QPointer<QObject> p4 = &derived;
|
||||||
QCOMPARE(p1, QPointer<QObject>(0));
|
QCOMPARE(p1, QPointer<QObject>(0));
|
||||||
QCOMPARE(p2, QPointer<QObject>(this));
|
QCOMPARE(p2, QPointer<QObject>(this));
|
||||||
QCOMPARE(p3, QPointer<QObject>(this));
|
QCOMPARE(p3, QPointer<QObject>(this));
|
||||||
|
QCOMPARE(p4, &derived);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QPointer::ctad()
|
void tst_QPointer::ctad()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user