QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qobjectuniqueptr.h
Go to the documentation of this file.
1/***************************************************************************
2 qobjectuniqueptr.h
3
4 A unique pointer to a QObject.
5
6 -------------------
7 begin : June 2019
8 copyright : (C) 2009 by Matthias Kuhn
10 ***************************************************************************/
11
12/***************************************************************************
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 ***************************************************************************/
20
21#ifndef QOBJECTUNIQUEPTR_H
22#define QOBJECTUNIQUEPTR_H
23
24#define SIP_NO_FILE
25
26#include <QObject>
27#include <QPointer>
28#include <QtDebug>
29#include <qtypeinfo.h>
30
31class QVariant;
32
43template <class T>
45{
46 Q_STATIC_ASSERT_X( !std::is_pointer<T>::value, "QObjectUniquePtr's template type must not be a pointer type" );
47
48 template<typename U>
49 struct TypeSelector
50 {
51 typedef QObject Type;
52 };
53 template<typename U>
54 struct TypeSelector<const U>
55 {
56 typedef const QObject Type;
57 };
58 typedef typename TypeSelector<T>::Type QObjectType;
59 QPointer<QObjectType> mPtr;
60 public:
61
66 { }
67
71 inline QObjectUniquePtr( T *p ) : mPtr( p )
72 { }
73
78 {
79 // Will be a nullptr if the QObject has been deleted from somewhere else (e.g. through parent ownership)
80 delete mPtr.data();
81 }
82
83 // This is a unique ptr, so copy is forbidden and we need to implement the move constructor/operator
84 QObjectUniquePtr( const QObjectUniquePtr &other ) = delete;
85 QObjectUniquePtr &operator=( const QObjectUniquePtr &other ) = delete;
86
88 {
89 *this = std::move( other );
90 }
91
93 {
94 if ( &other == this )
95 return *this;
96
97 delete mPtr.data();
98 mPtr = other.mPtr;
99 other.clear();
100 return *this;
101 }
102
106 inline void swap( QObjectUniquePtr &other )
107 {
108 mPtr.swap( other.mPtr );
109 }
110
112 {
113 mPtr.assign( static_cast<QObjectType *>( p ) );
114 return *this;
115 }
116
120 inline T *data() const
121 {
122 return static_cast<T *>( mPtr.data() );
123 }
124
128 inline T *get() const
129 {
130 return static_cast<T *>( mPtr.data() );
131 }
132
136 inline T *operator->() const
137 {
138 return data();
139 }
140
144 inline T &operator*() const
145 {
146 return *data();
147 }
148
152 inline operator T *() const
153 {
154 return data();
155 }
156
160 inline bool isNull() const
161 {
162 return mPtr.isNull();
163 }
164
170 explicit inline operator bool() const
171 {
172 return !mPtr.isNull();
173 }
174
178 inline void clear()
179 {
180 mPtr.clear();
181 }
182
187 inline T *release()
188 {
189 T *p = qobject_cast<T *>( mPtr.data() );
190 mPtr.clear();
191 return p;
192 }
193
199 void reset( T *p = nullptr )
200 {
201 delete mPtr.data();
202 mPtr = p;
203 }
204};
205template <class T> Q_DECLARE_TYPEINFO_BODY( QObjectUniquePtr<T>, Q_MOVABLE_TYPE );
206
207template <class T>
208inline bool operator==( const T *o, const QObjectUniquePtr<T> &p )
209{
210 return o == p.operator->();
211}
212
213template<class T>
214inline bool operator==( const QObjectUniquePtr<T> &p, const T *o )
215{
216 return p.operator->() == o;
217}
218
219template <class T>
220inline bool operator==( T *o, const QObjectUniquePtr<T> &p )
221{
222 return o == p.operator->();
223}
224
225template<class T>
226inline bool operator==( const QObjectUniquePtr<T> &p, T *o )
227{
228 return p.operator->() == o;
229}
230
231template<class T>
232inline bool operator==( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
233{
234 return p1.operator->() == p2.operator->();
235}
236
237template <class T>
238inline bool operator!=( const T *o, const QObjectUniquePtr<T> &p )
239{
240 return o != p.operator->();
241}
242
243template<class T>
244inline bool operator!= ( const QObjectUniquePtr<T> &p, const T *o )
245{
246 return p.operator->() != o;
247}
248
249template <class T>
250inline bool operator!=( T *o, const QObjectUniquePtr<T> &p )
251{
252 return o != p.operator->();
253}
254
255template<class T>
256inline bool operator!= ( const QObjectUniquePtr<T> &p, T *o )
257{
258 return p.operator->() != o;
259}
260
261template<class T>
262inline bool operator!= ( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
263{
264 return p1.operator->() != p2.operator->() ;
265}
266
267template<typename T>
269QObjectUniquePtrFromVariant( const QVariant &variant )
270{
271 return QObjectUniquePtr<T>( qobject_cast<T *>( QtSharedPointer::weakPointerFromVariant_internal( variant ).toStrongRef().data() ) );
272}
273
274
275
276
288template <class T>
290{
291 Q_STATIC_ASSERT_X( !std::is_pointer<T>::value, "QObjectParentUniquePtr's template object type must not be a pointer type" );
292
293 T *mChild = nullptr;
294
295 QPointer<QObject> mParent;
296 QMetaObject::Connection mParentDestroyedConnection;
297
298 public:
299
304 { }
305
309 inline QObjectParentUniquePtr( T *child, QObject *parent )
310 : mChild( child )
311 {
312 if ( parent )
313 {
314 setParentOwner( parent );
315 }
316 }
317 // compiler-generated copy/move ctor/assignment operators are fine!
318
323 {
324 if ( mParent )
325 {
326 QObject::disconnect( mParentDestroyedConnection );
327 mParent = nullptr;
328 }
329 if ( mChild )
330 {
331 // child is being deleted BEFORE parent, so we are responsible for deleting it
332 delete mChild;
333 mChild = nullptr;
334 }
335 }
336
340 inline void setParentOwner( QObject *parent )
341 {
342 if ( mParent )
343 {
344 QObject::disconnect( mParentDestroyedConnection );
345 }
346 mParentDestroyedConnection = QObject::connect( parent, &QObject::destroyed, parent, [this]()
347 {
348 mParent = nullptr;
349 // parent is being deleted BEFORE child, so it is responsible for deleting the child -- we don't need to delete it here!
350 mChild = nullptr;
351 } );
352 mParent = parent;
353 }
354
361 {
362 if ( child && !mParent )
363 {
364 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
365 }
366 delete mChild;
367 mChild = child;
368 return *this;
369 }
370
374 inline T *data() const
375 {
376 return static_cast<T *>( mChild );
377 }
378
382 inline T *get() const
383 {
384 return static_cast<T *>( mChild );
385 }
386
390 inline T *operator->() const
391 {
392 return data();
393 }
394
400 inline T &operator*() const
401 {
402 return *data();
403 }
404
408 inline operator T *() const
409 {
410 return data();
411 }
412
416 inline bool isNull() const
417 {
418 return !mChild;
419 }
420
427 explicit inline operator bool() const
428 {
429 return static_cast< bool >( mChild );
430 }
431
435 inline void clear()
436 {
437 mChild = nullptr;
438 }
439
446 inline T *release()
447 {
448 T *p = qobject_cast<T *>( mChild );
449 mChild = nullptr;
450 return p;
451 }
452
461 void reset( T *p = nullptr )
462 {
463 if ( p && !mParent )
464 {
465 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
466 }
467 delete mChild;
468 mChild = p;
469 }
470};
471
472template <class T>
473inline bool operator==( const T *o, const QObjectParentUniquePtr<T> &p )
474{
475 return o == p.operator->();
476}
477
478template<class T>
479inline bool operator==( const QObjectParentUniquePtr<T> &p, const T *o )
480{
481 return p.operator->() == o;
482}
483
484template <class T>
485inline bool operator==( T *o, const QObjectParentUniquePtr<T> &p )
486{
487 return o == p.operator->();
488}
489
490template<class T>
491inline bool operator==( const QObjectParentUniquePtr<T> &p, T *o )
492{
493 return p.operator->() == o;
494}
495
496template<class T>
498{
499 return p1.operator->() == p2.operator->();
500}
501
502template <class T>
503inline bool operator!=( const T *o, const QObjectParentUniquePtr<T> &p )
504{
505 return o != p.operator->();
506}
507
508template<class T>
509inline bool operator!= ( const QObjectParentUniquePtr<T> &p, const T *o )
510{
511 return p.operator->() != o;
512}
513
514template <class T>
515inline bool operator!=( T *o, const QObjectParentUniquePtr<T> &p )
516{
517 return o != p.operator->();
518}
519
520template<class T>
521inline bool operator!= ( const QObjectParentUniquePtr<T> &p, T *o )
522{
523 return p.operator->() != o;
524}
525
526template<class T>
528{
529 return p1.operator->() != p2.operator->() ;
530}
531
532
533#endif // QOBJECTUNIQUEPTR_H
Keeps a pointer to an object owned by a QObject parent, and deletes it whenever this parent object is...
T * data() const
Returns the raw pointer to the managed QObject.
T * operator->() const
Returns a raw pointer to the managed child.
T & operator*() const
Dereferences the managed child.
QObjectParentUniquePtr< T > & operator=(T *child)
Assigns a new child to the pointer.
void setParentOwner(QObject *parent)
Sets the parent object.
void reset(T *p=nullptr)
Will reset the managed pointer to p.
QObjectParentUniquePtr()
Creates a new empty QObjectParentUniquePtr.
T * get() const
Returns the raw pointer to the managed child.
void clear()
Clears the pointer.
bool isNull() const
Checks if the managed pointer is nullptr.
T * release()
Clears the pointer and returns it.
~QObjectParentUniquePtr()
Will delete the contained object if the parent still exists.
QObjectParentUniquePtr(T *child, QObject *parent)
Takes a new QObjectParentUniquePtr and assign a child to it.
Keeps a pointer to a QObject and deletes it whenever this object is deleted.
QObjectUniquePtr< T > & operator=(T *p)
void reset(T *p=nullptr)
Will reset the managed pointer to p.
bool isNull() const
Checks if the managed pointer is nullptr.
QObjectUniquePtr(const QObjectUniquePtr &other)=delete
T & operator*() const
Dereferences the managed QObject.
QObjectUniquePtr()
Creates a new empty QObjectUniquePtr.
~QObjectUniquePtr()
Will delete the contained QObject if it still exists.
QObjectUniquePtr(QObjectUniquePtr &&other)
QObjectUniquePtr(T *p)
Takes a new QObjectUniquePtr and assigned p to it.
QObjectUniquePtr & operator=(const QObjectUniquePtr &other)=delete
T * release()
Clears the pointer and returns it.
T * get() const
Returns the raw pointer to the managed QObject.
void swap(QObjectUniquePtr &other)
Swaps the pointer managed by this instance with the pointer managed by other.
QObjectUniquePtr & operator=(QObjectUniquePtr &&other) noexcept
T * data() const
Returns the raw pointer to the managed QObject.
T * operator->() const
Returns a raw pointer to the managed QObject.
void clear()
Clears the pointer.
bool operator==(const T *o, const QObjectUniquePtr< T > &p)
Q_DECLARE_TYPEINFO_BODY(QObjectUniquePtr< T >, Q_MOVABLE_TYPE)
bool operator!=(const T *o, const QObjectUniquePtr< T > &p)
QObjectUniquePtr< T > QObjectUniquePtrFromVariant(const QVariant &variant)