Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlrefcount_p.h
Go to the documentation of this file.
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 QQMLREFCOUNT_P_H
5#define QQMLREFCOUNT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qglobal.h>
19#include <QtCore/qatomic.h>
20#include <private/qv4global_p.h>
21
23
24template <typename T>
25class QQmlRefCounted;
26
28{
29 Q_DISABLE_COPY_MOVE(QQmlRefCount)
30public:
31 inline QQmlRefCount();
32 inline void addref() const;
33 inline int count() const;
34
35private:
36 inline ~QQmlRefCount();
37 template <typename T> friend class QQmlRefCounted;
38
39private:
40 mutable QAtomicInt refCount;
41};
42
43template <typename T>
45{
46public:
47 inline void release() const;
48protected:
50};
51
52template<class T>
54{
55public:
56 enum Mode {
58 Adopt
59 };
64 inline ~QQmlRefPointer();
65
66 void swap(QQmlRefPointer &other) noexcept { qt_ptr_swap(o, other.o); }
67
68 inline QQmlRefPointer<T> &operator=(const QQmlRefPointer<T> &o);
69 inline QQmlRefPointer<T> &operator=(QQmlRefPointer<T> &&o) noexcept;
70
71 inline bool isNull() const { return !o; }
72
73 inline T* operator->() const { return o; }
74 inline T& operator*() const { return *o; }
75 explicit inline operator bool() const { return o != nullptr; }
76 inline T* data() const { return o; }
77
78 inline QQmlRefPointer<T> &adopt(T *);
79
80 inline T* take() { T *res = o; o = nullptr; return res; }
81
82 friend bool operator==(const QQmlRefPointer &a, const QQmlRefPointer &b) noexcept
83 {
84 return a.o == b.o;
85 }
86
87 friend bool operator!=(const QQmlRefPointer &a, const QQmlRefPointer &b) noexcept
88 {
89 return !(a == b);
90 }
91
92 friend size_t qHash(const QQmlRefPointer &v, size_t seed = 0) noexcept
93 {
94 return qHash(v.o, seed);
95 }
96
97 void reset(T *t = nullptr)
98 {
99 if (t == o)
100 return;
101 if (o)
102 o->release();
103 if (t)
104 t->addref();
105 o = t;
106 }
107
108private:
109 T *o;
110};
111
112namespace QQml {
119template <typename T, typename ...Args>
120QQmlRefPointer<T> makeRefPointer(Args&&... args)
121{
122 static_assert(std::is_base_of_v<QQmlRefCount, T>);
123 return QQmlRefPointer<T>(new T(std::forward<Args>(args)...), QQmlRefPointer<T>::Adopt);
124}
125}
126
127template <typename T>
129
131: refCount(1)
132{
133}
134
135QQmlRefCount::~QQmlRefCount()
136{
137 Q_ASSERT(refCount.loadRelaxed() == 0);
138}
139
141{
142 Q_ASSERT(refCount.loadRelaxed() > 0);
143 refCount.ref();
144}
145
146template <typename T>
148{
149 static_assert(std::is_base_of_v<QQmlRefCounted, T>,
150 "QQmlRefCounted<T> must be a base of T (CRTP)");
151 Q_ASSERT(refCount.loadRelaxed() > 0);
152 if (!refCount.deref())
153 delete static_cast<const T *>(this);
154}
155
156template <typename T>
158{
159 static_assert(std::is_final_v<T> || std::has_virtual_destructor_v<T>,
160 "T must either be marked final or have a virtual dtor, "
161 "lest release() runs into UB.");
162}
163
165{
166 return refCount.loadRelaxed();
167}
168
169template<class T>
171: o(nullptr)
172{
173}
174
175template<class T>
177: o(o)
178{
179 if (m == AddRef && o)
180 o->addref();
181}
182
183template<class T>
185: o(other.o)
186{
187 if (o) o->addref();
188}
189
190template <class T>
191QQmlRefPointer<T>::QQmlRefPointer(QQmlRefPointer<T> &&other) noexcept
192 : o(other.take())
193{
194}
195
196template<class T>
198{
199 if (o) o->release();
200}
201
202template<class T>
203QQmlRefPointer<T> &QQmlRefPointer<T>::operator=(const QQmlRefPointer<T> &other)
204{
205 if (o == other.o)
206 return *this;
207 if (other.o)
208 other.o->addref();
209 if (o)
210 o->release();
211 o = other.o;
212 return *this;
213}
214
215template <class T>
216QQmlRefPointer<T> &QQmlRefPointer<T>::operator=(QQmlRefPointer<T> &&other) noexcept
217{
218 QQmlRefPointer<T> m(std::move(other));
219 swap(m);
220 return *this;
221}
222
227template<class T>
228QQmlRefPointer<T> &QQmlRefPointer<T>::adopt(T *other)
229{
230 if (o) o->release();
231 o = other;
232 return *this;
233}
234
236
237#endif // QQMLREFCOUNT_P_H
\inmodule QtCore
Definition qatomic.h:112
bool ref() noexcept
T loadRelaxed() const noexcept
void addref() const
int count() const
void release() const
T * data() const
T & operator*() const
void swap(QQmlRefPointer &other) noexcept
QQmlRefPointer< T > & operator=(const QQmlRefPointer< T > &o)
QQmlRefPointer< T > & operator=(QQmlRefPointer< T > &&o) noexcept
void reset(T *t=nullptr)
friend size_t qHash(const QQmlRefPointer &v, size_t seed=0) noexcept
QQmlRefPointer< T > & adopt(T *)
Takes ownership of other.
T * operator->() const
friend bool operator!=(const QQmlRefPointer &a, const QQmlRefPointer &b) noexcept
friend bool operator==(const QQmlRefPointer &a, const QQmlRefPointer &b) noexcept
bool isNull() const
Q_NODISCARD_CTOR QQmlRefPointer() noexcept
QQmlRefPointer< T > makeRefPointer(Args &&... args)
Combined button and popup list for selecting options.
#define Q_NODISCARD_CTOR
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint res
GLdouble GLdouble t
Definition qopenglext.h:243
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Definition qswap.h:29
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:158
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
Definition qtypeinfo.h:163
QSharedPointer< T > other(t)
[5]
this swap(other)
QJSValueList args