1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QPOINTER_H
5#define QPOINTER_H
6
7#include <QtCore/qsharedpointer.h>
8#include <QtCore/qtypeinfo.h>
9
10#ifndef QT_NO_QOBJECT
11
12QT_BEGIN_NAMESPACE
13
14class QVariant;
15
16template <class T>
17class QPointer
18{
19 static_assert(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
20
21 template <typename X>
22 using if_convertible = std::enable_if_t<std::is_convertible_v<X*, T*>, bool>;
23 template <typename X>
24 friend class QPointer;
25
26 using QObjectType =
27 typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
28 QWeakPointer<QObjectType> wp;
29public:
30 Q_NODISCARD_CTOR
31 QPointer() = default;
32 Q_NODISCARD_CTOR
33 inline QPointer(T *p) : wp(p, true) { }
34 // compiler-generated copy/move ctor/assignment operators are fine!
35 // compiler-generated dtor is fine!
36
37 template <typename X, if_convertible<X> = true>
38 Q_NODISCARD_CTOR
39 QPointer(QPointer<X> &&other) noexcept
40 : wp(std::exchange(other.wp, nullptr).internalData(), true) {}
41 template <typename X, if_convertible<X> = true>
42 Q_NODISCARD_CTOR
43 QPointer(const QPointer<X> &other) noexcept
44 : wp(other.wp.internalData(), true) {}
45
46 template <typename X, if_convertible<X> = true>
47 QPointer &operator=(const QPointer<X> &other)
48 {
49 wp.assign(other.data());
50 return *this;
51 }
52
53#ifdef Q_QDOC
54 // Stop qdoc from complaining about missing function
55 ~QPointer();
56#endif
57
58 inline void swap(QPointer &other) noexcept { wp.swap(other.wp); }
59
60 inline QPointer<T> &operator=(T* p)
61 { wp.assign(static_cast<QObjectType*>(p)); return *this; }
62
63 inline T* data() const
64 { return static_cast<T*>(wp.internalData()); }
65 inline T* get() const
66 { return data(); }
67 inline T* operator->() const
68 { return data(); }
69 inline T& operator*() const
70 { return *data(); }
71 inline operator T*() const
72 { return data(); }
73
74 inline bool isNull() const
75 { return wp.isNull(); }
76
77 inline void clear()
78 { wp.clear(); }
79
80#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \
81 friend bool operator==(T1, T2) \
82 { return A1 == A2; } \
83 friend bool operator!=(T1, T2) \
84 { return A1 != A2; }
85
86#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \
87 template <typename X> \
88 friend bool operator==(T1, T2) noexcept \
89 { return A1 == A2; } \
90 template <typename X> \
91 friend bool operator!=(T1, T2) noexcept \
92 { return A1 != A2; }
93
94 DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), const QPointer<X> &p2, p2.data())
95 DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), X *ptr, ptr)
96 DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr, const QPointer &p2, p2.data())
97 DECLARE_COMPARE_SET(const QPointer &p1, p1.data(), std::nullptr_t, nullptr)
98 DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QPointer &p2, p2.data())
99#undef DECLARE_COMPARE_SET
100#undef DECLARE_TEMPLATE_COMPARE_SET
101};
102template <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_RELOCATABLE_TYPE);
103
104template<typename T>
105QPointer<T>
106qPointerFromVariant(const QVariant &variant)
107{
108 const auto wp = QtSharedPointer::weakPointerFromVariant_internal(variant);
109 return QPointer<T>{qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(p: wp))};
110}
111
112template <class T>
113inline void swap(QPointer<T> &p1, QPointer<T> &p2) noexcept
114{ p1.swap(p2); }
115
116QT_END_NAMESPACE
117
118#endif // QT_NO_QOBJECT
119
120#endif // QPOINTER_H
121

source code of qtbase/src/corelib/kernel/qpointer.h