From 8026dc6f361b31e36344a3147aac308620287518 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Apr 2016 18:02:25 -0700 Subject: Add support for initializing QSharedPointer from nullptr std::shared_ptr supports it. To resolve an ambiguous overload when a literal 0 is passed as a parameter, the normal constructors needed to be made a template, like std::shared_ptr. Task-number: QTBUG-52569 Change-Id: Id75834dab9ed466e94c7ffff14451417892d2148 Reviewed-by: Marc Mutz --- src/corelib/tools/qsharedpointer.cpp | 20 ++++++++++-- src/corelib/tools/qsharedpointer.h | 7 ++-- src/corelib/tools/qsharedpointer_impl.h | 14 +++++--- .../tools/qsharedpointer/tst_qsharedpointer.cpp | 37 ++++++++++++++++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index d03e3129aa..f420c6237b 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -442,7 +442,7 @@ */ /*! - \fn QSharedPointer::QSharedPointer(T *ptr) + \fn QSharedPointer::QSharedPointer(X *ptr) Creates a QSharedPointer that points to \a ptr. The pointer \a ptr becomes managed by this QSharedPointer and must not be passed to @@ -450,7 +450,7 @@ */ /*! - \fn QSharedPointer::QSharedPointer(T *ptr, Deleter deleter) + \fn QSharedPointer::QSharedPointer(X *ptr, Deleter deleter) Creates a QSharedPointer that points to \a ptr. The pointer \a ptr becomes managed by this QSharedPointer and must not be passed to @@ -486,6 +486,22 @@ \sa clear() */ +/*! + \fn QSharedPointer::QSharedPointer(std::nullptr_t) + \since 5.8 + + Creates a QSharedPointer that is null. This is equivalent to the + QSharedPointer default constructor. +*/ + +/*! + \fn QSharedPointer::QSharedPointer(std::nullptr_t, Deleter) + \since 5.8 + + Creates a QSharedPointer that is null. This is equivalent to the + QSharedPointer default constructor. +*/ + /*! \fn QSharedPointer::QSharedPointer(const QSharedPointer &other) diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index 6742a66939..3e05bf1ece 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -67,9 +67,10 @@ public: // constructors QSharedPointer(); - explicit QSharedPointer(T *ptr); - template - QSharedPointer(T *ptr, Deleter d); + template explicit QSharedPointer(X *ptr); + template QSharedPointer(X *ptr, Deleter d); + QSharedPointer(std::nullptr_t); + template QSharedPointer(std::nullptr_t, Deleter d); QSharedPointer(const QSharedPointer &other); QSharedPointer(const QWeakPointer &other); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 6a5c8f4fe5..b9b29e926d 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -313,16 +313,22 @@ public: inline T &operator*() const { return *data(); } inline T *operator->() const { return data(); } - QSharedPointer() Q_DECL_NOTHROW : value(Q_NULLPTR), d(Q_NULLPTR) {} + Q_DECL_CONSTEXPR QSharedPointer() Q_DECL_NOTHROW : value(nullptr), d(nullptr) { } ~QSharedPointer() { deref(); } - inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept + Q_DECL_CONSTEXPR QSharedPointer(std::nullptr_t) Q_DECL_NOTHROW : value(nullptr), d(nullptr) { } + + template + inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); } - template - inline QSharedPointer(T *ptr, Deleter deleter) : value(ptr) // throws + template + inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws { internalConstruct(ptr, deleter); } + template + QSharedPointer(std::nullptr_t, Deleter) : value(nullptr), d(nullptr) { } + QSharedPointer(const QSharedPointer &other) Q_DECL_NOTHROW : value(other.value), d(other.d) { if (d) ref(); } QSharedPointer &operator=(const QSharedPointer &other) Q_DECL_NOTHROW diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index cefe1e526d..f48e81ed91 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -57,6 +57,7 @@ private slots: void basics_data(); void basics(); void operators(); + void nullptrOps(); void swap(); void moveSemantics(); void useOfForwardDeclared(); @@ -362,6 +363,30 @@ void tst_QSharedPointer::operators() QCOMPARE(qHash(p2), qHash(p2.data())); } +void tst_QSharedPointer::nullptrOps() +{ + QSharedPointer p1(nullptr); + QSharedPointer p2 = nullptr; + QSharedPointer null; + + QVERIFY(p1 == null); + QVERIFY(p2 == null); + QVERIFY(!p1.data()); + QVERIFY(!p2.data()); + + QSharedPointer p3 = p1; + QVERIFY(p3 == null); + QVERIFY(!p3.data()); + + p3 = nullptr; + + // check for non-ambiguity + QSharedPointer p1_zero(0); + QSharedPointer p2_zero = 0; + + p3 = 0; +} + void tst_QSharedPointer::swap() { QSharedPointer p1, p2(new int(42)), control = p2; @@ -1309,6 +1334,18 @@ template int CustomDeleter::callCount = 0; void tst_QSharedPointer::customDeleter() { + { + QSharedPointer ptr(0, &Data::doDelete); + QSharedPointer ptr2(0, &Data::alsoDelete); + QSharedPointer ptr3(0, &Data::virtualDelete); + } + safetyCheck(); + { + QSharedPointer ptr(nullptr, &Data::doDelete); + QSharedPointer ptr2(nullptr, &Data::alsoDelete); + QSharedPointer ptr3(nullptr, &Data::virtualDelete); + } + safetyCheck(); { QSharedPointer ptr(new Data, &Data::doDelete); QSharedPointer ptr2(new Data, &Data::alsoDelete); -- cgit v1.2.3