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 QSCOPEDPOINTER_H |
43 | #define QSCOPEDPOINTER_H |
44 | |
45 | #include <QtCore/qglobal.h> |
46 | |
47 | QT_BEGIN_HEADER |
48 | QT_BEGIN_NAMESPACE |
49 | QT_MODULE(Core) |
50 | |
51 | template <typename T> |
52 | struct QScopedPointerDeleter |
53 | { |
54 | static inline void cleanup(T *pointer) |
55 | { |
56 | // Enforce a complete type. |
57 | // If you get a compile error here, read the section on forward declared |
58 | // classes in the QScopedPointer documentation. |
59 | typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; |
60 | (void) sizeof(IsIncompleteType); |
61 | |
62 | delete pointer; |
63 | } |
64 | }; |
65 | |
66 | template <typename T> |
67 | struct QScopedPointerArrayDeleter |
68 | { |
69 | static inline void cleanup(T *pointer) |
70 | { |
71 | // Enforce a complete type. |
72 | // If you get a compile error here, read the section on forward declared |
73 | // classes in the QScopedPointer documentation. |
74 | typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; |
75 | (void) sizeof(IsIncompleteType); |
76 | |
77 | delete [] pointer; |
78 | } |
79 | }; |
80 | |
81 | struct QScopedPointerPodDeleter |
82 | { |
83 | static inline void cleanup(void *pointer) { if (pointer) qFree(pointer); } |
84 | }; |
85 | |
86 | template <typename T, typename Cleanup = QScopedPointerDeleter<T> > |
87 | class QScopedPointer |
88 | { |
89 | #ifndef Q_CC_NOKIAX86 |
90 | typedef T *QScopedPointer:: *RestrictedBool; |
91 | #endif |
92 | public: |
93 | explicit inline QScopedPointer(T *p = 0) : d(p) |
94 | { |
95 | } |
96 | |
97 | inline ~QScopedPointer() |
98 | { |
99 | T *oldD = this->d; |
100 | Cleanup::cleanup(oldD); |
101 | this->d = 0; |
102 | } |
103 | |
104 | inline T &operator*() const |
105 | { |
106 | Q_ASSERT(d); |
107 | return *d; |
108 | } |
109 | |
110 | inline T *operator->() const |
111 | { |
112 | Q_ASSERT(d); |
113 | return d; |
114 | } |
115 | |
116 | inline bool operator!() const |
117 | { |
118 | return !d; |
119 | } |
120 | |
121 | #if defined(Q_CC_NOKIAX86) || defined(Q_QDOC) |
122 | inline operator bool() const |
123 | { |
124 | return isNull() ? 0 : &QScopedPointer::d; |
125 | } |
126 | #else |
127 | inline operator RestrictedBool() const |
128 | { |
129 | return isNull() ? 0 : &QScopedPointer::d; |
130 | } |
131 | #endif |
132 | |
133 | inline T *data() const |
134 | { |
135 | return d; |
136 | } |
137 | |
138 | inline bool isNull() const |
139 | { |
140 | return !d; |
141 | } |
142 | |
143 | inline void reset(T *other = 0) |
144 | { |
145 | if (d == other) |
146 | return; |
147 | T *oldD = d; |
148 | d = other; |
149 | Cleanup::cleanup(oldD); |
150 | } |
151 | |
152 | inline T *take() |
153 | { |
154 | T *oldD = d; |
155 | d = 0; |
156 | return oldD; |
157 | } |
158 | |
159 | inline void swap(QScopedPointer<T, Cleanup> &other) |
160 | { |
161 | qSwap(d, other.d); |
162 | } |
163 | |
164 | typedef T *pointer; |
165 | |
166 | protected: |
167 | T *d; |
168 | |
169 | private: |
170 | Q_DISABLE_COPY(QScopedPointer) |
171 | }; |
172 | |
173 | template <class T, class Cleanup> |
174 | inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) |
175 | { |
176 | return lhs.data() == rhs.data(); |
177 | } |
178 | |
179 | template <class T, class Cleanup> |
180 | inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) |
181 | { |
182 | return lhs.data() != rhs.data(); |
183 | } |
184 | |
185 | template <class T, class Cleanup> |
186 | Q_INLINE_TEMPLATE void qSwap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) |
187 | { p1.swap(p2); } |
188 | |
189 | #ifndef QT_NO_STL |
190 | QT_END_NAMESPACE |
191 | namespace std { |
192 | template <class T, class Cleanup> |
193 | Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QScopedPointer)<T, Cleanup> &p1, QT_PREPEND_NAMESPACE(QScopedPointer)<T, Cleanup> &p2) |
194 | { p1.swap(p2); } |
195 | } |
196 | QT_BEGIN_NAMESPACE |
197 | #endif |
198 | |
199 | |
200 | |
201 | namespace QtPrivate { |
202 | template <typename X, typename Y> struct QScopedArrayEnsureSameType; |
203 | template <typename X> struct QScopedArrayEnsureSameType<X,X> { typedef X* Type; }; |
204 | template <typename X> struct QScopedArrayEnsureSameType<const X, X> { typedef X* Type; }; |
205 | } |
206 | |
207 | template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> > |
208 | class QScopedArrayPointer : public QScopedPointer<T, Cleanup> |
209 | { |
210 | public: |
211 | inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(0) {} |
212 | |
213 | template <typename D> |
214 | explicit inline QScopedArrayPointer(D *p, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = 0) |
215 | : QScopedPointer<T, Cleanup>(p) |
216 | { |
217 | } |
218 | |
219 | inline T &operator[](int i) |
220 | { |
221 | return this->d[i]; |
222 | } |
223 | |
224 | inline const T &operator[](int i) const |
225 | { |
226 | return this->d[i]; |
227 | } |
228 | |
229 | private: |
230 | explicit inline QScopedArrayPointer(void *) { |
231 | // Enforce the same type. |
232 | |
233 | // If you get a compile error here, make sure you declare |
234 | // QScopedArrayPointer with the same template type as you pass to the |
235 | // constructor. See also the QScopedPointer documentation. |
236 | |
237 | // Storing a scalar array as a pointer to a different type is not |
238 | // allowed and results in undefined behavior. |
239 | } |
240 | |
241 | Q_DISABLE_COPY(QScopedArrayPointer) |
242 | }; |
243 | |
244 | QT_END_NAMESPACE |
245 | QT_END_HEADER |
246 | |
247 | #endif // QSCOPEDPOINTER_H |
248 | |