QGIS API Documentation 4.1.0-Master (60fea48833c)
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> class QObjectUniquePtr
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> struct TypeSelector
49 {
50 typedef QObject Type;
51 };
52 template<typename U> struct TypeSelector<const U>
53 {
54 typedef const QObject Type;
55 };
56 typedef typename TypeSelector<T>::Type QObjectType;
57 QPointer<QObjectType> mPtr;
58
59 public:
63 inline QObjectUniquePtr() {}
64
68 inline QObjectUniquePtr( T *p )
69 : mPtr( p )
70 {}
71
76 {
77 // Will be a nullptr if the QObject has been deleted from somewhere else (e.g. through parent ownership)
78 delete mPtr.data();
79 }
80
81 // This is a unique ptr, so copy is forbidden and we need to implement the move constructor/operator
82 QObjectUniquePtr( const QObjectUniquePtr &other ) = delete;
83 QObjectUniquePtr &operator=( const QObjectUniquePtr &other ) = delete;
84
85 QObjectUniquePtr( QObjectUniquePtr &&other ) { *this = std::move( other ); }
86
88 {
89 if ( &other == this )
90 return *this;
91
92 delete mPtr.data();
93 mPtr = other.mPtr;
94 other.clear();
95 return *this;
96 }
97
101 inline void swap( QObjectUniquePtr &other ) { mPtr.swap( other.mPtr ); }
102
104 {
105 mPtr.assign( static_cast<QObjectType *>( p ) );
106 return *this;
107 }
108
112 inline T *data() const { return static_cast<T *>( mPtr.data() ); }
113
117 inline T *get() const { return static_cast<T *>( mPtr.data() ); }
118
122 inline T *operator->() const { return data(); }
123
127 inline T &operator*() const { return *data(); }
128
132 inline operator T *() const { return data(); }
133
137 inline bool isNull() const { return mPtr.isNull(); }
138
144 explicit inline operator bool() const { return !mPtr.isNull(); }
145
149 inline void clear() { mPtr.clear(); }
150
155 inline T *release()
156 {
157 T *p = qobject_cast<T *>( mPtr.data() );
158 mPtr.clear();
159 return p;
160 }
161
167 void reset( T *p = nullptr )
168 {
169 delete mPtr.data();
170 mPtr = p;
171 }
172};
173template<class T> Q_DECLARE_TYPEINFO_BODY( QObjectUniquePtr<T>, Q_MOVABLE_TYPE );
174
175template<class T> inline bool operator==( const T *o, const QObjectUniquePtr<T> &p )
176{
177 return o == p.operator->();
178}
179
180template<class T> inline bool operator==( const QObjectUniquePtr<T> &p, const T *o )
181{
182 return p.operator->() == o;
183}
184
185template<class T> inline bool operator==( T *o, const QObjectUniquePtr<T> &p )
186{
187 return o == p.operator->();
188}
189
190template<class T> inline bool operator==( const QObjectUniquePtr<T> &p, T *o )
191{
192 return p.operator->() == o;
193}
194
195template<class T> inline bool operator==( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
196{
197 return p1.operator->() == p2.operator->();
198}
199
200template<class T> inline bool operator!=( const T *o, const QObjectUniquePtr<T> &p )
201{
202 return o != p.operator->();
203}
204
205template<class T> inline bool operator!=( const QObjectUniquePtr<T> &p, const T *o )
206{
207 return p.operator->() != o;
208}
209
210template<class T> inline bool operator!=( T *o, const QObjectUniquePtr<T> &p )
211{
212 return o != p.operator->();
213}
214
215template<class T> inline bool operator!=( const QObjectUniquePtr<T> &p, T *o )
216{
217 return p.operator->() != o;
218}
219
220template<class T> inline bool operator!=( const QObjectUniquePtr<T> &p1, const QObjectUniquePtr<T> &p2 )
221{
222 return p1.operator->() != p2.operator->();
223}
224
225template<typename T> QObjectUniquePtr<T> QObjectUniquePtrFromVariant( const QVariant &variant )
226{
227 return QObjectUniquePtr<T>( qobject_cast<T *>( QtSharedPointer::weakPointerFromVariant_internal( variant ).toStrongRef().data() ) );
228}
229
230
242template<class T> class QObjectParentUniquePtr
243{
244 Q_STATIC_ASSERT_X( !std::is_pointer<T>::value, "QObjectParentUniquePtr's template object type must not be a pointer type" );
245
246 T *mChild = nullptr;
247
248 QPointer<QObject> mParent;
249 QMetaObject::Connection mParentDestroyedConnection;
250
251 public:
256
260 inline QObjectParentUniquePtr( T *child, QObject *parent )
261 : mChild( child )
262 {
263 if ( parent )
264 {
265 setParentOwner( parent );
266 }
267 }
268 // compiler-generated copy/move ctor/assignment operators are fine!
269
274 {
275 if ( mParent )
276 {
277 QObject::disconnect( mParentDestroyedConnection );
278 mParent = nullptr;
279 }
280 if ( mChild )
281 {
282 // child is being deleted BEFORE parent, so we are responsible for deleting it
283 delete mChild;
284 mChild = nullptr;
285 }
286 }
287
291 inline void setParentOwner( QObject *parent )
292 {
293 if ( mParent )
294 {
295 QObject::disconnect( mParentDestroyedConnection );
296 }
297 mParentDestroyedConnection = QObject::connect( parent, &QObject::destroyed, parent, [this]() {
298 mParent = nullptr;
299 // parent is being deleted BEFORE child, so it is responsible for deleting the child -- we don't need to delete it here!
300 mChild = nullptr;
301 } );
302 mParent = parent;
303 }
304
311 {
312 if ( child && !mParent )
313 {
314 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
315 }
316 delete mChild;
317 mChild = child;
318 return *this;
319 }
320
324 inline T *data() const { return static_cast<T *>( mChild ); }
325
329 inline T *get() const { return static_cast<T *>( mChild ); }
330
334 inline T *operator->() const { return data(); }
335
341 inline T &operator*() const { return *data(); }
342
346 inline operator T *() const { return data(); }
347
351 inline bool isNull() const { return !mChild; }
352
359 explicit inline operator bool() const { return static_cast< bool >( mChild ); }
360
364 inline void clear() { mChild = nullptr; }
365
372 inline T *release()
373 {
374 T *p = qobject_cast<T *>( mChild );
375 mChild = nullptr;
376 return p;
377 }
378
387 void reset( T *p = nullptr )
388 {
389 if ( p && !mParent )
390 {
391 qWarning() << "Assigning pointer to QObjectParentUniquePtr with nullptr parent.";
392 }
393 delete mChild;
394 mChild = p;
395 }
396};
397
398template<class T> inline bool operator==( const T *o, const QObjectParentUniquePtr<T> &p )
399{
400 return o == p.operator->();
401}
402
403template<class T> inline bool operator==( const QObjectParentUniquePtr<T> &p, const T *o )
404{
405 return p.operator->() == o;
406}
407
408template<class T> inline bool operator==( T *o, const QObjectParentUniquePtr<T> &p )
409{
410 return o == p.operator->();
411}
412
413template<class T> inline bool operator==( const QObjectParentUniquePtr<T> &p, T *o )
414{
415 return p.operator->() == o;
416}
417
418template<class T> inline bool operator==( const QObjectParentUniquePtr<T> &p1, const QObjectParentUniquePtr<T> &p2 )
419{
420 return p1.operator->() == p2.operator->();
421}
422
423template<class T> inline bool operator!=( const T *o, const QObjectParentUniquePtr<T> &p )
424{
425 return o != p.operator->();
426}
427
428template<class T> inline bool operator!=( const QObjectParentUniquePtr<T> &p, const T *o )
429{
430 return p.operator->() != o;
431}
432
433template<class T> inline bool operator!=( T *o, const QObjectParentUniquePtr<T> &p )
434{
435 return o != p.operator->();
436}
437
438template<class T> inline bool operator!=( const QObjectParentUniquePtr<T> &p, T *o )
439{
440 return p.operator->() != o;
441}
442
443template<class T> inline bool operator!=( const QObjectParentUniquePtr<T> &p1, const QObjectParentUniquePtr<T> &p2 )
444{
445 return p1.operator->() != p2.operator->();
446}
447
448
449#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)