Line data Source code
1 : /****************************************************************************
2 : **
3 : ** Copyright (C) 2016 The Qt Company Ltd.
4 : ** Contact: https://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 : ** and conditions see https://www.qt.io/terms-conditions. For further
15 : ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20 : ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 : ** packaging of this file. Please review the following information to
22 : ** ensure the GNU Lesser General Public License version 3 requirements
23 : ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 : **
25 : ** GNU General Public License Usage
26 : ** Alternatively, this file may be used under the terms of the GNU
27 : ** General Public License version 2.0 or (at your option) the GNU General
28 : ** Public license version 3 or any later version approved by the KDE Free
29 : ** Qt Foundation. The licenses are as published by the Free Software
30 : ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 : ** included in the packaging of this file. Please review the following
32 : ** information to ensure the GNU General Public License requirements will
33 : ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 : ** https://www.gnu.org/licenses/gpl-3.0.html.
35 : **
36 : ** $QT_END_LICENSE$
37 : **
38 : ****************************************************************************/
39 :
40 : #ifndef QSCOPEDPOINTER_H
41 : #define QSCOPEDPOINTER_H
42 :
43 : #include <QtCore/qglobal.h>
44 :
45 : #include <stdlib.h>
46 :
47 : QT_BEGIN_NAMESPACE
48 :
49 : template <typename T>
50 : struct QScopedPointerDeleter
51 : {
52 : static inline void cleanup(T *pointer)
53 : {
54 : // Enforce a complete type.
55 : // If you get a compile error here, read the section on forward declared
56 : // classes in the QScopedPointer documentation.
57 : typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
58 : (void) sizeof(IsIncompleteType);
59 :
60 : delete pointer;
61 : }
62 : };
63 :
64 : template <typename T>
65 : struct QScopedPointerArrayDeleter
66 : {
67 : static inline void cleanup(T *pointer)
68 : {
69 : // Enforce a complete type.
70 : // If you get a compile error here, read the section on forward declared
71 : // classes in the QScopedPointer documentation.
72 : typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
73 : (void) sizeof(IsIncompleteType);
74 :
75 : delete [] pointer;
76 : }
77 : };
78 :
79 : struct QScopedPointerPodDeleter
80 : {
81 : static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
82 : };
83 :
84 : #ifndef QT_NO_QOBJECT
85 : template <typename T>
86 : struct QScopedPointerObjectDeleteLater
87 : {
88 : static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
89 : };
90 :
91 : class QObject;
92 : typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
93 : #endif
94 :
95 : template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
96 : class QScopedPointer
97 : {
98 : typedef T *QScopedPointer:: *RestrictedBool;
99 : public:
100 : explicit QScopedPointer(T *p = Q_NULLPTR) Q_DECL_NOTHROW : d(p)
101 : {
102 : }
103 :
104 : inline ~QScopedPointer()
105 : {
106 : T *oldD = this->d;
107 : Cleanup::cleanup(oldD);
108 : }
109 :
110 : inline T &operator*() const
111 : {
112 : Q_ASSERT(d);
113 : return *d;
114 : }
115 :
116 134 : T *operator->() const Q_DECL_NOTHROW
117 : {
118 134 : return d;
119 : }
120 :
121 : bool operator!() const Q_DECL_NOTHROW
122 : {
123 : return !d;
124 : }
125 :
126 : #if defined(Q_QDOC)
127 : inline operator bool() const
128 : {
129 : return isNull() ? Q_NULLPTR : &QScopedPointer::d;
130 : }
131 : #else
132 : operator RestrictedBool() const Q_DECL_NOTHROW
133 : {
134 : return isNull() ? Q_NULLPTR : &QScopedPointer::d;
135 : }
136 : #endif
137 :
138 : T *data() const Q_DECL_NOTHROW
139 : {
140 : return d;
141 : }
142 :
143 : bool isNull() const Q_DECL_NOTHROW
144 : {
145 : return !d;
146 : }
147 :
148 : void reset(T *other = Q_NULLPTR) Q_DECL_NOEXCEPT_EXPR(noexcept(Cleanup::cleanup(std::declval<T *>())))
149 : {
150 : if (d == other)
151 : return;
152 : T *oldD = d;
153 : d = other;
154 : Cleanup::cleanup(oldD);
155 : }
156 :
157 : T *take() Q_DECL_NOTHROW
158 : {
159 : T *oldD = d;
160 : d = Q_NULLPTR;
161 : return oldD;
162 : }
163 :
164 : void swap(QScopedPointer<T, Cleanup> &other) Q_DECL_NOTHROW
165 : {
166 : qSwap(d, other.d);
167 : }
168 :
169 : typedef T *pointer;
170 :
171 : protected:
172 : T *d;
173 :
174 : private:
175 : Q_DISABLE_COPY(QScopedPointer)
176 : };
177 :
178 : template <class T, class Cleanup>
179 : inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
180 : {
181 : return lhs.data() == rhs.data();
182 : }
183 :
184 : template <class T, class Cleanup>
185 : inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
186 : {
187 : return lhs.data() != rhs.data();
188 : }
189 :
190 : template <class T, class Cleanup>
191 : inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) Q_DECL_NOTHROW
192 : {
193 : return lhs.isNull();
194 : }
195 :
196 : template <class T, class Cleanup>
197 : inline bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
198 : {
199 : return rhs.isNull();
200 : }
201 :
202 : template <class T, class Cleanup>
203 : inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) Q_DECL_NOTHROW
204 : {
205 : return !lhs.isNull();
206 : }
207 :
208 : template <class T, class Cleanup>
209 : inline bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
210 : {
211 : return !rhs.isNull();
212 : }
213 :
214 : template <class T, class Cleanup>
215 : inline void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) Q_DECL_NOTHROW
216 : { p1.swap(p2); }
217 :
218 : template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
219 : class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
220 : {
221 : template <typename Ptr>
222 : using if_same_type = typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, Ptr>::value, bool>::type;
223 : public:
224 : inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(Q_NULLPTR) {}
225 :
226 : template <typename D, if_same_type<D> = true>
227 : explicit QScopedArrayPointer(D *p)
228 : : QScopedPointer<T, Cleanup>(p)
229 : {
230 : }
231 :
232 : inline T &operator[](int i)
233 : {
234 : return this->d[i];
235 : }
236 :
237 : inline const T &operator[](int i) const
238 : {
239 : return this->d[i];
240 : }
241 :
242 : void swap(QScopedArrayPointer &other) Q_DECL_NOTHROW // prevent QScopedPointer <->QScopedArrayPointer swaps
243 : { QScopedPointer<T, Cleanup>::swap(other); }
244 :
245 : private:
246 : explicit inline QScopedArrayPointer(void *) {
247 : // Enforce the same type.
248 :
249 : // If you get a compile error here, make sure you declare
250 : // QScopedArrayPointer with the same template type as you pass to the
251 : // constructor. See also the QScopedPointer documentation.
252 :
253 : // Storing a scalar array as a pointer to a different type is not
254 : // allowed and results in undefined behavior.
255 : }
256 :
257 : Q_DISABLE_COPY(QScopedArrayPointer)
258 : };
259 :
260 : template <typename T, typename Cleanup>
261 : inline void swap(QScopedArrayPointer<T, Cleanup> &lhs, QScopedArrayPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
262 : { lhs.swap(rhs); }
263 :
264 : QT_END_NAMESPACE
265 :
266 : #endif // QSCOPEDPOINTER_H
|