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 <marc.mutz@kdab.com>
bb10
Thiago Macieira 2016-04-13 18:02:25 -07:00
parent c22fcf03fb
commit 8026dc6f36
4 changed files with 69 additions and 9 deletions

View File

@ -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<T> &other)

View File

@ -67,9 +67,10 @@ public:
// constructors
QSharedPointer();
explicit QSharedPointer(T *ptr);
template<typename Deleter>
QSharedPointer(T *ptr, Deleter d);
template <typename X> explicit QSharedPointer(X *ptr);
template <typename X, typename Deleter> QSharedPointer(X *ptr, Deleter d);
QSharedPointer(std::nullptr_t);
template <typename Deleter> QSharedPointer(std::nullptr_t, Deleter d);
QSharedPointer(const QSharedPointer<T> &other);
QSharedPointer(const QWeakPointer<T> &other);

View File

@ -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 <class X>
inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept
{ internalConstruct(ptr, QtSharedPointer::NormalDeleter()); }
template <typename Deleter>
inline QSharedPointer(T *ptr, Deleter deleter) : value(ptr) // throws
template <class X, typename Deleter>
inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws
{ internalConstruct(ptr, deleter); }
template <typename Deleter>
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

View File

@ -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<char> p1(nullptr);
QSharedPointer<char> p2 = nullptr;
QSharedPointer<char> null;
QVERIFY(p1 == null);
QVERIFY(p2 == null);
QVERIFY(!p1.data());
QVERIFY(!p2.data());
QSharedPointer<char> p3 = p1;
QVERIFY(p3 == null);
QVERIFY(!p3.data());
p3 = nullptr;
// check for non-ambiguity
QSharedPointer<char> p1_zero(0);
QSharedPointer<char> p2_zero = 0;
p3 = 0;
}
void tst_QSharedPointer::swap()
{
QSharedPointer<int> p1, p2(new int(42)), control = p2;
@ -1309,6 +1334,18 @@ template<typename T> int CustomDeleter<T>::callCount = 0;
void tst_QSharedPointer::customDeleter()
{
{
QSharedPointer<Data> ptr(0, &Data::doDelete);
QSharedPointer<Data> ptr2(0, &Data::alsoDelete);
QSharedPointer<Data> ptr3(0, &Data::virtualDelete);
}
safetyCheck();
{
QSharedPointer<Data> ptr(nullptr, &Data::doDelete);
QSharedPointer<Data> ptr2(nullptr, &Data::alsoDelete);
QSharedPointer<Data> ptr3(nullptr, &Data::virtualDelete);
}
safetyCheck();
{
QSharedPointer<Data> ptr(new Data, &Data::doDelete);
QSharedPointer<Data> ptr2(new Data, &Data::alsoDelete);