Make it possible to use QPointer<const T>

This is possible with QWeakPointer, so allow it for migrating
code too.

In the process, replace the QPointerBase with a member variable for
simplicity. The functionality of the QPointerBase is replaced
by a TypeSelector template.

Change-Id: I3b4c77bdeda2b863cc33e84a3da8a25bae928c8c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Stephen Kelly 2013-02-10 10:57:43 +01:00 committed by The Qt Project
parent 60cde0bd14
commit cc7239da8d
4 changed files with 33 additions and 35 deletions

3
dist/changes-5.1.0 vendored
View File

@ -64,6 +64,9 @@ QtCore
inside the pattern string, as well as the numerical index of each inside the pattern string, as well as the numerical index of each
named capturing group. named capturing group.
- QPointer
* It is now possible to create a QPointer with a const templated type.
- -
QtGui QtGui

View File

@ -50,56 +50,44 @@ QT_BEGIN_NAMESPACE
class QVariant; class QVariant;
class QPointerBase
{
QWeakPointer<QObject> wp;
protected:
inline QPointerBase() : wp() { }
inline QPointerBase(QObject *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine! (even though public)
inline ~QPointerBase() { }
inline QObject* data() const
{ return wp.data(); }
inline void assign(QObject *p)
{ wp.assign(p); }
inline bool isNull() const
{ return wp.isNull(); }
inline void clear()
{ wp.clear(); }
};
template <class T> template <class T>
class QPointer : private QPointerBase class QPointer
{ {
template<typename U>
struct TypeSelector
{
typedef QObject Type;
};
template<typename U>
struct TypeSelector<const U>
{
typedef const QObject Type;
};
typedef typename TypeSelector<T>::Type QObjectType;
QWeakPointer<QObjectType> wp;
public: public:
inline QPointer() { } inline QPointer() { }
inline QPointer(T *p) : QPointerBase(p) { } 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!
inline ~QPointer() { } inline ~QPointer() { }
inline QPointer<T> &operator=(T* p) inline QPointer<T> &operator=(T* p)
{ QPointerBase::assign(p); return *this; } { wp.assign(static_cast<QObjectType*>(p)); return *this; }
inline T* data() const inline T* data() const
{ return static_cast<T*>(QPointerBase::data()); } { return static_cast<T*>( wp.data()); }
inline T* operator->() const inline T* operator->() const
{ return data(); } { return data(); }
inline T& operator*() const inline T& operator*() const
{ return *data(); } { return *data(); }
inline operator T*() const inline operator T*() const
{ return data(); } { return data(); }
#ifdef Q_QDOC
inline bool isNull() const; inline bool isNull() const
inline void clear(); { return wp.isNull(); }
#else
using QPointerBase::isNull; inline void clear()
using QPointerBase::clear; { wp.clear(); }
#endif
}; };
template <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_MOVABLE_TYPE); template <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_MOVABLE_TYPE);

View File

@ -639,7 +639,7 @@ private:
public: public:
#else #else
template <class X> friend class QSharedPointer; template <class X> friend class QSharedPointer;
friend class QPointerBase; template <class X> friend class QPointer;
#endif #endif
template <class X> template <class X>

View File

@ -65,6 +65,7 @@ private slots:
void threadSafety(); void threadSafety();
void qvariantCast(); void qvariantCast();
void constPointer();
}; };
void tst_QPointer::constructors() void tst_QPointer::constructors()
@ -384,6 +385,12 @@ void tst_QPointer::qvariantCast()
// QPointer<int> sop = qPointerFromVariant<int>(v); // QPointer<int> sop = qPointerFromVariant<int>(v);
} }
void tst_QPointer::constPointer()
{
// Compile-time test that QPointer<const T> works.
QPointer<const QFile> fp = new QFile;
delete fp.data();
}
QTEST_MAIN(tst_QPointer) QTEST_MAIN(tst_QPointer)