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

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