Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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/qcompare.h>
10#include <QtCore/qhashfunctions.h>
11
12#include <functional>
13
14QT_BEGIN_NAMESPACE
15
16
17template <class T> class QSharedDataPointer;
18
20{
21public:
22 mutable QAtomicInt ref;
23
24 QSharedData() noexcept : ref(0) { }
25 QSharedData(const QSharedData &) noexcept : ref(0) { }
26
27 // using the assignment operator would lead to corruption in the ref-counting
28 QSharedData &operator=(const QSharedData &) = delete;
29 ~QSharedData() = default;
30};
31
32struct QAdoptSharedDataTag { explicit constexpr QAdoptSharedDataTag() = default; };
33
34template <typename T>
36{
37public:
38 typedef T Type;
39 typedef T *pointer;
40
41 void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
42 T &operator*() { detach(); return *(d.get()); }
43 const T &operator*() const { return *(d.get()); }
44 T *operator->() { detach(); return d.get(); }
45 const T *operator->() const noexcept { return d.get(); }
46 operator T *() { detach(); return d.get(); }
47 operator const T *() const noexcept { return d.get(); }
48 T *data() { detach(); return d.get(); }
49 T *get() { detach(); return d.get(); }
50 const T *data() const noexcept { return d.get(); }
51 const T *get() const noexcept { return d.get(); }
52 const T *constData() const noexcept { return d.get(); }
53 T *take() noexcept { return std::exchange(d, nullptr).get(); }
54
56 QSharedDataPointer() noexcept : d(nullptr) { }
57 ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d.get(); }
58
60 explicit QSharedDataPointer(T *data) noexcept : d(data)
61 { if (d) d->ref.ref(); }
67 { if (d) d->ref.ref(); }
68
69 void reset(T *ptr = nullptr) noexcept
70 {
71 if (ptr != d.get()) {
72 if (ptr)
73 ptr->ref.ref();
74 T *old = std::exchange(d, Qt::totally_ordered_wrapper(ptr)).get();
75 if (old && !old->ref.deref())
76 delete old;
77 }
78 }
79
81 {
82 reset(o.d.get());
83 return *this;
84 }
85 inline QSharedDataPointer &operator=(T *o) noexcept
86 {
87 reset(o);
88 return *this;
89 }
91 QSharedDataPointer(QSharedDataPointer &&o) noexcept : d(std::exchange(o.d, nullptr)) {}
93
94 operator bool () const noexcept { return d != nullptr; }
95 bool operator!() const noexcept { return d == nullptr; }
96
98 { qt_ptr_swap(d, other.d); }
99
100protected:
102
103private:
104 friend bool comparesEqual(const QSharedDataPointer &lhs, const QSharedDataPointer &rhs) noexcept
105 { return lhs.d == rhs.d; }
106 friend Qt::strong_ordering
108 { return Qt::compareThreeWay(lhs.d, rhs.d); }
110
111 friend bool comparesEqual(const QSharedDataPointer &lhs, const T *rhs) noexcept
112 { return lhs.d == rhs; }
113 friend Qt::strong_ordering
114 compareThreeWay(const QSharedDataPointer &lhs, const T *rhs) noexcept
115 { return Qt::compareThreeWay(lhs.d, rhs); }
117
118 friend bool comparesEqual(const QSharedDataPointer &lhs, std::nullptr_t) noexcept
119 { return lhs.d == nullptr; }
120 friend Qt::strong_ordering
122 { return Qt::compareThreeWay(lhs.d, nullptr); }
124
125 void detach_helper();
126
127 Qt::totally_ordered_wrapper<T *> d;
128};
129
130template <typename T>
132{
133public:
134 typedef T Type;
135 typedef T *pointer;
136
137 T &operator*() const { return *(d.get()); }
138 T *operator->() noexcept { return d.get(); }
139 T *operator->() const noexcept { return d.get(); }
140 explicit operator T *() { return d.get(); }
141 explicit operator const T *() const noexcept { return d.get(); }
142 T *data() const noexcept { return d.get(); }
143 T *get() const noexcept { return d.get(); }
144 const T *constData() const noexcept { return d.get(); }
145 T *take() noexcept { return std::exchange(d, nullptr).get(); }
146
147 void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
148
150 QExplicitlySharedDataPointer() noexcept : d(nullptr) { }
151 ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d.get(); }
152
154 explicit QExplicitlySharedDataPointer(T *data) noexcept : d(data)
155 { if (d) d->ref.ref(); }
161 { if (d) d->ref.ref(); }
162
163 template<typename X>
166#ifdef QT_ENABLE_QEXPLICITLYSHAREDDATAPOINTER_STATICCAST
167#error This macro has been removed in Qt 6.9.
168#endif
169 : d(o.data())
170 { if (d) d->ref.ref(); }
171
172 void reset(T *ptr = nullptr) noexcept
173 {
174 if (ptr != d) {
175 if (ptr)
176 ptr->ref.ref();
177 T *old = std::exchange(d, Qt::totally_ordered_wrapper(ptr)).get();
178 if (old && !old->ref.deref())
179 delete old;
180 }
181 }
182
184 {
185 reset(o.d.get());
186 return *this;
187 }
189 {
190 reset(o);
191 return *this;
192 }
196
197 operator bool () const noexcept { return d != nullptr; }
198 bool operator!() const noexcept { return d == nullptr; }
199
202
203protected:
205
206private:
208 const QExplicitlySharedDataPointer &rhs) noexcept
209 { return lhs.d == rhs.d; }
210 friend Qt::strong_ordering
212 const QExplicitlySharedDataPointer &rhs) noexcept
213 { return Qt::compareThreeWay(lhs.d, rhs.d); }
215
216 friend bool comparesEqual(const QExplicitlySharedDataPointer &lhs, const T *rhs) noexcept
217 { return lhs.d == rhs; }
218 friend Qt::strong_ordering
220 { return Qt::compareThreeWay(lhs.d, rhs); }
222
224 { return lhs.d == nullptr; }
225 friend Qt::strong_ordering
227 { return Qt::compareThreeWay(lhs.d, nullptr); }
229
230 void detach_helper();
231
232 Qt::totally_ordered_wrapper<T *> d;
233};
234
235// Declared here and as Q_OUTOFLINE_TEMPLATE to work-around MSVC bug causing missing symbols at link time.
236template <typename T>
237Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
238{
239 return new T(*d);
240}
241
242template <typename T>
243Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
244{
245 T *x = clone();
246 x->ref.ref();
247 if (!d.get()->ref.deref())
248 delete d.get();
249 d.reset(x);
250}
251
252template <typename T>
253Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
254{
255 return new T(*d.get());
256}
257
258template <typename T>
259Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
260{
261 T *x = clone();
262 x->ref.ref();
263 if (!d->ref.deref())
264 delete d.get();
265 d.reset(x);
266}
267
268template <typename T>
269void swap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2) noexcept
270{ p1.swap(p2); }
271
272template <typename T>
274{ p1.swap(p2); }
275
276template <typename T>
277size_t qHash(const QSharedDataPointer<T> &ptr, size_t seed = 0) noexcept
278{
279 return qHash(ptr.data(), seed);
280}
281template <typename T>
282size_t qHash(const QExplicitlySharedDataPointer<T> &ptr, size_t seed = 0) noexcept
283{
284 return qHash(ptr.data(), seed);
285}
286
289
290#define QT_DECLARE_QSDP_SPECIALIZATION_DTOR(Class)
291 template<> QSharedDataPointer<Class>::~QSharedDataPointer();
292
293#define QT_DECLARE_QSDP_SPECIALIZATION_DTOR_WITH_EXPORT(Class, ExportMacro)
294 template<> ExportMacro QSharedDataPointer<Class>::~QSharedDataPointer();
295
296#define QT_DEFINE_QSDP_SPECIALIZATION_DTOR(Class)
297 template<> QSharedDataPointer<Class>::~QSharedDataPointer()
298 {
299 if (d && !d->ref.deref())
300 delete d.get();
301 }
302
303#define QT_DECLARE_QESDP_SPECIALIZATION_DTOR(Class)
304 template<> QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer();
305
306#define QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(Class, ExportMacro)
307 template<> ExportMacro QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer();
308
309#define QT_DEFINE_QESDP_SPECIALIZATION_DTOR(Class)
310 template<> QExplicitlySharedDataPointer<Class>::~QExplicitlySharedDataPointer()
311 {
312 if (d && !d->ref.deref())
313 delete d.get();
314 }
315
316QT_END_NAMESPACE
317
318#endif // QSHAREDDATA_H
\inmodule QtCore
Definition qatomic.h:112
constexpr QAtomicInt(int value=0) noexcept
Constructs a QAtomicInt with the given value.
Definition qatomic.h:117
\macro Q_ATOMIC_INTnn_IS_SUPPORTED
Definition qatomic.h:123
QAtomicPointer(const QAtomicPointer< T > &other) noexcept
Constructs a copy of other.
Definition qatomic.h:127
QAtomicPointer< T > & operator=(const QAtomicPointer< T > &other) noexcept
Assigns other to this QAtomicPointer and returns a reference to this QAtomicPointer.
Definition qatomic.h:133
constexpr QAtomicPointer(T *value=nullptr) noexcept
Constructs a QAtomicPointer with the given value.
Definition qatomic.h:125
const T * constData() const noexcept
Returns a const pointer to the shared data object.
T * get() const noexcept
~QExplicitlySharedDataPointer()
Decrements the reference count of the shared data object.
T Type
This is the type of the shared data object.
void reset(T *ptr=nullptr) noexcept
operator const T *() const noexcept
T * operator->() noexcept
Provides access to the shared data object's members.
T * operator->() const noexcept
Provides const access to the shared data object's members.
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.
friend Qt::strong_ordering compareThreeWay(const QExplicitlySharedDataPointer &lhs, const QExplicitlySharedDataPointer &rhs) noexcept
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
T & operator*() const
Provides access to the shared data object's members.
friend bool comparesEqual(const QExplicitlySharedDataPointer &lhs, const QExplicitlySharedDataPointer &rhs) noexcept
QExplicitlySharedDataPointer & operator=(T *o) noexcept
Sets the {d pointer} of this to o and increments {o}'s reference count.
QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr< QAbstractFileEngine > engine)
Definition qfileinfo_p.h:97
bool const isDefaultConstructed
QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data)
Definition qfileinfo_p.h:82
Ret checkAttribute(QFileSystemMetaData::MetaDataFlags fsFlags, FSLambda fsLambda, EngineLambda engineLambda) const
QFileSystemMetaData metaData
QDateTime & getFileTime(QFile::FileTime) const
std::unique_ptr< QAbstractFileEngine > const fileEngine
QDateTime fileTimes[4]
uint getFileFlags(QAbstractFileEngine::FileFlags) const
Definition qfileinfo.cpp:99
void clearFlags() const
void setCachedFlag(uint c) const
QString getFileOwner(QAbstractFileEngine::FileOwner own) const
Definition qfileinfo.cpp:75
QString fileOwners[2]
bool getCachedFlag(uint c) const
QFileInfoPrivate(const QFileInfoPrivate &copy)
Definition qfileinfo_p.h:56
QFileSystemEntry fileEntry
static QFileInfoPrivate * get(QFileInfo *fi)
Definition qfileinfo_p.h:48
QString getFileName(QAbstractFileEngine::FileName) const
Definition qfileinfo.cpp:17
QString fileNames[QAbstractFileEngine::NFileNames]
QFileInfoPrivate(const QString &file)
Definition qfileinfo_p.h:69
Ret checkAttribute(Ret defaultValue, QFileSystemMetaData::MetaDataFlags fsFlags, FSLambda fsLambda, EngineLambda engineLambda) const
T * take() noexcept
Definition qshareddata.h:53
T & operator*()
Provides access to the shared data object's members.
Definition qshareddata.h:42
const T * get() const noexcept
Definition qshareddata.h:51
T * data()
Returns a pointer to the shared data object.
Definition qshareddata.h:48
Q_NODISCARD_CTOR QSharedDataPointer() noexcept
Constructs a QSharedDataPointer initialized with \nullptr as {d pointer}.
Definition qshareddata.h:56
~QSharedDataPointer()
Decrements the reference count of the shared data object.
Definition qshareddata.h:57
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:80
T Type
This is the type of the shared data object.
Definition qshareddata.h:38
void reset(T *ptr=nullptr) noexcept
Definition qshareddata.h:69
operator const T *() const noexcept
Returns a pointer to the shared data object.
Definition qshareddata.h:47
friend Qt::strong_ordering compareThreeWay(const QSharedDataPointer &lhs, const QSharedDataPointer &rhs) noexcept
friend bool comparesEqual(const QSharedDataPointer &lhs, const QSharedDataPointer &rhs) noexcept
const T * data() const noexcept
Returns a pointer to the shared data object.
Definition qshareddata.h:50
operator T*()
Returns a pointer to the shared data object.
Definition qshareddata.h:46
const T * operator->() const noexcept
Provides const access to the shared data object's members.
Definition qshareddata.h:45
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:41
const T & operator*() const
Provides const access to the shared data object's members.
Definition qshareddata.h:43
const T * constData() const noexcept
Returns a const pointer to the shared data object.
Definition qshareddata.h:52
QSharedDataPointer & operator=(T *o) noexcept
Sets the {d pointer} og this to o and increments {o}'s reference count.
Definition qshareddata.h:85
T * operator->()
Provides access to the shared data object's members.
Definition qshareddata.h:44
\inmodule QtCore
Definition qshareddata.h:20
QSharedData() noexcept
Constructs a QSharedData object with a reference count of 0.
Definition qshareddata.h:24
~QSharedData()=default
QAtomicInt ref
Definition qshareddata.h:22
QSharedData & operator=(const QSharedData &)=delete
QSharedData(const QSharedData &) noexcept
Constructs a QSharedData object with reference count 0.
Definition qshareddata.h:25
Combined button and popup list for selecting options.
void qAtomicDetach(T *&d)
This is a helper for the detach method of implicitly shared classes.
Definition qatomic.h:199
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
Q_DECLARE_TYPEINFO_BODY(QExplicitlySharedDataPointer< T >, Q_RELOCATABLE_TYPE)
void swap(QExplicitlySharedDataPointer< T > &p1, QExplicitlySharedDataPointer< T > &p2) noexcept
void swap(QSharedDataPointer< T > &p1, QSharedDataPointer< T > &p2) noexcept
Q_DECLARE_TYPEINFO_BODY(QSharedDataPointer< T >, Q_RELOCATABLE_TYPE)
size_t qHash(const QSharedDataPointer< T > &ptr, size_t seed=0) noexcept
size_t qHash(const QExplicitlySharedDataPointer< T > &ptr, size_t seed=0) noexcept
\inmodule QtCore \threadsafe
Definition qshareddata.h:32