QGIS API Documentation 3.99.0-Master (7d2ca374f2d)
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
25#include <QObject>
26#include <QPointer>
27#include <QtDebug>
28#include <qtypeinfo.h>
29
30#define SIP_NO_FILE
31
32class QVariant;
33
44template <class T>
46{
47 Q_STATIC_ASSERT_X( !std::is_pointer<T>::value, "QObjectUniquePtr's template type must not be a pointer type" );
48
49 template<typename U>
50 struct TypeSelector
51 {
52 typedef QObject Type;
53 };
54 template<typename U>
55 struct TypeSelector<const U>
56 {
57 typedef const QObject Type;
58 };
59 typedef typename TypeSelector<T>::Type QObjectType;
60 QPointer<QObjectType> mPtr;
61 public:
62
67 { }
68
72 inline QObjectUniquePtr( T *p ) : mPtr( p )
73 { }
74
79 {
80 // Will be a nullptr if the QObject has been deleted from somewhere else (e.g. through parent ownership)
81 delete mPtr.data();
82 }
83
84 // This is a unique ptr, so copy is forbidden and we need to implement the move constructor/operator
85 QObjectUniquePtr( const QObjectUniquePtr &other ) = delete;
86 QObjectUniquePtr &operator=( const QObjectUniquePtr &other ) = delete;
87
89 {
90 *this = std::move( other );
91 }
92
94 {
95 if ( &other == this )
96 return *this;
97
98 delete mPtr.data();
99 mPtr = other.mPtr;
100 other.clear();
101 return *this;
102 }
103
107 inline void swap( QObjectUniquePtr &other )
108 {
109 mPtr.swap( other.mPtr );
110 }
111
113 {
114 mPtr.assign( static_cast<QObjectType *>( p ) );
115 return *this;
116 }
117
121 inline T *data() const
122 {
123 return static_cast<T *>( mPtr.data() );
124 }
125
129 inline T *get() const
130 {
131 return static_cast<T *>( mPtr.data() );
132 }
133
137 inline T *operator->() const
138 {
139 return data();
140 }
141
145 inline T &operator*() const
146 {
147 return *data();
148 }
149
153 inline operator T *() const
154 {
155 return data();
156 }
157
161 inline bool isNull() const
162 {
163 return mPtr.isNull();
164 }
165
171 explicit inline operator bool() const
172 {
173 return !mPtr.isNull();
174 }
175
179 inline void clear()
180 {
181 mPtr.clear();
182 }
183
188 inline T *release()
189 {
190 T *p = qobject_cast<T *>( mPtr.data() );
191 mPtr.clear();
192 return p;
193 }
194
200 void reset( T *p = nullptr )
201 {
202 delete mPtr.data();
203 mPtr = p;
204 }
205};
206template <class T> Q_DECLARE_TYPEINFO_BODY( QObjectUniquePtr<T>, Q_MOVABLE_TYPE );
207
208template <class T>
209inline bool operator==( const T *o, const QObjectUniquePtr<T> &p )
210{
211 return o == p.operator->();
212}
213
214template<class T>
215inline bool operator==( const QObjectUniquePtr<T> &p, const T *o )
216{
217 return p.operator->() == o;
218}
219
220template <class T>
221inline bool operator==( T *o, const QObjectUniquePtr<T> &p )
222{
223 return o == p.operator->();
224}
225
226template<class T>
227inline bool operator==( const QObjectUniquePtr<T> &p, T *o )
228{
229 return p.operator->() == o;
230}
231
232template<class T>
233inline bool operator==( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
234{
235 return p1.operator->() == p2.operator->();
236}
237
238template <class T>
239inline bool operator!=( const T *o, const QObjectUniquePtr<T> &p )
240{
241 return o != p.operator->();
242}
243
244template<class T>
245inline bool operator!= ( const QObjectUniquePtr<T> &p, const T *o )
246{
247 return p.operator->() != o;
248}
249
250template <class T>
251inline bool operator!=( T *o, const QObjectUniquePtr<T> &p )
252{
253 return o != p.operator->();
254}
255
256template<class T>
257inline bool operator!= ( const QObjectUniquePtr<T> &p, T *o )
258{
259 return p.operator->() != o;
260}
261
262template<class T>
263inline bool operator!= ( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
264{
265 return p1.operator->() != p2.operator->() ;
266}
267
268template<typename T>
270QObjectUniquePtrFromVariant( const QVariant &variant )
271{
272 return QObjectUniquePtr<T>( qobject_cast<T *>( QtSharedPointer::weakPointerFromVariant_internal( variant ).toStrongRef().data() ) );
273}
274
275
276
277
289template <class T>
291{
292 Q_STATIC_ASSERT_X( !std::is_pointer<T>::value, "QObjectParentUniquePtr's template object type must not be a pointer type" );
293
294 T *mChild = nullptr;
295
296 QPointer<QObject> mParent;
297 QMetaObject::Connection mParentDestroyedConnection;
298
299 public:
300
305 { }
306
310 inline QObjectParentUniquePtr( T *child, QObject *parent )
311 : mChild( child )
312 {
313 if ( parent )
314 {
315 setParentOwner( parent );
316 }
317 }
318 // compiler-generated copy/move ctor/assignment operators are fine!
319
324 {
325 if ( mParent )
326 {
327 QObject::disconnect( mParentDestroyedConnection );
328 mParent = nullptr;
329 }
330 if ( mChild )
331 {
332 // child is being deleted BEFORE parent, so we are responsible for deleting it
333 delete mChild;
334 mChild = nullptr;
335 }
336 }
337
341 inline void setParentOwner( QObject *parent )
342 {
343 if ( mParent )
344 {
345 QObject::disconnect( mParentDestroyedConnection );
346 }
347 mParentDestroyedConnection = QObject::connect( parent, &QObject::destroyed, parent, [this]()
348 {
349 mParent = nullptr;
350 // parent is being deleted BEFORE child, so it is responsible for deleting the child -- we don't need to delete it here!
351 mChild = nullptr;
352 } );
353 mParent = parent;
354 }
355
362 {
363 if ( child && !mParent )
364 {
365 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
366 }
367 delete mChild;
368 mChild = child;
369 return *this;
370 }
371
375 inline T *data() const
376 {
377 return static_cast<T *>( mChild );
378 }
379
383 inline T *get() const
384 {
385 return static_cast<T *>( mChild );
386 }
387
391 inline T *operator->() const
392 {
393 return data();
394 }
395
401 inline T &operator*() const
402 {
403 return *data();
404 }
405
409 inline operator T *() const
410 {
411 return data();
412 }
413
417 inline bool isNull() const
418 {
419 return !mChild;
420 }
421
428 explicit inline operator bool() const
429 {
430 return static_cast< bool >( mChild );
431 }
432
436 inline void clear()
437 {
438 mChild = nullptr;
439 }
440
447 inline T *release()
448 {
449 T *p = qobject_cast<T *>( mChild );
450 mChild = nullptr;
451 return p;
452 }
453
462 void reset( T *p = nullptr )
463 {
464 if ( p && !mParent )
465 {
466 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
467 }
468 delete mChild;
469 mChild = p;
470 }
471};
472
473template <class T>
474inline bool operator==( const T *o, const QObjectParentUniquePtr<T> &p )
475{
476 return o == p.operator->();
477}
478
479template<class T>
480inline bool operator==( const QObjectParentUniquePtr<T> &p, const T *o )
481{
482 return p.operator->() == o;
483}
484
485template <class T>
486inline bool operator==( T *o, const QObjectParentUniquePtr<T> &p )
487{
488 return o == p.operator->();
489}
490
491template<class T>
492inline bool operator==( const QObjectParentUniquePtr<T> &p, T *o )
493{
494 return p.operator->() == o;
495}
496
497template<class T>
499{
500 return p1.operator->() == p2.operator->();
501}
502
503template <class T>
504inline bool operator!=( const T *o, const QObjectParentUniquePtr<T> &p )
505{
506 return o != p.operator->();
507}
508
509template<class T>
510inline bool operator!= ( const QObjectParentUniquePtr<T> &p, const T *o )
511{
512 return p.operator->() != o;
513}
514
515template <class T>
516inline bool operator!=( T *o, const QObjectParentUniquePtr<T> &p )
517{
518 return o != p.operator->();
519}
520
521template<class T>
522inline bool operator!= ( const QObjectParentUniquePtr<T> &p, T *o )
523{
524 return p.operator->() != o;
525}
526
527template<class T>
529{
530 return p1.operator->() != p2.operator->() ;
531}
532
533
534#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)