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

Last change on this file since 240 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 7.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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 inline void detach() { if (d && d->ref != 1) detach_helper(); }
73 inline T &operator*() { detach(); return *d; }
74 inline const T &operator*() const { return *d; }
75 inline T *operator->() { detach(); return d; }
76 inline const T *operator->() const { return d; }
77 inline operator T *() { detach(); return d; }
78 inline operator const T *() const { return d; }
79 inline T *data() { detach(); return d; }
80 inline const T *data() const { return d; }
81 inline const T *constData() const { return d; }
82
83 inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
84 inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
85
86 inline QSharedDataPointer() { d = 0; }
87 inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
88
89 explicit QSharedDataPointer(T *data);
90 inline QSharedDataPointer(const QSharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
91 inline QSharedDataPointer<T> & operator=(const QSharedDataPointer<T> &o) {
92 if (o.d != d) {
93 if (o.d)
94 o.d->ref.ref();
95 if (d && !d->ref.deref())
96 delete d;
97 d = o.d;
98 }
99 return *this;
100 }
101 inline QSharedDataPointer &operator=(T *o) {
102 if (o != d) {
103 if (o)
104 o->ref.ref();
105 if (d && !d->ref.deref())
106 delete d;
107 d = o;
108 }
109 return *this;
110 }
111
112 inline bool operator!() const { return !d; }
113
114protected:
115 T *clone();
116
117private:
118 void detach_helper();
119
120 T *d;
121};
122
123template <class T> class QExplicitlySharedDataPointer
124{
125public:
126 typedef T Type;
127
128 inline T &operator*() const { return *d; }
129 inline T *operator->() { return d; }
130 inline T *operator->() const { return d; }
131 inline T *data() const { return d; }
132 inline const T *constData() const { return d; }
133
134 inline void detach() { if (d && d->ref != 1) detach_helper(); }
135
136 inline void reset()
137 {
138 if(d && !d->ref.deref())
139 delete d;
140
141 d = 0;
142 }
143
144 inline operator bool () const { return d != 0; }
145
146 inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
147 inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
148 inline bool operator==(const T *ptr) const { return d == ptr; }
149 inline bool operator!=(const T *ptr) const { return d != ptr; }
150
151 inline QExplicitlySharedDataPointer() { d = 0; }
152 inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
153
154 explicit QExplicitlySharedDataPointer(T *data);
155 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
156
157#ifndef QT_NO_MEMBER_TEMPLATES
158 template<class X>
159 inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
160 {
161 if(d)
162 d->ref.ref();
163 }
164#endif
165
166 inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
167 if (o.d != d) {
168 if (o.d)
169 o.d->ref.ref();
170 if (d && !d->ref.deref())
171 delete d;
172 d = o.d;
173 }
174 return *this;
175 }
176 inline QExplicitlySharedDataPointer &operator=(T *o) {
177 if (o != d) {
178 if (o)
179 o->ref.ref();
180 if (d && !d->ref.deref())
181 delete d;
182 d = o;
183 }
184 return *this;
185 }
186
187 inline bool operator!() const { return !d; }
188
189protected:
190 T *clone();
191
192private:
193 void detach_helper();
194
195 T *d;
196};
197
198template <class T>
199Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
200{ if (d) d->ref.ref(); }
201
202template <class T>
203Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
204{
205 return new T(*d);
206}
207
208template <class T>
209Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
210{
211 T *x = clone();
212 x->ref.ref();
213 if (!d->ref.deref())
214 delete d;
215 d = x;
216}
217
218template <class T>
219Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
220{
221 return new T(*d);
222}
223
224template <class T>
225Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
226{
227 T *x = clone();
228 x->ref.ref();
229 if (!d->ref.deref())
230 delete d;
231 d = x;
232}
233
234template <class T>
235Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
236{ if (d) d->ref.ref(); }
237
238QT_END_NAMESPACE
239
240QT_END_HEADER
241
242#endif // QSHAREDDATA_H
Note: See TracBrowser for help on using the repository browser.