1// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#if 0
5#pragma qt_sync_skip_header_check
6#pragma qt_sync_stop_processing
7#endif
8
9#ifndef QSHAREDDATA_IMPL_H
10#define QSHAREDDATA_IMPL_H
11
12#include <QtCore/qglobal.h>
13#include <QtCore/qshareddata.h>
14
15QT_BEGIN_NAMESPACE
16
17namespace QtPrivate {
18
19template <typename T>
20class QExplicitlySharedDataPointerV2
21{
22 T *d;
23
24public:
25 constexpr QExplicitlySharedDataPointerV2() noexcept : d(nullptr) {}
26
27 explicit QExplicitlySharedDataPointerV2(T *t) noexcept
28 : d(t)
29 {
30 if (d)
31 d->ref.ref();
32 }
33
34 QExplicitlySharedDataPointerV2(T *t, QAdoptSharedDataTag) noexcept
35 : d(t)
36 {
37 }
38
39 QExplicitlySharedDataPointerV2(const QExplicitlySharedDataPointerV2 &other) noexcept
40 : d(other.d)
41 {
42 if (d)
43 d->ref.ref();
44 }
45
46 QExplicitlySharedDataPointerV2 &operator=(const QExplicitlySharedDataPointerV2 &other) noexcept
47 {
48 QExplicitlySharedDataPointerV2 copy(other);
49 swap(other&: copy);
50 return *this;
51 }
52
53 QExplicitlySharedDataPointerV2(QExplicitlySharedDataPointerV2 &&other) noexcept
54 : d(std::exchange(other.d, nullptr))
55 {
56 }
57
58 QExplicitlySharedDataPointerV2 &operator=(QExplicitlySharedDataPointerV2 &&other) noexcept
59 {
60 QExplicitlySharedDataPointerV2 moved(std::move(other));
61 swap(other&: moved);
62 return *this;
63 }
64
65 ~QExplicitlySharedDataPointerV2()
66 {
67 if (d && !d->ref.deref())
68 delete d;
69 }
70
71 void detach()
72 {
73 if (!d) {
74 // should this codepath be here on in all user's detach()?
75 d = new T;
76 d->ref.ref();
77 } else if (d->ref.loadRelaxed() != 1) {
78 // TODO: qAtomicDetach here...?
79 QExplicitlySharedDataPointerV2 copy(new T(*d));
80 swap(other&: copy);
81 }
82 }
83
84 void reset(T *t = nullptr) noexcept
85 {
86 if (d && !d->ref.deref())
87 delete d;
88 d = t;
89 if (d)
90 d->ref.ref();
91 }
92
93 constexpr T *take() noexcept
94 {
95 return std::exchange(d, nullptr);
96 }
97
98 bool isShared() const noexcept
99 {
100 return d && d->ref.loadRelaxed() != 1;
101 }
102
103 constexpr void swap(QExplicitlySharedDataPointerV2 &other) noexcept
104 {
105 qt_ptr_swap(d, other.d);
106 }
107
108 // important change from QExplicitlySharedDataPointer: deep const
109 constexpr T &operator*() { return *d; }
110 constexpr T *operator->() { return d; }
111 constexpr const T &operator*() const { return *d; }
112 constexpr const T *operator->() const { return d; }
113
114 constexpr T *data() noexcept { return d; }
115 constexpr const T *data() const noexcept { return d; }
116
117 constexpr explicit operator bool() const noexcept { return d; }
118
119 constexpr friend bool operator==(const QExplicitlySharedDataPointerV2 &lhs,
120 const QExplicitlySharedDataPointerV2 &rhs) noexcept
121 {
122 return lhs.d == rhs.d;
123 }
124
125 constexpr friend bool operator!=(const QExplicitlySharedDataPointerV2 &lhs,
126 const QExplicitlySharedDataPointerV2 &rhs) noexcept
127 {
128 return lhs.d != rhs.d;
129 }
130};
131
132template <typename T>
133constexpr void swap(QExplicitlySharedDataPointerV2<T> &lhs, QExplicitlySharedDataPointerV2<T> &rhs) noexcept
134{
135 lhs.swap(rhs);
136}
137
138} // namespace QtPrivate
139
140QT_END_NAMESPACE
141
142#endif // QSHAREDDATA_IMPL_H
143

source code of qtbase/src/corelib/tools/qshareddata_impl.h