source: trunk/src/corelib/tools/qshareddata.h@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 7.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
48QT_BEGIN_HEADER
49
50QT_BEGIN_NAMESPACE
51
52QT_MODULE(Core)
53
54template <class T> class QSharedDataPointer;
55
56class Q_CORE_EXPORT QSharedData
57{
58public:
59 mutable QAtomicInt ref;
60
61 inline QSharedData() : ref(0) { }
62 inline QSharedData(const QSharedData &) : ref(0) { }
63
64private:
65 // using the assignment operator would lead to corruption in the ref-counting
66 QSharedData &operator=(const QSharedData &);
67};
68
69template <class T> class QSharedDataPointer
70{
71public:
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(); }
94 inline QSharedDataPointer<T> & operator=(const QSharedDataPointer<T> &o) {
95 if (o.d != d) {
96 if (o.d)
97 o.d->ref.ref();
98 if (d && !d->ref.deref())
99 delete d;
100 d = o.d;
101 }
102 return *this;
103 }
104 inline QSharedDataPointer &operator=(T *o) {
105 if (o != d) {
106 if (o)
107 o->ref.ref();
108 if (d && !d->ref.deref())
109 delete d;
110 d = o;
111 }
112 return *this;
113 }
114
115 inline bool operator!() const { return !d; }
116
117 inline void swap(QSharedDataPointer &other)
118 { qSwap(d, other.d); }
119
120protected:
121 T *clone();
122
123private:
124 void detach_helper();
125
126 T *d;
127};
128
129template <class T> class QExplicitlySharedDataPointer
130{
131public:
132 typedef T Type;
133 typedef T *pointer;
134
135 inline T &operator*() const { return *d; }
136 inline T *operator->() { return d; }
137 inline T *operator->() const { return d; }
138 inline T *data() const { return d; }
139 inline const T *constData() const { return d; }
140
141 inline void detach() { if (d && d->ref != 1) detach_helper(); }
142
143 inline void reset()
144 {
145 if(d && !d->ref.deref())
146 delete d;
147
148 d = 0;
149 }
150
151 inline operator bool () const { return d != 0; }
152
153 inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
154 inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
155 inline bool operator==(const T *ptr) const { return d == ptr; }
156 inline bool operator!=(const T *ptr) const { return d != ptr; }
157
158 inline QExplicitlySharedDataPointer() { d = 0; }
159 inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
160
161 explicit QExplicitlySharedDataPointer(T *data);
162 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
163
164#ifndef QT_NO_MEMBER_TEMPLATES
165 template<class X>
166 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
167 {
168 if(d)
169 d->ref.ref();
170 }
171#endif
172
173 inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
174 if (o.d != d) {
175 if (o.d)
176 o.d->ref.ref();
177 if (d && !d->ref.deref())
178 delete d;
179 d = o.d;
180 }
181 return *this;
182 }
183 inline QExplicitlySharedDataPointer &operator=(T *o) {
184 if (o != d) {
185 if (o)
186 o->ref.ref();
187 if (d && !d->ref.deref())
188 delete d;
189 d = o;
190 }
191 return *this;
192 }
193
194 inline bool operator!() const { return !d; }
195
196 inline void swap(QExplicitlySharedDataPointer &other)
197 { qSwap(d, other.d); }
198
199protected:
200 T *clone();
201
202private:
203 void detach_helper();
204
205 T *d;
206};
207
208template <class T>
209Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
210{ if (d) d->ref.ref(); }
211
212template <class T>
213Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
214{
215 return new T(*d);
216}
217
218template <class T>
219Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
220{
221 T *x = clone();
222 x->ref.ref();
223 if (!d->ref.deref())
224 delete d;
225 d = x;
226}
227
228template <class T>
229Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
230{
231 return new T(*d);
232}
233
234template <class T>
235Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
236{
237 T *x = clone();
238 x->ref.ref();
239 if (!d->ref.deref())
240 delete d;
241 d = x;
242}
243
244template <class T>
245Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
246{ if (d) d->ref.ref(); }
247
248template <class T>
249Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
250{ p1.swap(p2); }
251
252template <class T>
253Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2)
254{ p1.swap(p2); }
255
256QT_END_NAMESPACE
257
258QT_END_HEADER
259
260#endif // QSHAREDDATA_H
Note: See TracBrowser for help on using the repository browser.