tools/qsharedpointer.cpp

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

Generated by Squish Coco Non-Commercial