diff options
Diffstat (limited to 'src/corelib/tools/qscopedpointer.h')
-rw-r--r-- | src/corelib/tools/qscopedpointer.h | 118 |
1 files changed, 90 insertions, 28 deletions
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index fc8f9e2..62daacb 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -49,8 +49,46 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) template <typename T> +struct QScopedPointerDeleter +{ + static inline void cleanup(T *pointer) + { + // Enforce a complete type. + // If you get a compile error here, read the secion on forward declared + // classes in the QScopedPointer documentation. + typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; + (void) sizeof(IsIncompleteType); + + delete pointer; + } +}; + +template <typename T> +struct QScopedPointerArrayDeleter +{ + static inline void cleanup(T *pointer) + { + // Enforce a complete type. + // If you get a compile error here, read the secion on forward declared + // classes in the QScopedPointer documentation. + typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; + (void) sizeof(IsIncompleteType); + + delete [] pointer; + } +}; + +struct QScopedPointerPodDeleter +{ + static inline void cleanup(void *pointer) { if (pointer) qFree(pointer); } +}; + +template <typename T, typename Cleanup = QScopedPointerDeleter<T> > class QScopedPointer { +#ifndef Q_CC_NOKIAX86 + typedef T *QScopedPointer:: *RestrictedBool; +#endif public: explicit inline QScopedPointer(T *p = 0) : d(p) { @@ -58,16 +96,20 @@ public: inline ~QScopedPointer() { - delete d; + T *oldD = this->d; + Cleanup::cleanup(oldD); + this->d = 0; } inline T &operator*() const { + Q_ASSERT(d); return *d; } inline T *operator->() const { + Q_ASSERT(d); return d; } @@ -81,10 +123,17 @@ public: return d != other.d; } +#if defined(Q_CC_NOKIAX86) || defined(Q_QDOC) inline operator bool() const { - return d; + return isNull() ? 0 : &QScopedPointer::d; + } +#else + inline operator RestrictedBool() const + { + return isNull() ? 0 : &QScopedPointer::d; } +#endif inline T *data() const { @@ -98,9 +147,11 @@ public: inline void reset(T *other = 0) { + if (d == other) + return; T *oldD = d; d = other; - delete oldD; + Cleanup::cleanup(oldD); } inline T *take() @@ -117,37 +168,52 @@ private: Q_DISABLE_COPY(QScopedPointer) }; -/* internal class - allows special handling for resetting and cleaning the pointer */ -template <typename T, typename CustomHandler> -class QScopedCustomPointer : public QScopedPointer<T> +template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> > +class QScopedArrayPointer : public QScopedPointer<T, Cleanup> { public: - inline QScopedCustomPointer(T *p = 0) - : QScopedPointer<T>(p) + explicit inline QScopedArrayPointer(T *p = 0) + : QScopedPointer<T, Cleanup>(p) { } - inline ~QScopedCustomPointer() + inline T &operator[](int i) { - T *oldD = this->d; - this->d = 0; - CustomHandler::cleanup(oldD); + return this->d[i]; } - inline void reset(T *other = 0) + inline const T &operator[](int i) const + { + return this->d[i]; + } + +private: + Q_DISABLE_COPY(QScopedArrayPointer) +}; + +/* Internal helper class - exposes the data through data_ptr (legacy from QShared). + Required for some internal Qt classes, do not use otherwise. */ +template <typename T, typename Cleanup = QScopedPointerDeleter<T> > +class QCustomScopedPointer : public QScopedPointer<T, Cleanup> +{ +public: + explicit inline QCustomScopedPointer(T *p = 0) + : QScopedPointer<T, Cleanup>(p) { - CustomHandler::reset(this->d, other); } inline T *&data_ptr() { return this->d; } + +private: + Q_DISABLE_COPY(QCustomScopedPointer) }; -/* Internal helper class - a handler for QShared* classes, to be used in QScopedCustomPointer */ +/* Internal helper class - a handler for QShared* classes, to be used in QCustomScopedPointer */ template <typename T> -class QScopedSharedPointerHandler +class QScopedPointerSharedDeleter { public: static inline void cleanup(T *d) @@ -155,24 +221,17 @@ public: if (d && !d->ref.deref()) delete d; } - - static inline void reset(T *&d, T *other) - { - T *oldD = d; - d = other; - cleanup(oldD); - } }; -/* Internal. This should really have been a typedef, but you can't have a templated typedef :) +/* Internal. This class is basically a scoped pointer pointing to a ref-counted object */ template <typename T> -class QScopedSharedPointer : public QScopedCustomPointer<T, QScopedSharedPointerHandler<T> > +class QScopedSharedPointer : public QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> > { public: - inline QScopedSharedPointer(T *p = 0) - : QScopedCustomPointer<T, QScopedSharedPointerHandler<T> >(p) + explicit inline QScopedSharedPointer(T *p = 0) + : QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> >(p) { } @@ -189,8 +248,11 @@ public: other->ref.ref(); T *oldD = this->d; this->d = other; - QScopedSharedPointerHandler<T>::cleanup(oldD); + QScopedPointerSharedDeleter<T>::cleanup(oldD); } + +private: + Q_DISABLE_COPY(QScopedSharedPointer) }; QT_END_NAMESPACE |