QtCore/qshareddata.h Source File

qshareddata.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QSHAREDDATA_H
43 #define QSHAREDDATA_H
44 
45 #include <QtCore/qglobal.h>
46 #include <QtCore/qatomic.h>
47 
49 
51 
52 QT_MODULE(Core)
53 
54 template <class T> class QSharedDataPointer;
55 
56 class Q_CORE_EXPORT QSharedData
57 {
58 public:
59  mutable QAtomicInt ref;
60 
61  inline QSharedData() : ref(0) { }
62  inline QSharedData(const QSharedData &) : ref(0) { }
63 
64 private:
65  // using the assignment operator would lead to corruption in the ref-counting
66  QSharedData &operator=(const QSharedData &);
67 };
68 
69 template <class T> class QSharedDataPointer
70 {
71 public:
72  typedef T Type;
73  typedef T *pointer;
74 
75  inline void detach() { if (d && d->ref != 1) detach_helper(); }
76  inline T &operator*() { detach(); return *d; }
77  inline const T &operator*() const { return *d; }
78  inline T *operator->() { detach(); return d; }
79  inline const T *operator->() const { return d; }
80  inline operator T *() { detach(); return d; }
81  inline operator const T *() const { return d; }
82  inline T *data() { detach(); return d; }
83  inline const T *data() const { return d; }
84  inline const T *constData() const { return d; }
85 
86  inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
87  inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
88 
89  inline QSharedDataPointer() { d = 0; }
90  inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
91 
92  explicit QSharedDataPointer(T *data);
93  inline QSharedDataPointer(const QSharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
95  if (o.d != d) {
96  if (o.d)
97  o.d->ref.ref();
98  T *old = d;
99  d = o.d;
100  if (old && !old->ref.deref())
101  delete old;
102  }
103  return *this;
104  }
106  if (o != d) {
107  if (o)
108  o->ref.ref();
109  T *old = d;
110  d = o;
111  if (old && !old->ref.deref())
112  delete old;
113  }
114  return *this;
115  }
116 #ifdef Q_COMPILER_RVALUE_REFS
117  QSharedDataPointer(QSharedDataPointer &&o) : d(o.d) { o.d = 0; }
119  { qSwap(d, other.d); return *this; }
120 #endif
121 
122  inline bool operator!() const { return !d; }
123 
124  inline void swap(QSharedDataPointer &other)
125  { qSwap(d, other.d); }
126 
127 protected:
128  T *clone();
129 
130 private:
131  void detach_helper();
132 
133  T *d;
134 };
135 
136 template <class T> class QExplicitlySharedDataPointer
137 {
138 public:
139  typedef T Type;
140  typedef T *pointer;
141 
142  inline T &operator*() const { return *d; }
143  inline T *operator->() { return d; }
144  inline T *operator->() const { return d; }
145  inline T *data() const { return d; }
146  inline const T *constData() const { return d; }
147 
148  inline void detach() { if (d && d->ref != 1) detach_helper(); }
149 
150  inline void reset()
151  {
152  if(d && !d->ref.deref())
153  delete d;
154 
155  d = 0;
156  }
157 
158  inline operator bool () const { return d != 0; }
159 
160  inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
161  inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
162  inline bool operator==(const T *ptr) const { return d == ptr; }
163  inline bool operator!=(const T *ptr) const { return d != ptr; }
164 
165  inline QExplicitlySharedDataPointer() { d = 0; }
166  inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
167 
168  explicit QExplicitlySharedDataPointer(T *data);
169  inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
170 
171  template<class X>
172  inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
173  {
174  if(d)
175  d->ref.ref();
176  }
177 
179  if (o.d != d) {
180  if (o.d)
181  o.d->ref.ref();
182  T *old = d;
183  d = o.d;
184  if (old && !old->ref.deref())
185  delete old;
186  }
187  return *this;
188  }
190  if (o != d) {
191  if (o)
192  o->ref.ref();
193  T *old = d;
194  d = o;
195  if (old && !old->ref.deref())
196  delete old;
197  }
198  return *this;
199  }
200 #ifdef Q_COMPILER_RVALUE_REFS
201  inline QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) : d(o.d) { o.d = 0; }
203  { qSwap(d, other.d); return *this; }
204 #endif
205 
206  inline bool operator!() const { return !d; }
207 
208  inline void swap(QExplicitlySharedDataPointer &other)
209  { qSwap(d, other.d); }
210 
211 protected:
212  T *clone();
213 
214 private:
215  void detach_helper();
216 
217  T *d;
218 };
219 
220 template <class T>
221 Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
222 { if (d) d->ref.ref(); }
223 
224 template <class T>
225 Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
226 {
227  return new T(*d);
228 }
229 
230 template <class T>
231 Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
232 {
233  T *x = clone();
234  x->ref.ref();
235  if (!d->ref.deref())
236  delete d;
237  d = x;
238 }
239 
240 template <class T>
242 {
243  return new T(*d);
244 }
245 
246 template <class T>
247 Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
248 {
249  T *x = clone();
250  x->ref.ref();
251  if (!d->ref.deref())
252  delete d;
253  d = x;
254 }
255 
256 template <class T>
258 { if (d) d->ref.ref(); }
259 
260 template <class T>
261 Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
262 { p1.swap(p2); }
263 
264 template <class T>
266 { p1.swap(p2); }
267 
268 #ifndef QT_NO_STL
270 namespace std {
271  template <class T>
272  Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QSharedDataPointer)<T> &p1, QT_PREPEND_NAMESPACE(QSharedDataPointer)<T> &p2)
273  { p1.swap(p2); }
274 
275  template <class T>
276  Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QExplicitlySharedDataPointer)<T> &p1, QT_PREPEND_NAMESPACE(QExplicitlySharedDataPointer)<T> &p2)
277  { p1.swap(p2); }
278 }
280 #endif
281 
283 
285 
286 #endif // QSHAREDDATA_H
#define QT_END_NAMESPACE
Definition: qglobal.h:128
#define QT_BEGIN_HEADER
Definition: qglobal.h:141
void swap(QExplicitlySharedDataPointer &other)
Definition: qshareddata.h:208
const T & operator*() const
Definition: qshareddata.h:77
const T * constData() const
Definition: qshareddata.h:84
Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QScopedPointer)< T, Cleanup > &p1, QT_PREPEND_NAMESPACE(QScopedPointer)< T, Cleanup > &p2)
QSharedDataPointer(const QSharedDataPointer< T > &o)
Definition: qshareddata.h:93
QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer< T > &o)
Definition: qshareddata.h:169
const T * constData() const
Definition: qshareddata.h:146
QExplicitlySharedDataPointer< T > & operator=(const QExplicitlySharedDataPointer< T > &o)
Definition: qshareddata.h:178
#define QT_BEGIN_NAMESPACE
Definition: qglobal.h:127
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: GLee.h:880
QSharedDataPointer< T > & operator=(const QSharedDataPointer< T > &o)
Definition: qshareddata.h:94
bool operator!=(const QExplicitlySharedDataPointer< T > &other) const
Definition: qshareddata.h:161
const T * data() const
Definition: qshareddata.h:83
QSharedData(const QSharedData &)
Definition: qshareddata.h:62
GLenum GLint x
Definition: GLee.h:876
bool operator==(const QSharedDataPointer< T > &other) const
Definition: qshareddata.h:86
Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer< T > &p1, QSharedDataPointer< T > &p2)
Definition: qshareddata.h:261
bool operator!=(const T *ptr) const
Definition: qshareddata.h:163
QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer< X > &o)
Definition: qshareddata.h:172
void swap(QSharedDataPointer &other)
Definition: qshareddata.h:124
bool operator==(const T *ptr) const
Definition: qshareddata.h:162
QAtomicInt ref
Definition: qshareddata.h:59
const T * operator->() const
Definition: qshareddata.h:79
bool operator!() const
Definition: qshareddata.h:122
QSharedDataPointer & operator=(T *o)
Definition: qshareddata.h:105
bool operator!=(const QSharedDataPointer< T > &other) const
Definition: qshareddata.h:87
#define QT_END_HEADER
Definition: qglobal.h:142
bool operator==(const QExplicitlySharedDataPointer< T > &other) const
Definition: qshareddata.h:160
QExplicitlySharedDataPointer & operator=(T *o)
Definition: qshareddata.h:189