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/qcompare.h>
13#include <QtCore/qglobal.h>
14#include <QtCore/qshareddata.h>
15
16QT_BEGIN_NAMESPACE
17
18namespace QtPrivate {
19
20template <typename T>
21class QExplicitlySharedDataPointerV2
22{
23 Qt::totally_ordered_wrapper<T *> d;
24
25public:
26 constexpr QExplicitlySharedDataPointerV2() noexcept : d(nullptr) {}
27
28 explicit QExplicitlySharedDataPointerV2(T *t) noexcept
29 : d(t)
30 {
31 if (d)
32 d->ref.ref();
33 }
34
35 QExplicitlySharedDataPointerV2(T *t, QAdoptSharedDataTag) noexcept
36 : d(t)
37 {
38 }
39
40 QExplicitlySharedDataPointerV2(const QExplicitlySharedDataPointerV2 &other) noexcept
41 : d(other.d)
42 {
43 if (d)
44 d->ref.ref();
45 }
46
47 QExplicitlySharedDataPointerV2 &operator=(const QExplicitlySharedDataPointerV2 &other) noexcept
48 {
49 QExplicitlySharedDataPointerV2 copy(other);
50 swap(other&: copy);
51 return *this;
52 }
53
54 QExplicitlySharedDataPointerV2(QExplicitlySharedDataPointerV2 &&other) noexcept
55 : d(std::exchange(other.d, nullptr))
56 {
57 }
58
59 QExplicitlySharedDataPointerV2 &operator=(QExplicitlySharedDataPointerV2 &&other) noexcept
60 {
61 QExplicitlySharedDataPointerV2 moved(std::move(other));
62 swap(other&: moved);
63 return *this;
64 }
65
66 ~QExplicitlySharedDataPointerV2()
67 {
68 if (d && !d->ref.deref())
69 delete d.get();
70 }
71
72 void detach()
73 {
74 if (!d) {
75 // should this codepath be here on in all user's detach()?
76 d.reset(new T);
77 d->ref.ref();
78 } else if (d->ref.loadRelaxed() != 1) {
79 // TODO: qAtomicDetach here...?
80 QExplicitlySharedDataPointerV2 copy(new T(*d));
81 swap(other&: copy);
82 }
83 }
84
85 void reset(T *t = nullptr) noexcept
86 {
87 if (d && !d->ref.deref())
88 delete d.get();
89 d.reset(t);
90 if (d)
91 d->ref.ref();
92 }
93
94 constexpr T *take() noexcept
95 {
96 return std::exchange(d, nullptr).get();
97 }
98
99 bool isShared() const noexcept
100 {
101 return d && d->ref.loadRelaxed() != 1;
102 }
103
104 constexpr void swap(QExplicitlySharedDataPointerV2 &other) noexcept
105 {
106 qt_ptr_swap(d, other.d);
107 }
108
109 // important change from QExplicitlySharedDataPointer: deep const
110 constexpr T &operator*() { return *(d.get()); }
111 constexpr T *operator->() { return d.get(); }
112 constexpr const T &operator*() const { return *(d.get()); }
113 constexpr const T *operator->() const { return d.get(); }
114
115 constexpr T *data() noexcept { return d.get(); }
116 constexpr const T *data() const noexcept { return d.get(); }
117
118 constexpr explicit operator bool() const noexcept { return d.get(); }
119
120private:
121 constexpr friend bool comparesEqual(const QExplicitlySharedDataPointerV2 &lhs,
122 const QExplicitlySharedDataPointerV2 &rhs) noexcept
123 { return lhs.d == rhs.d; }
124 constexpr friend Qt::strong_ordering
125 compareThreeWay(const QExplicitlySharedDataPointerV2 &lhs,
126 const QExplicitlySharedDataPointerV2 &rhs) noexcept
127 { return Qt::compareThreeWay(lhs.d, rhs.d); }
128 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QExplicitlySharedDataPointerV2)
129
130 constexpr friend bool
131 comparesEqual(const QExplicitlySharedDataPointerV2 &lhs, std::nullptr_t) noexcept
132 { return lhs.d == nullptr; }
133 constexpr friend Qt::strong_ordering
134 compareThreeWay(const QExplicitlySharedDataPointerV2 &lhs, std::nullptr_t) noexcept
135 { return Qt::compareThreeWay(lhs.d, nullptr); }
136 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QExplicitlySharedDataPointerV2, std::nullptr_t)
137};
138
139template <typename T>
140constexpr void swap(QExplicitlySharedDataPointerV2<T> &lhs, QExplicitlySharedDataPointerV2<T> &rhs) noexcept
141{
142 lhs.swap(rhs);
143}
144
145} // namespace QtPrivate
146
147QT_END_NAMESPACE
148
149#endif // QSHAREDDATA_IMPL_H
150

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