src/corelib/tools/qscopedpointer.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QSCOPEDPOINTER_H
       
    43 #define QSCOPEDPOINTER_H
       
    44 
       
    45 #include <QtCore/qglobal.h>
       
    46 
       
    47 QT_BEGIN_HEADER
       
    48 QT_BEGIN_NAMESPACE
       
    49 QT_MODULE(Core)
       
    50 
       
    51 template <typename T>
       
    52 struct QScopedPointerDeleter
       
    53 {
       
    54     static inline void cleanup(T *pointer)
       
    55     {
       
    56         // Enforce a complete type.
       
    57         // If you get a compile error here, read the secion on forward declared
       
    58         // classes in the QScopedPointer documentation.
       
    59         typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
       
    60         (void) sizeof(IsIncompleteType);
       
    61 
       
    62         delete pointer;
       
    63     }
       
    64 };
       
    65 
       
    66 template <typename T>
       
    67 struct QScopedPointerArrayDeleter
       
    68 {
       
    69     static inline void cleanup(T *pointer)
       
    70     {
       
    71         // Enforce a complete type.
       
    72         // If you get a compile error here, read the secion on forward declared
       
    73         // classes in the QScopedPointer documentation.
       
    74         typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
       
    75         (void) sizeof(IsIncompleteType);
       
    76 
       
    77         delete [] pointer;
       
    78     }
       
    79 };
       
    80 
       
    81 struct QScopedPointerPodDeleter
       
    82 {
       
    83     static inline void cleanup(void *pointer) { if (pointer) qFree(pointer); }
       
    84 };
       
    85 
       
    86 template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
       
    87 class QScopedPointer
       
    88 {
       
    89 #ifndef Q_CC_NOKIAX86
       
    90     typedef T *QScopedPointer:: *RestrictedBool;
       
    91 #endif
       
    92 public:
       
    93     explicit inline QScopedPointer(T *p = 0) : d(p)
       
    94     {
       
    95     }
       
    96 
       
    97     inline ~QScopedPointer()
       
    98     {
       
    99         T *oldD = this->d;
       
   100         Cleanup::cleanup(oldD);
       
   101         this->d = 0;
       
   102     }
       
   103 
       
   104     inline T &operator*() const
       
   105     {
       
   106         Q_ASSERT(d);
       
   107         return *d;
       
   108     }
       
   109 
       
   110     inline T *operator->() const
       
   111     {
       
   112         Q_ASSERT(d);
       
   113         return d;
       
   114     }
       
   115 
       
   116     inline bool operator==(const QScopedPointer<T, Cleanup> &other) const
       
   117     {
       
   118         return d == other.d;
       
   119     }
       
   120 
       
   121     inline bool operator!=(const QScopedPointer<T, Cleanup> &other) const
       
   122     {
       
   123         return d != other.d;
       
   124     }
       
   125 
       
   126     inline bool operator!() const
       
   127     {
       
   128         return !d;
       
   129     }
       
   130 
       
   131 #if defined(Q_CC_NOKIAX86) || defined(Q_QDOC)
       
   132     inline operator bool() const
       
   133     {
       
   134         return isNull() ? 0 : &QScopedPointer::d;
       
   135     }
       
   136 #else
       
   137     inline operator RestrictedBool() const
       
   138     {
       
   139         return isNull() ? 0 : &QScopedPointer::d;
       
   140     }
       
   141 #endif
       
   142 
       
   143     inline T *data() const
       
   144     {
       
   145         return d;
       
   146     }
       
   147 
       
   148     inline bool isNull() const
       
   149     {
       
   150         return !d;
       
   151     }
       
   152 
       
   153     inline void reset(T *other = 0)
       
   154     {
       
   155         if (d == other)
       
   156             return;
       
   157         T *oldD = d;
       
   158         d = other;
       
   159         Cleanup::cleanup(oldD);
       
   160     }
       
   161 
       
   162     inline T *take()
       
   163     {
       
   164         T *oldD = d;
       
   165         d = 0;
       
   166         return oldD;
       
   167     }
       
   168 
       
   169     inline void swap(QScopedPointer<T, Cleanup> &other)
       
   170     {
       
   171         qSwap(d, other.d);
       
   172     }
       
   173 
       
   174     typedef T *pointer;
       
   175 
       
   176 protected:
       
   177     T *d;
       
   178 
       
   179 private:
       
   180     Q_DISABLE_COPY(QScopedPointer)
       
   181 };
       
   182 
       
   183 template <class T, class Cleanup>
       
   184 Q_INLINE_TEMPLATE void qSwap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2)
       
   185 { p1.swap(p2); }
       
   186 
       
   187 template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
       
   188 class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
       
   189 {
       
   190 public:
       
   191     explicit inline QScopedArrayPointer(T *p = 0)
       
   192         : QScopedPointer<T, Cleanup>(p)
       
   193     {
       
   194     }
       
   195 
       
   196     inline T &operator[](int i)
       
   197     {
       
   198         return this->d[i];
       
   199     }
       
   200 
       
   201     inline const T &operator[](int i) const
       
   202     {
       
   203         return this->d[i];
       
   204     }
       
   205 
       
   206     inline bool operator==(const QScopedArrayPointer<T, Cleanup> &other) const
       
   207     {
       
   208         return this->d == other.d;
       
   209     }
       
   210 
       
   211     inline bool operator!=(const QScopedArrayPointer<T, Cleanup> &other) const
       
   212     {
       
   213         return this->d != other.d;
       
   214     }
       
   215 
       
   216 private:
       
   217     Q_DISABLE_COPY(QScopedArrayPointer)
       
   218 };
       
   219 
       
   220 /* Internal helper class - exposes the data through data_ptr (legacy from QShared).
       
   221    Required for some internal Qt classes, do not use otherwise. */
       
   222 template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
       
   223 class QCustomScopedPointer : public QScopedPointer<T, Cleanup>
       
   224 {
       
   225 public:
       
   226     explicit inline QCustomScopedPointer(T *p = 0)
       
   227         : QScopedPointer<T, Cleanup>(p)
       
   228     {
       
   229     }
       
   230 
       
   231     inline T *&data_ptr()
       
   232     {
       
   233         return this->d;
       
   234     }
       
   235 
       
   236     inline bool operator==(const QCustomScopedPointer<T, Cleanup> &other) const
       
   237     {
       
   238         return this->d == other.d;
       
   239     }
       
   240 
       
   241     inline bool operator!=(const QCustomScopedPointer<T, Cleanup> &other) const
       
   242     {
       
   243         return this->d != other.d;
       
   244     }
       
   245 
       
   246 private:
       
   247     Q_DISABLE_COPY(QCustomScopedPointer)
       
   248 };
       
   249 
       
   250 /* Internal helper class - a handler for QShared* classes, to be used in QCustomScopedPointer */
       
   251 template <typename T>
       
   252 class QScopedPointerSharedDeleter
       
   253 {
       
   254 public:
       
   255     static inline void cleanup(T *d)
       
   256     {
       
   257         if (d && !d->ref.deref())
       
   258             delete d;
       
   259     }
       
   260 };
       
   261 
       
   262 /* Internal.
       
   263    This class is basically a scoped pointer pointing to a ref-counted object
       
   264  */
       
   265 template <typename T>
       
   266 class QScopedSharedPointer : public QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> >
       
   267 {
       
   268 public:
       
   269     explicit inline QScopedSharedPointer(T *p = 0)
       
   270         : QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> >(p)
       
   271     {
       
   272     }
       
   273 
       
   274     inline void detach()
       
   275     {
       
   276         qAtomicDetach(this->d);
       
   277     }
       
   278 
       
   279     inline void assign(T *other)
       
   280     {
       
   281         if (this->d == other)
       
   282             return;
       
   283         if (other)
       
   284             other->ref.ref();
       
   285         T *oldD = this->d;
       
   286         this->d = other;
       
   287         QScopedPointerSharedDeleter<T>::cleanup(oldD);
       
   288     }
       
   289 
       
   290     inline bool operator==(const QScopedSharedPointer<T> &other) const
       
   291     {
       
   292         return this->d == other.d;
       
   293     }
       
   294 
       
   295     inline bool operator!=(const QScopedSharedPointer<T> &other) const
       
   296     {
       
   297         return this->d != other.d;
       
   298     }
       
   299 
       
   300 private:
       
   301     Q_DISABLE_COPY(QScopedSharedPointer)
       
   302 };
       
   303 
       
   304 QT_END_NAMESPACE
       
   305 QT_END_HEADER
       
   306 
       
   307 #endif // QSCOPEDPOINTER_H