1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Copyright (C) 2020 Intel Corporation.
5** Copyright (C) 2019 Klarälvdalens Datakonsult AB.
6** Contact: https://www.qt.io/licensing/
7**
8** This file is part of the QtCore module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial License Usage
12** Licensees holding valid commercial Qt licenses may use this file in
13** accordance with the commercial license agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and The Qt Company. For licensing terms
16** and conditions see https://www.qt.io/terms-conditions. For further
17** information use the contact form at https://www.qt.io/contact-us.
18**
19** GNU Lesser General Public License Usage
20** Alternatively, this file may be used under the terms of the GNU Lesser
21** General Public License version 3 as published by the Free Software
22** Foundation and appearing in the file LICENSE.LGPL3 included in the
23** packaging of this file. Please review the following information to
24** ensure the GNU Lesser General Public License version 3 requirements
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26**
27** GNU General Public License Usage
28** Alternatively, this file may be used under the terms of the GNU
29** General Public License version 2.0 or (at your option) the GNU General
30** Public license version 3 or any later version approved by the KDE Free
31** Qt Foundation. The licenses are as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33** included in the packaging of this file. Please review the following
34** information to ensure the GNU General Public License requirements will
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36** https://www.gnu.org/licenses/gpl-3.0.html.
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qsharedpointer.h"
43
44// to be sure we aren't causing a namespace clash:
45#include "qshareddata.h"
46
47/*!
48 \class QSharedPointer
49 \inmodule QtCore
50 \brief The QSharedPointer class holds a strong reference to a shared pointer.
51 \since 4.5
52
53 \reentrant
54
55 The QSharedPointer is an automatic, shared pointer in C++. It
56 behaves exactly like a normal pointer for normal purposes,
57 including respect for constness.
58
59 QSharedPointer will delete the pointer it is holding when it goes
60 out of scope, provided no other QSharedPointer objects are
61 referencing it.
62
63 A QSharedPointer object can be created from a normal pointer,
64 another QSharedPointer object or by promoting a
65 QWeakPointer object to a strong reference.
66
67 \section1 Thread-Safety
68
69 QSharedPointer and QWeakPointer are reentrant classes. This means that, in
70 general, a given QSharedPointer or QWeakPointer object \b{cannot} be
71 accessed by multiple threads at the same time without synchronization.
72
73 Different QSharedPointer and QWeakPointer objects can safely be accessed
74 by multiple threads at the same time. This includes the case where they
75 hold pointers to the same object; the reference counting mechanism
76 is atomic, and no manual synchronization is required.
77
78 It should be noted that, while the pointer value can be accessed in this
79 manner (that is, by multiple threads at the same time, without
80 synchronization), QSharedPointer and QWeakPointer provide no guarantee
81 about the object being pointed to. The specific thread-safety and
82 reentrancy rules for that object still apply.
83
84 \section1 Other Pointer Classes
85
86 Qt also provides two other pointer wrapper classes: QPointer and
87 QSharedDataPointer. They are incompatible with one another, since
88 each has its very different use case.
89
90 QSharedPointer holds a shared pointer by means of an external
91 reference count (i.e., a reference counter placed outside the
92 object). Like its name indicates, the pointer value is shared
93 among all instances of QSharedPointer and QWeakPointer. The
94 contents of the object pointed to by the pointer should not be
95 considered shared, however: there is only one object. For that
96 reason, QSharedPointer does not provide a way to detach or make
97 copies of the pointed object.
98
99 QSharedDataPointer, on the other hand, holds a pointer to shared
100 data (i.e., a class derived from QSharedData). It does so by means
101 of an internal reference count, placed in the QSharedData base
102 class. This class can, therefore, detach based on the type of
103 access made to the data being guarded: if it's a non-const access,
104 it creates a copy atomically for the operation to complete.
105
106 QExplicitlySharedDataPointer is a variant of QSharedDataPointer, except
107 that it only detaches if QExplicitlySharedDataPointer::detach() is
108 explicitly called (hence the name).
109
110 QScopedPointer simply holds a pointer to a heap allocated object and
111 deletes it in its destructor. This class is useful when an object needs to
112 be heap allocated and deleted, but no more. QScopedPointer is lightweight,
113 it makes no use of additional structure or reference counting.
114
115 Finally, QPointer holds a pointer to a QObject-derived object, but it
116 does so weakly. QWeakPointer has the same functionality, but its use for
117 that function is deprecated.
118
119 \section1 Optional Pointer Tracking
120
121 A feature of QSharedPointer that can be enabled at compile-time for
122 debugging purposes is a pointer tracking mechanism. When enabled,
123 QSharedPointer registers in a global set all the pointers that it tracks.
124 This allows one to catch mistakes like assigning the same pointer to two
125 QSharedPointer objects.
126
127 This function is enabled by defining the \tt{QT_SHAREDPOINTER_TRACK_POINTERS}
128 macro before including the QSharedPointer header.
129
130 It is safe to use this feature even with code compiled without the
131 feature. QSharedPointer will ensure that the pointer is removed from the
132 tracker even from code compiled without pointer tracking.
133
134 Note, however, that the pointer tracking feature has limitations on
135 multiple- or virtual-inheritance (that is, in cases where two different
136 pointer addresses can refer to the same object). In that case, if a
137 pointer is cast to a different type and its value changes,
138 QSharedPointer's pointer tracking mechanism may fail to detect that the
139 object being tracked is the same.
140
141 \omit
142 \section1 QSharedPointer internals
143
144 QSharedPointer has two "private" members: the pointer itself being tracked
145 and a d-pointer. Those members are private to the class, but QSharedPointer
146 is friends with QWeakPointer and other QSharedPointer with different
147 template arguments. (On some compilers, template friends are not supported,
148 so the members are technically public)
149
150 The reason for keeping the pointer value itself outside the d-pointer is
151 because of multiple inheritance needs. If you have two QSharedPointer
152 objects of different pointer types, but pointing to the same object in
153 memory, it could happen that the pointer values are different. The \tt
154 differentPointers autotest exemplifies this problem. The same thing could
155 happen in the case of virtual inheritance: a pointer of class matching
156 the virtual base has different address compared to the pointer of the
157 complete object. See the \tt virtualBaseDifferentPointers autotest for
158 this problem.
159
160 The d pointer is a pointer to QtSharedPointer::ExternalRefCountData, but it
161 always points to one of the two classes derived from ExternalRefCountData.
162
163 \section2 d-pointer
164 \section3 QtSharedPointer::ExternalRefCountData
165
166 It is basically a reference-counted reference-counter plus a pointer to the
167 function to be used to delete the pointer. It has three members: \tt
168 strongref, \tt weakref, and \tt destroyer. The strong reference counter is
169 controlling the lifetime of the object tracked by QSharedPointer. A
170 positive value indicates that the object is alive. It's also the number of
171 QSharedObject instances that are attached to this Data.
172
173 When the strong reference count decreases to zero, the object is deleted
174 (see below for information on custom deleters). The strong reference count
175 can also exceptionally be -1, indicating that there are no QSharedPointers
176 attached to an object, which is tracked too. The only case where this is
177 possible is that of QWeakPointers and QPointers tracking a QObject. Note
178 that QWeakPointers tracking a QObject is a deprecated feature as of Qt 5.0,
179 kept only for compatibility with Qt 4.x.
180
181 The weak reference count controls the lifetime of the d-pointer itself.
182 It can be thought of as an internal/intrusive reference count for
183 ExternalRefCountData itself. This count is equal to the number of
184 QSharedPointers and QWeakPointers that are tracking this object. In case
185 the object is a QObject being tracked by QPointer, this number is increased
186 by 1, since QObjectPrivate tracks it too.
187
188 The third member is a pointer to the function that is used to delete the
189 pointer being tracked. That happens when the destroy() function is called.
190
191 The size of this class is the size of the two atomic ints plus the size of
192 a pointer. On 32-bit architectures, that's 12 bytes, whereas on 64-bit ones
193 it's 16 bytes. There is no padding.
194
195 \section3 QtSharedPointer::ExternalRefCountWithCustomDeleter
196
197 This class derives from ExternalRefCountData and is a template class. As
198 template parameters, it has the type of the pointer being tracked (\tt T)
199 and a \tt Deleter, which is anything. It adds two fields to its parent
200 class, matching those template parameters: a member of type \tt Deleter and
201 a member of type \tt T*. Those members are actually inside a template
202 struct of type CustomDeleter, which is partially-specialized for normal
203 deletion. See below for more details on that.
204
205 The purpose of this class is to store the pointer to be deleted and the
206 deleter code along with the d-pointer. This allows the last strong
207 reference to call any arbitrary function that disposes of the object. For
208 example, this allows calling QObject::deleteLater() on a given object.
209 The pointer to the object is kept here because it needs to match the actual
210 deleter function's parameters, regardless of what template argument the
211 last QSharedPointer instance had.
212
213 This class is never instantiated directly: the constructors and
214 destructor are private and, in C++11, deleted. Only the create() function
215 may be called to return an object of this type. See below for construction
216 details.
217
218 The size of this class depends on the size of \tt Deleter. If it's an empty
219 functor (i.e., no members), ABIs generally assign it the size of 1. But
220 given that it's followed by a pointer, padding bytes may be inserted so
221 that the alignment of the class and of the pointer are correct. In that
222 case, the size of this class is 12+4+4 = 20 bytes on 32-bit architectures,
223 or 16+8+8 = 40 bytes on 64-bit architectures. If \tt Deleter is a function
224 pointer, the size should be the same as the empty structure case. If \tt
225 Deleter is a pointer to a member function (PMF), the size will be bigger
226 and will depend on the ABI. For architectures using the Itanium C++ ABI, a
227 PMF is twice the size of a normal pointer. In that case, the size of this
228 structure will be 12+8+4 = 24 bytes on 32-bit architectures, 16+16+8 = 40
229 bytes on 64-bit ones.
230
231 If the deleter was not specified when creating the QSharedPointer object
232 (i.e., if a standard \tt delete call is expected), then there's an
233 optimization that avoids the need to store another function pointer in
234 ExternalRefCountWithCustomDeleter. Instead, a template specialization makes
235 a direct delete call. The size of the structure, in this case, is 12+4 = 16
236 bytes on 32-bit architectures, 16+8 = 24 bytes on 64-bit ones.
237
238 \section3 QtSharedPointer::ExternalRefCountWithContiguousData
239
240 This class also derives from ExternalRefCountData and it is
241 also a template class. The template parameter is the type \tt T of the
242 class which QSharedPointer tracks. It adds only one member to its parent,
243 which is of type \tt T (the actual type, not a pointer to it).
244
245 The purpose of this class is to lay the \tt T object out next to the
246 reference counts, saving one memory allocation per shared pointer. This
247 is particularly interesting for small \tt T or for the cases when there
248 are few if any QWeakPointer tracking the object. This class exists to
249 implement the QSharedPointer::create() call.
250
251 Like ExternalRefCountWithCustomDeleter, this class is never instantiated
252 directly. This class also provides a create() member that returns the
253 pointer, and hides its constructors and destructor. With C++11, they're
254 deleted.
255
256 The size of this class depends on the size of \tt T.
257
258 \section3 Instantiating ExternalRefCountWithCustomDeleter and ExternalRefCountWithContiguousData
259
260 Like explained above, these classes have private constructors. Moreover,
261 they are not defined anywhere, so trying to call \tt{new ClassType} would
262 result in a compilation or linker error. Instead, these classes must be
263 constructed via their create() methods.
264
265 Instead of instantiating the class by the normal way, the create() method
266 calls \tt{operator new} directly with the size of the class, then calls
267 the parent class's constructor only (that is, ExternalRefCountData's constructor).
268 This ensures that the inherited members are initialised properly.
269
270 After initialising the base class, the
271 ExternalRefCountWithCustomDeleter::create() function initialises the new
272 members directly, by using the placement \tt{operator new}. In the case
273 of the ExternalRefCountWithContiguousData::create() function, the address
274 to the still-uninitialised \tt T member is saved for the callee to use.
275 The member is only initialised in QSharedPointer::create(), so that we
276 avoid having many variants of the internal functions according to the
277 arguments in use for calling the constructor.
278
279 When initialising the parent class, the create() functions pass the
280 address of the static deleter() member function. That is, when the
281 destroy() function is called by QSharedPointer, the deleter() functions
282 are called instead. These functions static_cast the ExternalRefCountData*
283 parameter to their own type and execute their deletion: for the
284 ExternalRefCountWithCustomDeleter::deleter() case, it runs the user's
285 custom deleter, then destroys the deleter; for
286 ExternalRefCountWithContiguousData::deleter, it simply calls the \tt T
287 destructor directly.
288
289 Only one non-inline function is required per template, which is
290 the deleter() static member. All the other functions can be inlined.
291 What's more, the address of deleter() is calculated only in code, which
292 can be resolved at link-time if the linker can determine that the
293 function lies in the current application or library module (since these
294 classes are not exported, that is the case for Windows or for builds with
295 \tt{-fvisibility=hidden}).
296
297 \section3 Modifications due to pointer-tracking
298
299 To ensure that pointers created with pointer-tracking enabled get
300 un-tracked when destroyed, even if destroyed by code compiled without the
301 feature, QSharedPointer modifies slightly the instructions of the
302 previous sections.
303
304 When ExternalRefCountWithCustomDeleter or
305 ExternalRefCountWithContiguousData are used, their create() functions
306 will set the ExternalRefCountData::destroyer function
307 pointer to safetyCheckDeleter() instead. These static member functions
308 simply call internalSafetyCheckRemove() before passing control to the
309 normal deleter() function.
310
311 If neither custom deleter nor QSharedPointer::create() are used, then
312 QSharedPointer uses a custom deleter of its own: the normalDeleter()
313 function, which simply calls \tt delete. By using a custom deleter, the
314 safetyCheckDeleter() procedure described above kicks in.
315
316 \endomit
317
318 \sa QSharedDataPointer, QWeakPointer, QScopedPointer, QEnableSharedFromThis
319*/
320
321/*!
322 \class QWeakPointer
323 \inmodule QtCore
324 \brief The QWeakPointer class holds a weak reference to a shared pointer.
325 \since 4.5
326 \reentrant
327
328 The QWeakPointer is an automatic weak reference to a
329 pointer in C++. It cannot be used to dereference the pointer
330 directly, but it can be used to verify if the pointer has been
331 deleted or not in another context.
332
333 QWeakPointer objects can only be created by assignment from a
334 QSharedPointer.
335
336 It's important to note that QWeakPointer provides no automatic casting
337 operators to prevent mistakes from happening. Even though QWeakPointer
338 tracks a pointer, it should not be considered a pointer itself, since it
339 doesn't guarantee that the pointed object remains valid.
340
341 Therefore, to access the pointer that QWeakPointer is tracking, you must
342 first promote it to QSharedPointer and verify if the resulting object is
343 null or not. QSharedPointer guarantees that the object isn't deleted, so
344 if you obtain a non-null object, you may use the pointer. See
345 QWeakPointer::toStrongRef() for an example.
346
347 \omit
348 \section1 QWeakPointer internals
349
350 QWeakPointer shares most of its internal functionality with
351 \l{QSharedPointer#qsharedpointer-internals}{QSharedPointer}, so see that
352 class's internal documentation for more information.
353
354 QWeakPointer requires an external reference counter in order to operate.
355 Therefore, it is incompatible by design with \l QSharedData-derived
356 classes.
357
358 It has a special QObject constructor, which works by calling
359 QtSharedPointer::ExternalRefCountData::getAndRef, which retrieves the
360 d-pointer from QObjectPrivate. If one isn't set yet, that function
361 creates the d-pointer and atomically sets it.
362
363 If getAndRef needs to create a d-pointer, it sets the strongref to -1,
364 indicating that the QObject is not shared: QWeakPointer is used only to
365 determine whether the QObject has been deleted. In that case, it cannot
366 be upgraded to QSharedPointer (see the previous section).
367
368 \endomit
369
370 \sa QSharedPointer, QScopedPointer
371*/
372
373/*!
374 \class QEnableSharedFromThis
375 \inmodule QtCore
376 \brief A base class that allows obtaining a QSharedPointer for an object already managed by a shared pointer.
377 \since 5.4
378
379 You can inherit this class when you need to create a QSharedPointer
380 from any instance of a class; for instance, from within the
381 object itself. The key point is that the technique of
382 just returning QSharedPointer<T>(this) cannot be used, because
383 this winds up creating multiple distinct QSharedPointer objects
384 with separate reference counts. For this reason you must never
385 create more than one QSharedPointer from the same raw pointer.
386
387 QEnableSharedFromThis defines two member functions called
388 sharedFromThis() that return a QSharedPointer<T> and
389 QSharedPointer<const T>, depending on constness, to \c this:
390
391 \snippet code/src_corelib_tools_qsharedpointer.cpp 0
392
393 It is also possible to get a shared pointer from an object outside of
394 the class itself. This is especially useful in code that provides an
395 interface to scripts, where it is currently not possible to use shared
396 pointers. For example:
397
398 \snippet code/src_corelib_tools_qsharedpointer.cpp 1
399*/
400
401/*!
402 \fn template <class T> QSharedPointer<T>::QSharedPointer()
403
404 Creates a QSharedPointer that is null (the object is holding
405 a reference to \nullptr).
406*/
407
408/*!
409 \fn template <class T> QSharedPointer<T>::~QSharedPointer()
410
411 Destroys this QSharedPointer object. If it is the last reference to
412 the pointer stored, this will delete the pointer as well.
413*/
414
415/*!
416 \fn template <class T> template <typename X> QSharedPointer<T>::QSharedPointer(X *ptr)
417
418 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
419 becomes managed by this QSharedPointer and must not be passed to
420 another QSharedPointer object or deleted outside this object.
421
422 Since Qt 5.8, when the last reference to this QSharedPointer gets
423 destroyed, \a ptr will be deleted by calling \c X's destructor (even if \c
424 X is not the same as QSharedPointer's template parameter \c T). Previously,
425 the destructor for \c T was called.
426*/
427
428/*!
429 \fn template <class T> template <typename X, typename Deleter> QSharedPointer<T>::QSharedPointer(X *ptr, Deleter d)
430
431 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
432 becomes managed by this QSharedPointer and must not be passed to
433 another QSharedPointer object or deleted outside this object.
434
435 The deleter parameter \a d specifies the custom deleter for this
436 object. The custom deleter is called, instead of the operator delete(),
437 when the strong reference count drops to 0. This is useful,
438 for instance, for calling \l {QObject::}{deleteLater()} on a QObject instead:
439
440 \snippet code/src_corelib_tools_qsharedpointer.cpp 2
441
442 Note that the custom deleter function will be called with a pointer to type
443 \c X, even if the QSharedPointer template parameter \c T is not the same.
444
445 It is also possible to specify a member function directly, as in:
446 \snippet code/src_corelib_tools_qsharedpointer.cpp 3
447
448 \sa clear()
449*/
450
451/*!
452 \fn template <class T> QSharedPointer<T>::QSharedPointer(std::nullptr_t)
453 \since 5.8
454
455 Creates a QSharedPointer that is null. This is equivalent to the
456 QSharedPointer default constructor.
457*/
458
459/*!
460 \fn template <class T> template <typename Deleter> QSharedPointer<T>::QSharedPointer(std::nullptr_t, Deleter d)
461 \since 5.8
462
463 Creates a QSharedPointer that is null. This is equivalent to the
464 QSharedPointer default constructor.
465
466 The deleter parameter \a d specifies the custom deleter for this
467 object. The custom deleter is called, instead of the operator
468 delete(), when the strong reference count drops to 0.
469*/
470
471/*!
472 \fn template <class T> QSharedPointer<T>::QSharedPointer(const QSharedPointer<T> &other)
473
474 Creates a QSharedPointer object that shares \a other's pointer.
475
476 If \tt T is a derived type of the template parameter of this class,
477 QSharedPointer will perform an automatic cast. Otherwise, you will
478 get a compiler error.
479*/
480
481/*!
482 \fn template <class T> QSharedPointer<T>::QSharedPointer(const QWeakPointer<T> &other)
483
484 Creates a QSharedPointer by promoting the weak reference \a other
485 to strong reference and sharing its pointer.
486
487 If \tt T is a derived type of the template parameter of this
488 class, QSharedPointer will perform an automatic cast. Otherwise,
489 you will get a compiler error.
490
491 \sa QWeakPointer::toStrongRef()
492*/
493
494/*!
495 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QSharedPointer<T> &other)
496
497 Makes this object share \a other's pointer. The current pointer
498 reference is discarded and, if it was the last, the pointer will
499 be deleted.
500
501 If \tt T is a derived type of the template parameter of this
502 class, QSharedPointer will perform an automatic cast. Otherwise,
503 you will get a compiler error.
504*/
505
506/*!
507 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QWeakPointer<T> &other)
508
509 Promotes \a other to a strong reference and makes this object
510 share a reference to the pointer referenced by it. The current pointer
511 reference is discarded and, if it was the last, the pointer will
512 be deleted.
513
514 If \tt T is a derived type of the template parameter of this
515 class, QSharedPointer will perform an automatic cast. Otherwise,
516 you will get a compiler error.
517*/
518
519/*!
520 \fn template <class T> void QSharedPointer<T>::swap(QSharedPointer<T> &other);
521 \since 5.3
522
523 Swaps this shared pointer instance with \a other. This function is
524 very fast and never fails.
525*/
526
527/*!
528 \fn template <class T> T *QSharedPointer<T>::data() const
529
530 Returns the value of the pointer referenced by this object.
531
532 Note: do not delete the pointer returned by this function or pass
533 it to another function that could delete it, including creating
534 QSharedPointer or QWeakPointer objects.
535*/
536
537/*!
538 \fn template <class T> T *QSharedPointer<T>::get() const
539 \since 5.11
540
541 Same as data().
542
543 This function is provided for API compatibility with \c{std::shared_ptr}.
544*/
545
546/*!
547 \fn template <class T> T &QSharedPointer<T>::operator *() const
548
549 Provides access to the shared pointer's members.
550
551 If the contained pointer is \nullptr, behavior is undefined.
552 \sa isNull()
553*/
554
555/*!
556 \fn template <class T> T *QSharedPointer<T>::operator ->() const
557
558 Provides access to the shared pointer's members.
559
560 If the contained pointer is \nullptr, behavior is undefined.
561 \sa isNull()
562*/
563
564/*!
565 \fn template <class T> bool QSharedPointer<T>::isNull() const
566
567 Returns \c true if this object refers to \nullptr.
568*/
569
570/*!
571 \fn template <class T> QSharedPointer<T>::operator bool() const
572
573 Returns \c true if the contained pointer is not \nullptr.
574 This function is suitable for use in \tt if-constructs, like:
575
576 \snippet code/src_corelib_tools_qsharedpointer.cpp 4
577
578 \sa isNull()
579*/
580
581/*!
582 \fn template <class T> bool QSharedPointer<T>::operator !() const
583
584 Returns \c true if this object refers to \nullptr.
585 This function is suitable for use in \tt if-constructs, like:
586
587 \snippet code/src_corelib_tools_qsharedpointer.cpp 5
588
589 \sa isNull()
590*/
591
592/*!
593 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::staticCast() const
594
595 Performs a static cast from this pointer's type to \tt X and returns
596 a QSharedPointer that shares the reference. This function can be
597 used for up- and for down-casting, but is more useful for
598 up-casting.
599
600 Note: the template type \c X must have the same const and volatile
601 qualifiers as the template of this object, or the cast will
602 fail. Use constCast() if you need to drop those qualifiers.
603
604 \sa dynamicCast(), constCast(), qSharedPointerCast()
605*/
606
607/*!
608 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::dynamicCast() const
609
610 Performs a dynamic cast from this pointer's type to \tt X and
611 returns a QSharedPointer that shares the reference. If this
612 function is used to up-cast, then QSharedPointer will perform a \tt
613 dynamic_cast, which means that if the object being pointed by this
614 QSharedPointer is not of type \tt X, the returned object will be
615 null.
616
617 Note: the template type \c X must have the same const and volatile
618 qualifiers as the template of this object, or the cast will
619 fail. Use constCast() if you need to drop those qualifiers.
620
621 \sa qSharedPointerDynamicCast()
622*/
623
624/*!
625 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::constCast() const
626
627 Performs a \tt const_cast from this pointer's type to \tt X and returns
628 a QSharedPointer that shares the reference. This function can be
629 used for up- and for down-casting, but is more useful for
630 up-casting.
631
632 \sa isNull(), qSharedPointerConstCast()
633*/
634
635/*!
636 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::objectCast() const
637 \since 4.6
638
639 Performs a \l qobject_cast() from this pointer's type to \tt X and
640 returns a QSharedPointer that shares the reference. If this
641 function is used to up-cast, then QSharedPointer will perform a \tt
642 qobject_cast, which means that if the object being pointed by this
643 QSharedPointer is not of type \tt X, the returned object will be
644 null.
645
646 Note: the template type \c X must have the same const and volatile
647 qualifiers as the template of this object, or the cast will
648 fail. Use constCast() if you need to drop those qualifiers.
649
650 \sa qSharedPointerObjectCast()
651*/
652
653/*!
654 \fn template <class T> template <typename... Args> QSharedPointer<T> QSharedPointer<T>::create(Args &&... args)
655 \overload
656 \since 5.1
657
658 Creates a QSharedPointer object and allocates a new item of type \tt T. The
659 QSharedPointer internals and the object are allocated in one single memory
660 allocation, which could help reduce memory fragmentation in a long-running
661 application.
662
663 This function will attempt to call a constructor for type \tt T that can
664 accept all the arguments passed (\a args). Arguments will be perfectly-forwarded.
665*/
666
667/*!
668 \fn template <class T> QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
669
670 Returns a weak reference object that shares the pointer referenced
671 by this object.
672
673 \sa QWeakPointer::QWeakPointer()
674*/
675
676/*!
677 \fn template <class T> void QSharedPointer<T>::clear()
678
679 Clears this QSharedPointer object, dropping the reference that it
680 may have had to the pointer. If this was the last reference, then
681 the pointer itself will be deleted.
682*/
683
684/*!
685 \fn template <class T> void QSharedPointer<T>::reset()
686 \since 5.0
687
688 Same as clear(). For std::shared_ptr compatibility.
689*/
690
691/*!
692 \fn template <class T> void QSharedPointer<T>::reset(T *t)
693 \since 5.0
694
695 Resets this QSharedPointer object to point to \a t
696 instead. Equivalent to:
697 \snippet code/src_corelib_tools_qsharedpointer.cpp 6
698*/
699
700/*!
701 \fn template <class T> template <typename Deleter> void QSharedPointer<T>::reset(T *t, Deleter deleter)
702 \since 5.0
703
704 Resets this QSharedPointer object to point to \a t
705 instead, with the Deleter \a deleter. Equivalent to:
706 \snippet code/src_corelib_tools_qsharedpointer.cpp 7
707*/
708
709/*!
710 \fn template <class T> QWeakPointer<T>::QWeakPointer()
711
712 Creates a QWeakPointer that points to nothing.
713*/
714
715/*!
716 \fn template <class T> QWeakPointer<T>::~QWeakPointer()
717
718 Destroys this QWeakPointer object. The pointer referenced
719 by this object will not be deleted.
720*/
721
722/*!
723 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QWeakPointer<T> &other)
724
725 Creates a QWeakPointer that holds a weak reference to the
726 pointer referenced by \a other.
727
728 If \tt T is a derived type of the template parameter of this
729 class, QWeakPointer will perform an automatic cast. Otherwise,
730 you will get a compiler error.
731*/
732
733/*!
734 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QSharedPointer<T> &other)
735
736 Creates a QWeakPointer that holds a weak reference to the
737 pointer referenced by \a other.
738
739 If \tt T is a derived type of the template parameter of this
740 class, QWeakPointer will perform an automatic cast. Otherwise,
741 you will get a compiler error.
742*/
743
744/*!
745 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QObject *other)
746 \since 4.6
747 \deprecated
748
749 Creates a QWeakPointer that holds a weak reference directly to the
750 QObject \a other. This constructor is only available if the template type
751 \tt T is QObject or derives from it (otherwise a compilation error will
752 result).
753
754 You can use this constructor with any QObject, even if they were not
755 created with \l QSharedPointer.
756
757 Note that QWeakPointers created this way on arbitrary QObjects usually
758 cannot be promoted to QSharedPointer.
759
760 \sa QSharedPointer, QPointer
761*/
762
763/*!
764 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QObject *other)
765 \since 4.6
766 \deprecated
767
768 Makes this QWeakPointer hold a weak reference directly to the QObject
769 \a other. This function is only available if the template type \tt T is
770 QObject or derives from it.
771
772 \sa QPointer
773*/
774
775/*!
776 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QWeakPointer<T> &other)
777
778 Makes this object share \a other's pointer. The current pointer
779 reference is discarded but is not deleted.
780
781 If \tt T is a derived type of the template parameter of this
782 class, QWeakPointer will perform an automatic cast. Otherwise,
783 you will get a compiler error.
784*/
785
786/*!
787 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QSharedPointer<T> &other)
788
789 Makes this object share \a other's pointer. The current pointer
790 reference is discarded but is not deleted.
791
792 If \tt T is a derived type of the template parameter of this
793 class, QWeakPointer will perform an automatic cast. Otherwise,
794 you will get a compiler error.
795*/
796
797/*!
798 \fn template <class T> void QWeakPointer<T>::swap(QWeakPointer<T> &other)
799 \since 5.4
800
801 Swaps this weak pointer instance with \a other. This function is
802 very fast and never fails.
803*/
804
805/*!
806 \fn template <class T> bool QWeakPointer<T>::isNull() const
807
808 Returns \c true if this object refers to \nullptr.
809
810 Note that, due to the nature of weak references, the pointer that
811 QWeakPointer references can become \nullptr at any moment, so
812 the value returned from this function can change from false to
813 true from one call to the next.
814*/
815
816/*!
817 \fn template <class T> QWeakPointer<T>::operator bool() const
818
819 Returns \c true if the contained pointer is not \nullptr.
820 This function is suitable for use in \tt if-constructs, like:
821
822 \snippet code/src_corelib_tools_qsharedpointer.cpp 8
823
824 Note that, due to the nature of weak references, the pointer that
825 QWeakPointer references can become \nullptr at any moment, so
826 the value returned from this function can change from true to
827 false from one call to the next.
828
829 \sa isNull()
830*/
831
832/*!
833 \fn template <class T> bool QWeakPointer<T>::operator !() const
834
835 Returns \c true if this object refers to \nullptr.
836 This function is suitable for use in \tt if-constructs, like:
837
838 \snippet code/src_corelib_tools_qsharedpointer.cpp 9
839
840 Note that, due to the nature of weak references, the pointer that
841 QWeakPointer references can become \nullptr at any moment, so
842 the value returned from this function can change from false to
843 true from one call to the next.
844
845 \sa isNull()
846*/
847
848/*!
849 \fn template <class T> T *QWeakPointer<T>::data() const
850 \since 4.6
851 \obsolete Use toStrongRef() instead, and data() on the returned QSharedPointer.
852
853 Returns the value of the pointer being tracked by this QWeakPointer,
854 \b without ensuring that it cannot get deleted. To have that guarantee,
855 use toStrongRef(), which returns a QSharedPointer object. If this
856 function can determine that the pointer has already been deleted, it
857 returns \nullptr.
858
859 It is ok to obtain the value of the pointer and using that value itself,
860 like for example in debugging statements:
861
862 \snippet code/src_corelib_tools_qsharedpointer.cpp 10
863
864 However, dereferencing the pointer is only allowed if you can guarantee
865 by external means that the pointer does not get deleted. For example,
866 if you can be certain that no other thread can delete it, nor the
867 functions that you may call.
868
869 If that is the case, then the following code is valid:
870
871 \snippet code/src_corelib_tools_qsharedpointer.cpp 11
872
873 Use this function with care.
874
875 \sa isNull(), toStrongRef()
876*/
877
878/*!
879 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::toStrongRef() const
880
881 Promotes this weak reference to a strong one and returns a
882 QSharedPointer object holding that reference. When promoting to
883 QSharedPointer, this function verifies if the object has been deleted
884 already or not. If it hasn't, this function increases the reference
885 count to the shared object, thus ensuring that it will not get
886 deleted.
887
888 Since this function can fail to obtain a valid strong reference to the
889 shared object, you should always verify if the conversion succeeded,
890 by calling QSharedPointer::isNull() on the returned object.
891
892 For example, the following code promotes a QWeakPointer that was held
893 to a strong reference and, if it succeeded, it prints the value of the
894 integer that was held:
895
896 \snippet code/src_corelib_tools_qsharedpointer.cpp 12
897
898 \sa QSharedPointer::QSharedPointer()
899*/
900
901/*!
902 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::lock() const
903 \since 5.4
904
905 Same as toStrongRef().
906
907 This function is provided for API compatibility with std::weak_ptr.
908*/
909
910/*!
911 \fn template <class T> void QWeakPointer<T>::clear()
912
913 Clears this QWeakPointer object, dropping the reference that it
914 may have had to the pointer.
915*/
916
917/*!
918 \fn template <class T> QSharedPointer<T> QEnableSharedFromThis<T>::sharedFromThis()
919 \since 5.4
920
921 If \c this (that is, the subclass instance invoking this method) is being
922 managed by a QSharedPointer, returns a shared pointer instance pointing to
923 \c this; otherwise returns a null QSharedPointer.
924*/
925
926/*!
927 \fn template <class T> QSharedPointer<const T> QEnableSharedFromThis<T>::sharedFromThis() const
928 \overload
929 \since 5.4
930
931 Const overload of sharedFromThis().
932*/
933
934/*!
935 \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
936 \relates QSharedPointer
937
938 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
939
940 If \a ptr2's template parameter is different from \a ptr1's,
941 QSharedPointer will attempt to perform an automatic \tt static_cast
942 to ensure that the pointers being compared are equal. If \a ptr2's
943 template parameter is not a base or a derived type from
944 \a ptr1's, you will get a compiler error.
945*/
946
947/*!
948 \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
949 \relates QSharedPointer
950
951 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
952
953 If \a ptr2's template parameter is different from \a ptr1's,
954 QSharedPointer will attempt to perform an automatic \tt static_cast
955 to ensure that the pointers being compared are equal. If \a ptr2's
956 template parameter is not a base or a derived type from
957 \a ptr1's, you will get a compiler error.
958*/
959
960/*!
961 \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
962 \relates QSharedPointer
963
964 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
965
966 If \a ptr2's type is different from \a ptr1's,
967 QSharedPointer will attempt to perform an automatic \tt static_cast
968 to ensure that the pointers being compared are equal. If \a ptr2's
969 type is not a base or a derived type from this
970 \a ptr1's, you will get a compiler error.
971*/
972
973/*!
974 \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
975 \relates QSharedPointer
976
977 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
978
979 If \a ptr2's type is different from \a ptr1's,
980 QSharedPointer will attempt to perform an automatic \tt static_cast
981 to ensure that the pointers being compared are equal. If \a ptr2's
982 type is not a base or a derived type from this
983 \a ptr1's, you will get a compiler error.
984*/
985
986/*!
987 \fn template <class T> template <class X> bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
988 \relates QSharedPointer
989
990 Returns \c true if the pointer \a ptr1 is the
991 same pointer as that referenced by \a ptr2.
992
993 If \a ptr2's template parameter is different from \a ptr1's type,
994 QSharedPointer will attempt to perform an automatic \tt static_cast
995 to ensure that the pointers being compared are equal. If \a ptr2's
996 template parameter is not a base or a derived type from
997 \a ptr1's type, you will get a compiler error.
998*/
999
1000/*!
1001 \fn template <class T> template <class X> bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
1002 \relates QSharedPointer
1003
1004 Returns \c true if the pointer \a ptr1 is not the
1005 same pointer as that referenced by \a ptr2.
1006
1007 If \a ptr2's template parameter is different from \a ptr1's type,
1008 QSharedPointer will attempt to perform an automatic \tt static_cast
1009 to ensure that the pointers being compared are equal. If \a ptr2's
1010 template parameter is not a base or a derived type from
1011 \a ptr1's type, you will get a compiler error.
1012*/
1013
1014/*!
1015 \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1016 \relates QWeakPointer
1017
1018 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1019
1020 If \a ptr2's template parameter is different from \a ptr1's,
1021 QSharedPointer will attempt to perform an automatic \tt static_cast
1022 to ensure that the pointers being compared are equal. If \a ptr2's
1023 template parameter is not a base or a derived type from
1024 \a ptr1's, you will get a compiler error.
1025*/
1026
1027/*!
1028 \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1029 \relates QWeakPointer
1030
1031 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1032
1033 If \a ptr2's template parameter is different from \a ptr1's,
1034 QSharedPointer will attempt to perform an automatic \tt static_cast
1035 to ensure that the pointers being compared are equal. If \a ptr2's
1036 template parameter is not a base or a derived type from
1037 \a ptr1's, you will get a compiler error.
1038*/
1039
1040/*!
1041 \fn template <class T> template <class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1042 \relates QWeakPointer
1043
1044 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1045
1046 If \a ptr2's template parameter is different from \a ptr1's,
1047 QSharedPointer will attempt to perform an automatic \tt static_cast
1048 to ensure that the pointers being compared are equal. If \a ptr2's
1049 template parameter is not a base or a derived type from
1050 \a ptr1's, you will get a compiler error.
1051*/
1052
1053/*!
1054 \fn template <class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t)
1055 \relates QSharedPointer
1056 \since 5.8
1057
1058 Returns \c true if \a lhs refers to \nullptr.
1059
1060 \sa QSharedPointer::isNull()
1061*/
1062
1063/*!
1064 \fn template <class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs)
1065 \relates QSharedPointer
1066 \since 5.8
1067
1068 Returns \c true if \a rhs refers to \nullptr.
1069
1070 \sa QSharedPointer::isNull()
1071*/
1072
1073/*!
1074 \fn template <class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t)
1075 \relates QSharedPointer
1076 \since 5.8
1077
1078 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1079
1080 \sa QSharedPointer::isNull()
1081*/
1082
1083/*!
1084 \fn template <class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs)
1085 \relates QSharedPointer
1086 \since 5.8
1087
1088 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1089
1090 \sa QSharedPointer::isNull()
1091*/
1092
1093/*!
1094 \fn template <class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t)
1095 \relates QWeakPointer
1096 \since 5.8
1097
1098 Returns \c true if \a lhs refers to \nullptr.
1099
1100 \sa QWeakPointer::isNull()
1101*/
1102
1103/*!
1104 \fn template <class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs)
1105 \relates QWeakPointer
1106 \since 5.8
1107
1108 Returns \c true if \a rhs refers to \nullptr.
1109
1110 \sa QWeakPointer::isNull()
1111*/
1112
1113/*!
1114 \fn template <class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t)
1115 \relates QWeakPointer
1116 \since 5.8
1117
1118 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1119
1120 \sa QWeakPointer::isNull()
1121*/
1122
1123/*!
1124 \fn template <class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs)
1125 \relates QWeakPointer
1126 \since 5.8
1127
1128 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1129
1130 \sa QWeakPointer::isNull()
1131*/
1132
1133/*!
1134 \fn template <class T> template <class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1135 \relates QWeakPointer
1136
1137 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1138
1139 If \a ptr2's template parameter is different from \a ptr1's,
1140 QSharedPointer will attempt to perform an automatic \tt static_cast
1141 to ensure that the pointers being compared are equal. If \a ptr2's
1142 template parameter is not a base or a derived type from
1143 \a ptr1's, you will get a compiler error.
1144*/
1145
1146/*!
1147 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
1148 \relates QSharedPointer
1149
1150 Returns a shared pointer to the pointer held by \a other, cast to
1151 type \tt X. The types \tt T and \tt X must belong to one
1152 hierarchy for the \tt static_cast to succeed.
1153
1154 Note that \tt X must have the same cv-qualifiers (\tt const and
1155 \tt volatile) that \tt T has, or the code will fail to
1156 compile. Use qSharedPointerConstCast to cast away the constness.
1157
1158 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1159*/
1160
1161/*!
1162 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
1163 \relates QSharedPointer
1164 \relates QWeakPointer
1165
1166 Returns a shared pointer to the pointer held by \a other, cast to
1167 type \tt X. The types \tt T and \tt X must belong to one
1168 hierarchy for the \tt static_cast to succeed.
1169
1170 The \a other object is converted first to a strong reference. If
1171 that conversion fails (because the object it's pointing to has
1172 already been deleted), this function returns a null
1173 QSharedPointer.
1174
1175 Note that \tt X must have the same cv-qualifiers (\tt const and
1176 \tt volatile) that \tt T has, or the code will fail to
1177 compile. Use qSharedPointerConstCast to cast away the constness.
1178
1179 \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1180*/
1181
1182/*!
1183 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1184 \relates QSharedPointer
1185
1186 Returns a shared pointer to the pointer held by \a src, using a
1187 dynamic cast to type \tt X to obtain an internal pointer of the
1188 appropriate type. If the \tt dynamic_cast fails, the object
1189 returned will be null.
1190
1191 Note that \tt X must have the same cv-qualifiers (\tt const and
1192 \tt volatile) that \tt T has, or the code will fail to
1193 compile. Use qSharedPointerConstCast to cast away the constness.
1194
1195 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1196*/
1197
1198/*!
1199 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
1200 \relates QSharedPointer
1201 \relates QWeakPointer
1202
1203 Returns a shared pointer to the pointer held by \a src, using a
1204 dynamic cast to type \tt X to obtain an internal pointer of the
1205 appropriate type. If the \tt dynamic_cast fails, the object
1206 returned will be null.
1207
1208 The \a src object is converted first to a strong reference. If
1209 that conversion fails (because the object it's pointing to has
1210 already been deleted), this function also returns a null
1211 QSharedPointer.
1212
1213 Note that \tt X must have the same cv-qualifiers (\tt const and
1214 \tt volatile) that \tt T has, or the code will fail to
1215 compile. Use qSharedPointerConstCast to cast away the constness.
1216
1217 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1218*/
1219
1220/*!
1221 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
1222 \relates QSharedPointer
1223
1224 Returns a shared pointer to the pointer held by \a src, cast to
1225 type \tt X. The types \tt T and \tt X must belong to one
1226 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1227 volatile differences between \tt T and \tt X are ignored.
1228
1229 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1230*/
1231
1232/*!
1233 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
1234 \relates QSharedPointer
1235 \relates QWeakPointer
1236
1237 Returns a shared pointer to the pointer held by \a src, cast to
1238 type \tt X. The types \tt T and \tt X must belong to one
1239 hierarchy for the \tt const_cast to succeed. The \tt const and
1240 \tt volatile differences between \tt T and \tt X are ignored.
1241
1242 The \a src object is converted first to a strong reference. If
1243 that conversion fails (because the object it's pointing to has
1244 already been deleted), this function returns a null
1245 QSharedPointer.
1246
1247 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
1248*/
1249
1250/*!
1251 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
1252 \relates QSharedPointer
1253 \since 4.6
1254
1255 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1256
1257 Returns a shared pointer to the pointer held by \a src, using a
1258 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1259 appropriate type. If the \tt qobject_cast fails, the object
1260 returned will be null.
1261
1262 Note that \tt X must have the same cv-qualifiers (\tt const and
1263 \tt volatile) that \tt T has, or the code will fail to
1264 compile. Use qSharedPointerConstCast to cast away the constness.
1265
1266 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1267*/
1268
1269/*!
1270 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
1271 \relates QSharedPointer
1272 \since 5.14
1273
1274 Returns a shared pointer to the pointer held by \a src, using a
1275 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1276 appropriate type. If the \tt qobject_cast fails, the object
1277 returned will be null.
1278
1279 Note that \tt X must have the same cv-qualifiers (\tt const and
1280 \tt volatile) that \tt T has, or the code will fail to
1281 compile. Use const_pointer_cast to cast away the constness.
1282*/
1283
1284/*!
1285 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
1286 \relates QSharedPointer
1287 \since 5.14
1288
1289 Returns a shared pointer to the pointer held by \a src.
1290
1291 Same as qSharedPointerObjectCast(). This function is provided for STL
1292 compatibility.
1293*/
1294
1295/*!
1296 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
1297 \relates QSharedPointer
1298 \since 5.14
1299
1300 Returns a shared pointer to the pointer held by \a src, using a
1301 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1302 appropriate type.
1303
1304 If the \tt qobject_cast succeeds, the function will return a valid shared
1305 pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
1306 object returned will be null, and \a src will not be modified.
1307
1308 Note that \tt X must have the same cv-qualifiers (\tt const and
1309 \tt volatile) that \tt T has, or the code will fail to
1310 compile. Use const_pointer_cast to cast away the constness.
1311*/
1312
1313/*!
1314 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
1315 \relates QSharedPointer
1316 \since 5.14
1317
1318 Same as qSharedPointerObjectCast(). This function is provided for STL
1319 compatibility.
1320*/
1321
1322/*!
1323 \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
1324 \relates QSharedPointer
1325 \relates QWeakPointer
1326 \since 4.6
1327
1328 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1329
1330 Returns a shared pointer to the pointer held by \a src, using a
1331 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1332 appropriate type. If the \tt qobject_cast fails, the object
1333 returned will be null.
1334
1335 The \a src object is converted first to a strong reference. If
1336 that conversion fails (because the object it's pointing to has
1337 already been deleted), this function also returns a null
1338 QSharedPointer.
1339
1340 Note that \tt X must have the same cv-qualifiers (\tt const and
1341 \tt volatile) that \tt T has, or the code will fail to
1342 compile. Use qSharedPointerConstCast to cast away the constness.
1343
1344 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1345*/
1346
1347
1348/*!
1349 \fn template <class X> template <class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
1350 \relates QWeakPointer
1351
1352 Returns a weak pointer to the pointer held by \a src, cast to
1353 type \tt X. The types \tt T and \tt X must belong to one
1354 hierarchy for the \tt static_cast to succeed.
1355
1356 Note that \tt X must have the same cv-qualifiers (\tt const and
1357 \tt volatile) that \tt T has, or the code will fail to
1358 compile. Use qSharedPointerConstCast to cast away the constness.
1359*/
1360
1361#include <qset.h>
1362#include <qmutex.h>
1363
1364#if !defined(QT_NO_QOBJECT)
1365#include "private/qobject_p.h"
1366
1367QT_BEGIN_NAMESPACE
1368
1369/*!
1370 \internal
1371 This function is called for a just-created QObject \a obj, to enable
1372 the use of QSharedPointer and QWeakPointer in the future.
1373 */
1374void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1375{}
1376
1377/*!
1378 \internal
1379 This function is called when a QSharedPointer is created from a QWeakPointer
1380
1381 We check that the QWeakPointer was really created from a QSharedPointer, and
1382 not from a QObject.
1383*/
1384void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1385{
1386 if (strongref.loadRelaxed() < 0)
1387 qWarning(msg: "QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1388}
1389
1390QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1391{
1392 Q_ASSERT(obj);
1393 QObjectPrivate *d = QObjectPrivate::get(o: const_cast<QObject *>(obj));
1394 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1395
1396 ExternalRefCountData *that = d->sharedRefcount.loadRelaxed();
1397 if (that) {
1398 that->weakref.ref();
1399 return that;
1400 }
1401
1402 // we can create the refcount data because it doesn't exist
1403 ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
1404 x->strongref.storeRelaxed(newValue: -1);
1405 x->weakref.storeRelaxed(newValue: 2); // the QWeakPointer that called us plus the QObject itself
1406
1407 ExternalRefCountData *ret;
1408 if (d->sharedRefcount.testAndSetOrdered(expectedValue: nullptr, newValue: x, currentValue&: ret)) { // ought to be release+acquire; this is acq_rel+acquire
1409 ret = x;
1410 } else {
1411 // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
1412 // only execute this if Q_ASSERTs are enabled
1413 Q_ASSERT((x->weakref.storeRelaxed(0), true));
1414 delete x;
1415 ret->weakref.ref();
1416 }
1417 return ret;
1418}
1419
1420/**
1421 \internal
1422 Returns a QSharedPointer<QObject> if the variant contains
1423 a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1424*/
1425QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
1426{
1427 Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject);
1428 return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
1429}
1430
1431/**
1432 \internal
1433 Returns a QWeakPointer<QObject> if the variant contains
1434 a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1435*/
1436QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
1437{
1438 Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::WeakPointerToQObject || QMetaType::typeFlags(variant.userType()) & QMetaType::TrackingPointerToQObject);
1439 return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
1440}
1441
1442QT_END_NAMESPACE
1443
1444#endif
1445
1446
1447
1448//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1449# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1450# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1451# define BACKTRACE_SUPPORTED
1452# elif defined(Q_OS_MAC)
1453# define BACKTRACE_SUPPORTED
1454# endif
1455# endif
1456
1457# if defined(BACKTRACE_SUPPORTED)
1458# include <sys/types.h>
1459# include <execinfo.h>
1460# include <stdio.h>
1461# include <unistd.h>
1462# include <sys/wait.h>
1463
1464QT_BEGIN_NAMESPACE
1465
1466static inline QByteArray saveBacktrace() __attribute__((always_inline));
1467static inline QByteArray saveBacktrace()
1468{
1469 static const int maxFrames = 32;
1470
1471 QByteArray stacktrace;
1472 stacktrace.resize(sizeof(void*) * maxFrames);
1473 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1474 stacktrace.resize(sizeof(void*) * stack_size);
1475
1476 return stacktrace;
1477}
1478
1479static void printBacktrace(QByteArray stacktrace)
1480{
1481 void *const *stack = (void *const *)stacktrace.constData();
1482 int stack_size = stacktrace.size() / sizeof(void*);
1483 char **stack_symbols = backtrace_symbols(stack, stack_size);
1484
1485 int filter[2];
1486 pid_t child = -1;
1487 if (pipe(filter) != -1)
1488 child = fork();
1489 if (child == 0) {
1490 // child process
1491 dup2(fileno(stderr), fileno(stdout));
1492 dup2(filter[0], fileno(stdin));
1493 close(filter[0]);
1494 close(filter[1]);
1495 execlp("c++filt", "c++filt", "-n", NULL);
1496
1497 // execlp failed
1498 execl("/bin/cat", "/bin/cat", NULL);
1499 _exit(127);
1500 }
1501
1502 // parent process
1503 close(filter[0]);
1504 FILE *output;
1505 if (child == -1) {
1506 // failed forking
1507 close(filter[1]);
1508 output = stderr;
1509 } else {
1510 output = fdopen(filter[1], "w");
1511 }
1512
1513 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1514 for (int i = 0; i < stack_size; ++i) {
1515 if (strlen(stack_symbols[i]))
1516 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1517 else
1518 fprintf(output, "#%-2d %p\n", i, stack[i]);
1519 }
1520
1521 if (child != -1) {
1522 fclose(output);
1523 waitpid(child, 0, 0);
1524 }
1525}
1526
1527QT_END_NAMESPACE
1528
1529# endif // BACKTRACE_SUPPORTED
1530
1531namespace {
1532 QT_USE_NAMESPACE
1533 struct Data {
1534 const volatile void *pointer;
1535# ifdef BACKTRACE_SUPPORTED
1536 QByteArray backtrace;
1537# endif
1538 };
1539
1540 class KnownPointers
1541 {
1542 public:
1543 QMutex mutex;
1544 QHash<const void *, Data> dPointers;
1545 QHash<const volatile void *, const void *> dataPointers;
1546 };
1547}
1548
1549Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1550
1551QT_BEGIN_NAMESPACE
1552
1553namespace QtSharedPointer {
1554 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1555}
1556
1557/*!
1558 \internal
1559*/
1560void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1561{
1562 KnownPointers *const kp = knownPointers();
1563 if (!kp)
1564 return; // end-game: the application is being destroyed already
1565
1566 if (!ptr) {
1567 // nullptr is allowed to be tracked by more than one QSharedPointer, so we
1568 // need something else to put in our tracking structures
1569 ptr = d_ptr;
1570 }
1571
1572 QMutexLocker lock(&kp->mutex);
1573 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1574
1575 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1576
1577 const void *other_d_ptr = kp->dataPointers.value(akey: ptr, adefaultValue: 0);
1578 if (Q_UNLIKELY(other_d_ptr)) {
1579# ifdef BACKTRACE_SUPPORTED
1580 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1581# endif
1582 qFatal(msg: "QSharedPointer: internal self-check failed: pointer %p was already tracked "
1583 "by another QSharedPointer object %p", ptr, other_d_ptr);
1584 }
1585
1586 Data data;
1587 data.pointer = ptr;
1588# ifdef BACKTRACE_SUPPORTED
1589 data.backtrace = saveBacktrace();
1590# endif
1591
1592 kp->dPointers.insert(akey: d_ptr, avalue: data);
1593 kp->dataPointers.insert(akey: ptr, avalue: d_ptr);
1594 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1595}
1596
1597/*!
1598 \internal
1599*/
1600void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1601{
1602 KnownPointers *const kp = knownPointers();
1603 if (!kp)
1604 return; // end-game: the application is being destroyed already
1605
1606 QMutexLocker lock(&kp->mutex);
1607
1608 const auto it = kp->dPointers.constFind(akey: d_ptr);
1609 if (Q_UNLIKELY(it == kp->dPointers.cend())) {
1610 qFatal(msg: "QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1611 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1612 "in your code.", d_ptr);
1613 }
1614
1615 const auto it2 = kp->dataPointers.constFind(akey: it->pointer);
1616 Q_ASSERT(it2 != kp->dataPointers.cend());
1617
1618 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1619
1620 // remove entries
1621 kp->dataPointers.erase(it: it2);
1622 kp->dPointers.erase(it);
1623 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1624}
1625
1626/*!
1627 \internal
1628 Called by the QSharedPointer autotest
1629*/
1630void QtSharedPointer::internalSafetyCheckCleanCheck()
1631{
1632# ifdef QT_BUILD_INTERNAL
1633 KnownPointers *const kp = knownPointers();
1634 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1635
1636 if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
1637 qFatal(msg: "Internal consistency error: the number of pointers is not equal!");
1638
1639 if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
1640 qFatal(msg: "Pointer cleaning failed: %d entries remaining", kp->dPointers.size());
1641# endif
1642}
1643
1644QT_END_NAMESPACE
1645

source code of qtbase/src/corelib/tools/qsharedpointer.cpp