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
qshareddata.h
Go to the documentation of this file.
1// Copyright (C) 2020 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 QSHAREDDATA_H
5#define QSHAREDDATA_H
6
7#include <QtCore/qglobal.h>
8#include <QtCore/qatomic.h>
9#include <QtCore/qhashfunctions.h>
10
11#include <functional>
12
14
15
16template <class T> class QSharedDataPointer;
17
19{
20public:
21 mutable QAtomicInt ref;
22
23 QSharedData() noexcept : ref(0) { }
24 QSharedData(const QSharedData &) noexcept : ref(0) { }
25
26 // using the assignment operator would lead to corruption in the ref-counting
27 QSharedData &operator=(const QSharedData &) = delete;
28 ~QSharedData() = default;
29};
30
31struct QAdoptSharedDataTag { explicit constexpr QAdoptSharedDataTag() = default; };
32
33template <typename T>
35{
36public:
37 typedef T Type;
38 typedef T *pointer;
39
40 void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
41 T &operator*() { detach(); return *d; }
42 const T &operator*() const { return *d; }
43 T *operator->() { detach(); return d; }
44 const T *operator->() const noexcept { return d; }
45 operator T *() { detach(); return d; }
46 operator const T *() const noexcept { return d; }
47 T *data() { detach(); return d; }
48 T *get() { detach(); return d; }
49 const T *data() const noexcept { return d; }
50 const T *get() const noexcept { return d; }
51 const T *constData() const noexcept { return d; }
52 T *take() noexcept { return std::exchange(d, nullptr); }
53
55 QSharedDataPointer() noexcept : d(nullptr) { }
56 ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
57
59 explicit QSharedDataPointer(T *data) noexcept : d(data)
60 { if (d) d->ref.ref(); }
65 QSharedDataPointer(const QSharedDataPointer &o) noexcept : d(o.d)
66 { if (d) d->ref.ref(); }
67
68 void reset(T *ptr = nullptr) noexcept
69 {
70 if (ptr != d) {
71 if (ptr)
72 ptr->ref.ref();
73 T *old = std::exchange(d, ptr);
74 if (old && !old->ref.deref())
75 delete old;
76 }
77 }
78
80 {
81 reset(o.d);
82 return *this;
83 }
84 inline QSharedDataPointer &operator=(T *o) noexcept
85 {
86 reset(o);
87 return *this;
88 }
90 QSharedDataPointer(QSharedDataPointer &&o) noexcept : d(std::exchange(o.d, nullptr)) {}
91 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedDataPointer)
92
93 operator bool () const noexcept { return d != nullptr; }
94 bool operator!() const noexcept { return d == nullptr; }
95
97 { qt_ptr_swap(d, other.d); }
98
99#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \
100 friend bool operator<(T1, T2) noexcept \
101 { return std::less<T*>{}(A1, A2); } \
102 friend bool operator<=(T1, T2) noexcept \
103 { return !std::less<T*>{}(A2, A1); } \
104 friend bool operator>(T1, T2) noexcept \
105 { return std::less<T*>{}(A2, A1); } \
106 friend bool operator>=(T1, T2) noexcept \
107 { return !std::less<T*>{}(A1, A2); } \
108 friend bool operator==(T1, T2) noexcept \
109 { return A1 == A2; } \
110 friend bool operator!=(T1, T2) noexcept \
111 { return A1 != A2; } \
112
114 DECLARE_COMPARE_SET(const QSharedDataPointer &p1, p1.d, const T *ptr, ptr)
115 DECLARE_COMPARE_SET(const T *ptr, ptr, const QSharedDataPointer &p2, p2.d)
116 DECLARE_COMPARE_SET(const QSharedDataPointer &p1, p1.d, std::nullptr_t, nullptr)
117 DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QSharedDataPointer &p2, p2.d)
118
119protected:
120 T *clone();
121
122private:
123 void detach_helper();
124
125 T *d;
126};
127
128template <typename T>
130{
131public:
132 typedef T Type;
133 typedef T *pointer;
134
135 T &operator*() const { return *d; }
136 T *operator->() noexcept { return d; }
137 T *operator->() const noexcept { return d; }
138 explicit operator T *() { return d; }
139 explicit operator const T *() const noexcept { return d; }
140 T *data() const noexcept { return d; }
141 T *get() const noexcept { return d; }
142 const T *constData() const noexcept { return d; }
143 T *take() noexcept { return std::exchange(d, nullptr); }
144
145 void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
146
148 QExplicitlySharedDataPointer() noexcept : d(nullptr) { }
149 ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
150
152 explicit QExplicitlySharedDataPointer(T *data) noexcept : d(data)
153 { if (d) d->ref.ref(); }
159 { if (d) d->ref.ref(); }
160
161 template<typename X>
163 QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) noexcept
164#ifdef QT_ENABLE_QEXPLICITLYSHAREDDATAPOINTER_STATICCAST
165 : d(static_cast<T *>(o.data()))
166#else
167 : d(o.data())
168#endif
169 { if (d) d->ref.ref(); }
170
171 void reset(T *ptr = nullptr) noexcept
172 {
173 if (ptr != d) {
174 if (ptr)
175 ptr->ref.ref();
176 T *old = std::exchange(d, ptr);
177 if (old && !old->ref.deref())
178 delete old;
179 }
180 }
181
183 {
184 reset(o.d);
185 return *this;
186 }
188 {
189 reset(o);
190 return *this;
191 }
193 QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) noexcept : d(std::exchange(o.d, nullptr)) {}
194 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QExplicitlySharedDataPointer)
195
196 operator bool () const noexcept { return d != nullptr; }
197 bool operator!() const noexcept { return d == nullptr; }
198
201
205 DECLARE_COMPARE_SET(const QExplicitlySharedDataPointer &p1, p1.d, std::nullptr_t, nullptr)
206 DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QExplicitlySharedDataPointer &p2, p2.d)
207
208#undef DECLARE_COMPARE_SET
209
210protected:
211 T *clone();
212
213private:
214 void detach_helper();
215
216 T *d;
217};
218
219// Declared here and as Q_OUTOFLINE_TEMPLATE to work-around MSVC bug causing missing symbols at link time.
220template <typename T>
221Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
222{
223 return new T(*d);
224}
225
226template <typename T>
227Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
228{
229 T *x = clone();
230 x->ref.ref();
231 if (!d->ref.deref())
232 delete d;
233 d = x;
234}
235
236template <typename T>
238{
239 return new T(*d);
240}
241
242template <typename T>
243Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
244{
245 T *x = clone();
246 x->ref.ref();
247 if (!d->ref.deref())
248 delete d;
249 d = x;
250}
251
252template <typename T>
253void swap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2) noexcept
254{ p1.swap(p2); }
255
256template <typename T>
257void swap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2) noexcept
258{ p1.swap(p2); }
259
260template <typename T>
261size_t qHash(const QSharedDataPointer<T> &ptr, size_t seed = 0) noexcept
262{
263 return qHash(ptr.data(), seed);
264}
265template <typename T>
266size_t qHash(const QExplicitlySharedDataPointer<T> &ptr, size_t seed = 0) noexcept
267{
268 return qHash(ptr.data(), seed);
269}
270
271template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedDataPointer<T>, Q_RELOCATABLE_TYPE);
272template<typename T> Q_DECLARE_TYPEINFO_BODY(QExplicitlySharedDataPointer<T>, Q_RELOCATABLE_TYPE);
273
274#define QT_DECLARE_QSDP_SPECIALIZATION_DTOR(Class) \
275 template<> QSharedDataPointer<Class>::~QSharedDataPointer();
276
277#define QT_DECLARE_QSDP_SPECIALIZATION_DTOR_WITH_EXPORT(Class, ExportMacro) \
278 template<> ExportMacro QSharedDataPointer<Class>::~QSharedDataPointer();
279
280#define QT_DEFINE_QSDP_SPECIALIZATION_DTOR(Class) \
281 template<> QSharedDataPointer<Class>::~QSharedDataPointer() \
282 { \
283 if (d && !d->ref.deref()) \
284 delete d; \
285 }
286
287#define QT_DECLARE_QESDP_SPECIALIZATION_DTOR(Class) \
288 template<> QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer();
289
290#define QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(Class, ExportMacro) \
291 template<> ExportMacro QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer();
292
293#define QT_DEFINE_QESDP_SPECIALIZATION_DTOR(Class) \
294 template<> QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer() \
295 { \
296 if (d && !d->ref.deref()) \
297 delete d; \
298 }
299
301
302#endif // QSHAREDDATA_H
\inmodule QtCore
Definition qatomic.h:112
Q_NODISCARD_CTOR QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer< X > &o) noexcept
This copy constructor is different in that it allows o to be a different type of explicitly shared da...
T Type
This is the type of the shared data object.
void reset(T *ptr=nullptr) noexcept
Q_NODISCARD_CTOR QExplicitlySharedDataPointer(T *data, QAdoptSharedDataTag) noexcept
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
T * get() const noexcept
QExplicitlySharedDataPointer & operator=(T *o) noexcept
Sets the {d pointer} of this to o and increments {o}'s reference count.
Q_NODISCARD_CTOR QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer &o) noexcept
This standard copy constructor sets the {d pointer} of this to the {d pointer} in o and increments th...
~QExplicitlySharedDataPointer()
Decrements the reference count of the shared data object.
QExplicitlySharedDataPointer & operator=(const QExplicitlySharedDataPointer &o) noexcept
Sets the {d pointer} of this to the {d pointer} of o and increments the reference count of the shared...
T * data() const noexcept
Returns a pointer to the shared data object.
Q_NODISCARD_CTOR QExplicitlySharedDataPointer(T *data) noexcept
Constructs a QExplicitlySharedDataPointer with {d pointer} set to data and increments {data}'s refere...
const T * constData() const noexcept
Returns a const pointer to the shared data object.
T * operator->() noexcept
Provides access to the shared data object's members.
bool operator!() const noexcept
Returns true if the {d pointer} of this is \nullptr.
void swap(QExplicitlySharedDataPointer &other) noexcept
Swap this instance's explicitly shared data pointer with the explicitly shared data pointer in other.
Q_NODISCARD_CTOR QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) noexcept
Move-constructs a QExplicitlySharedDataPointer instance, making it point at the same object that o wa...
T & operator*() const
Provides access to the shared data object's members.
T * operator->() const noexcept
Provides const access to the shared data object's members.
Q_NODISCARD_CTOR QExplicitlySharedDataPointer() noexcept
Constructs a QExplicitlySharedDataPointer initialized with \nullptr as {d pointer}.
void swap(QPixmap &other) noexcept
Swaps pixmap other with this pixmap.
Definition qpixmap.h:43
\inmodule QtCore
Definition qshareddata.h:35
QSharedDataPointer & operator=(const QSharedDataPointer &o) noexcept
Sets the {d pointer} of this to the {d pointer} of o and increments the reference count of the shared...
Definition qshareddata.h:79
void reset(T *ptr=nullptr) noexcept
Definition qshareddata.h:68
Q_NODISCARD_CTOR QSharedDataPointer() noexcept
Constructs a QSharedDataPointer initialized with \nullptr as {d pointer}.
Definition qshareddata.h:55
Q_NODISCARD_CTOR QSharedDataPointer(QSharedDataPointer &&o) noexcept
Move-constructs a QSharedDataPointer instance, making it point at the same object that o was pointing...
Definition qshareddata.h:90
QSharedDataPointer & operator=(T *o) noexcept
Sets the {d pointer} og this to o and increments {o}'s reference count.
Definition qshareddata.h:84
T Type
This is the type of the shared data object.
Definition qshareddata.h:37
~QSharedDataPointer()
Decrements the reference count of the shared data object.
Definition qshareddata.h:56
T & operator*()
Provides access to the shared data object's members.
Definition qshareddata.h:41
const T * data() const noexcept
Returns a pointer to the shared data object.
Definition qshareddata.h:49
const T * operator->() const noexcept
Provides const access to the shared data object's members.
Definition qshareddata.h:44
void swap(QSharedDataPointer &other) noexcept
Swap this instance's shared data pointer with the shared data pointer in other.
Definition qshareddata.h:96
const T & operator*() const
Provides const access to the shared data object's members.
Definition qshareddata.h:42
bool operator!() const noexcept
Returns true if the {d pointer} of this is \nullptr.
Definition qshareddata.h:94
T * take() noexcept
Definition qshareddata.h:52
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
Definition qshareddata.h:40
T * operator->()
Provides access to the shared data object's members.
Definition qshareddata.h:43
const T * get() const noexcept
Definition qshareddata.h:50
const T * constData() const noexcept
Returns a const pointer to the shared data object.
Definition qshareddata.h:51
Q_NODISCARD_CTOR QSharedDataPointer(const QSharedDataPointer &o) noexcept
Sets the {d pointer} of this to the {d pointer} in o and increments the reference count of the shared...
Definition qshareddata.h:65
T * data()
Returns a pointer to the shared data object.
Definition qshareddata.h:47
Q_NODISCARD_CTOR QSharedDataPointer(T *data, QAdoptSharedDataTag) noexcept
Definition qshareddata.h:62
Q_NODISCARD_CTOR QSharedDataPointer(T *data) noexcept
Constructs a QSharedDataPointer with {d pointer} set to data and increments {data}'s reference count.
Definition qshareddata.h:59
\inmodule QtCore
Definition qshareddata.h:19
QSharedData() noexcept
Constructs a QSharedData object with a reference count of 0.
Definition qshareddata.h:23
~QSharedData()=default
QAtomicInt ref
Definition qshareddata.h:21
QSharedData & operator=(const QSharedData &)=delete
QSharedData(const QSharedData &) noexcept
Constructs a QSharedData object with reference count 0.
Definition qshareddata.h:24
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
#define Q_NODISCARD_CTOR
static ControlElement< T > * ptr(QWidget *widget)
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint ref
GLboolean reset
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
size_t qHash(const QSharedDataPointer< T > &ptr, size_t seed=0) noexcept
#define DECLARE_COMPARE_SET(T1, A1, T2, A2)
Definition qshareddata.h:99
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]
\inmodule QtCore \threadsafe
Definition qshareddata.h:31
constexpr QAdoptSharedDataTag()=default