- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qshareddata.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    00039 **
    00040 ****************************************************************************/
    00041
    00042 #ifndef QSHAREDDATA_H
    00043 #define QSHAREDDATA_H
    00044
    00045 #include <QtCore/qglobal.h>
    00046 #include <QtCore/qatomic.h>
    00047
    00048 QT_BEGIN_HEADER
    00049
    00050 QT_BEGIN_NAMESPACE
    00051
    00052 QT_MODULE(Core)
    00053
    00054 template <class T> class QSharedDataPointer;
    00055
    00056 class Q_CORE_EXPORT QSharedData
    00057 {
    00058 public:
    00059     mutable QAtomicInt ref;
    00060
    00061     inline QSharedData() : ref(0) { }
    00062     inline QSharedData(const QSharedData &) : ref(0) { }
    00063
    00064 private:
    00065     // using the assignment operator would lead to corruption in the ref-counting
    00066     QSharedData &operator=(const QSharedData &);
    00067 };
    00068
    00069 template <class T> class QSharedDataPointer
    00070 {
    00071 public:
    00072     typedef T Type;
    00073     typedef T *pointer;
    00074
    00075     inline void detach() { if (d && d->ref != 1) detach_helper(); }
    00076     inline T &operator*() { detach(); return *d; }
    00077     inline const T &operator*() const { return *d; }
    00078     inline T *operator->() { detach(); return d; }
    00079     inline const T *operator->() const { return d; }
    00080     inline operator T *() { detach(); return d; }
    00081     inline operator const T *() const { return d; }
    00082     inline T *data() { detach(); return d; }
    00083     inline const T *data() const { return d; }
    00084     inline const T *constData() const { return d; }
    00085
    00086     inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
    00087     inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
    00088
    00089     inline QSharedDataPointer() { d = 0; }
    00090     inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
    00091
    00092     explicit QSharedDataPointer(T *data);
    00093     inline QSharedDataPointer(const QSharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
    00094     inline QSharedDataPointer<T> & operator=(const QSharedDataPointer<T> &o) {
    00095         if (o.d != d) {
    00096             if (o.d)
    00097                 o.d->ref.ref();
    00098             T *old = d;
    00099             d = o.d;
    00100             if (old && !old->ref.deref())
    00101                 delete old;
    00102         }
    00103         return *this;
    00104     }
    00105     inline QSharedDataPointer &operator=(T *o) {
    00106         if (o != d) {
    00107             if (o)
    00108                 o->ref.ref();
    00109             T *old = d;
    00110             d = o;
    00111             if (old && !old->ref.deref())
    00112                 delete old;
    00113         }
    00114         return *this;
    00115     }
    00116
    00117     inline bool operator!() const { return !d; }
    00118
    00119     inline void swap(QSharedDataPointer &other)
    00120     { qSwap(d, other.d); }
    00121
    00122 protected:
    00123     T *clone();
    00124
    00125 private:
    00126     void detach_helper();
    00127
    00128     T *d;
    00129 };
    00130
    00131 template <class T> class QExplicitlySharedDataPointer
    00132 {
    00133 public:
    00134     typedef T Type;
    00135     typedef T *pointer;
    00136
    00137     inline T &operator*() const { return *d; }
    00138     inline T *operator->() { return d; }
    00139     inline T *operator->() const { return d; }
    00140     inline T *data() const { return d; }
    00141     inline const T *constData() const { return d; }
    00142
    00143     inline void detach() { if (d && d->ref != 1) detach_helper(); }
    00144
    00145     inline void reset()
    00146     {
    00147         if(d && !d->ref.deref())
    00148             delete d;
    00149
    00150         d = 0;
    00151     }
    00152
    00153     inline operator bool () const { return d != 0; }
    00154
    00155     inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
    00156     inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
    00157     inline bool operator==(const T *ptr) const { return d == ptr; }
    00158     inline bool operator!=(const T *ptr) const { return d != ptr; }
    00159
    00160     inline QExplicitlySharedDataPointer() { d = 0; }
    00161     inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
    00162
    00163     explicit QExplicitlySharedDataPointer(T *data);
    00164     inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
    00165
    00166 #ifndef QT_NO_MEMBER_TEMPLATES
    00167     template<class X>
    00168     inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
    00169     {
    00170         if(d)
    00171             d->ref.ref();
    00172     }
    00173 #endif
    00174
    00175     inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
    00176         if (o.d != d) {
    00177             if (o.d)
    00178                 o.d->ref.ref();
    00179             T *old = d;
    00180             d = o.d;
    00181             if (old && !old->ref.deref())
    00182                 delete old;
    00183         }
    00184         return *this;
    00185     }
    00186     inline QExplicitlySharedDataPointer &operator=(T *o) {
    00187         if (o != d) {
    00188             if (o)
    00189                 o->ref.ref();
    00190             T *old = d;
    00191             d = o;
    00192             if (old && !old->ref.deref())
    00193                 delete old;
    00194         }
    00195         return *this;
    00196     }
    00197
    00198     inline bool operator!() const { return !d; }
    00199
    00200     inline void swap(QExplicitlySharedDataPointer &other)
    00201     { qSwap(d, other.d); }
    00202
    00203 protected:
    00204     T *clone();
    00205
    00206 private:
    00207     void detach_helper();
    00208
    00209     T *d;
    00210 };
    00211
    00212 template <class T>
    00213 Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
    00214 { if (d) d->ref.ref(); }
    00215
    00216 template <class T>
    00217 Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
    00218 {
    00219     return new T(*d);
    00220 }
    00221
    00222 template <class T>
    00223 Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
    00224 {
    00225     T *x = clone();
    00226     x->ref.ref();
    00227     if (!d->ref.deref())
    00228         delete d;
    00229     d = x;
    00230 }
    00231
    00232 template <class T>
    00233 Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
    00234 {
    00235     return new T(*d);
    00236 }
    00237
    00238 template <class T>
    00239 Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
    00240 {
    00241     T *x = clone();
    00242     x->ref.ref();
    00243     if (!d->ref.deref())
    00244         delete d;
    00245     d = x;
    00246 }
    00247
    00248 template <class T>
    00249 Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
    00250 { if (d) d->ref.ref(); }
    00251
    00252 template <class T>
    00253 Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
    00254 { p1.swap(p2); }
    00255
    00256 template <class T>
    00257 Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2)
    00258 { p1.swap(p2); }
    00259
    00260 QT_END_NAMESPACE
    00261
    00262 QT_END_HEADER
    00263
    00264 #endif // QSHAREDDATA_H