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

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

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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 T *old = d;
99 d = o.d;
100 if (old && !old->ref.deref())
101 delete old;
102 }
103 return *this;
104 }
105 inline QSharedDataPointer &operator=(T *o) {
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
117 inline bool operator!() const { return !d; }
118
119 inline void swap(QSharedDataPointer &other)
120 { qSwap(d, other.d); }
121
122protected:
123 T *clone();
124
125private:
126 void detach_helper();
127
128 T *d;
129};
130
131template <class T> class QExplicitlySharedDataPointer
132{
133public:
134 typedef T Type;
135 typedef T *pointer;
136
137 inline T &operator*() const { return *d; }
138 inline T *operator->() { return d; }
139 inline T *operator->() const { return d; }
140 inline T *data() const { return d; }
141 inline const T *constData() const { return d; }
142
143 inline void detach() { if (d && d->ref != 1) detach_helper(); }
144
145 inline void reset()
146 {
147 if(d && !d->ref.deref())
148 delete d;
149
150 d = 0;
151 }
152
153 inline operator bool () const { return d != 0; }
154
155 inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
156 inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
157 inline bool operator==(const T *ptr) const { return d == ptr; }
158 inline bool operator!=(const T *ptr) const { return d != ptr; }
159
160 inline QExplicitlySharedDataPointer() { d = 0; }
161 inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
162
163 explicit QExplicitlySharedDataPointer(T *data);
164 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
165
166#ifndef QT_NO_MEMBER_TEMPLATES
167 template<class X>
168 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
169 {
170 if(d)
171 d->ref.ref();
172 }
173#endif
174
175 inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
176 if (o.d != d) {
177 if (o.d)
178 o.d->ref.ref();
179 T *old = d;
180 d = o.d;
181 if (old && !old->ref.deref())
182 delete old;
183 }
184 return *this;
185 }
186 inline QExplicitlySharedDataPointer &operator=(T *o) {
187 if (o != d) {
188 if (o)
189 o->ref.ref();
190 T *old = d;
191 d = o;
192 if (old && !old->ref.deref())
193 delete old;
194 }
195 return *this;
196 }
197
198 inline bool operator!() const { return !d; }
199
200 inline void swap(QExplicitlySharedDataPointer &other)
201 { qSwap(d, other.d); }
202
203protected:
204 T *clone();
205
206private:
207 void detach_helper();
208
209 T *d;
210};
211
212template <class T>
213Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
214{ if (d) d->ref.ref(); }
215
216template <class T>
217Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
218{
219 return new T(*d);
220}
221
222template <class T>
223Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
224{
225 T *x = clone();
226 x->ref.ref();
227 if (!d->ref.deref())
228 delete d;
229 d = x;
230}
231
232template <class T>
233Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
234{
235 return new T(*d);
236}
237
238template <class T>
239Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
240{
241 T *x = clone();
242 x->ref.ref();
243 if (!d->ref.deref())
244 delete d;
245 d = x;
246}
247
248template <class T>
249Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
250{ if (d) d->ref.ref(); }
251
252template <class T>
253Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
254{ p1.swap(p2); }
255
256template <class T>
257Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2)
258{ p1.swap(p2); }
259
260QT_END_NAMESPACE
261
262QT_END_HEADER
263
264#endif // QSHAREDDATA_H
Note: See TracBrowser for help on using the repository browser.