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
qqmlpropertycachevector_p.h
Go to the documentation of this file.
1// Copyright (C) 2019 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 QQMLPROPERTYCACHEVECTOR_P_H
5#define QQMLPROPERTYCACHEVECTOR_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 <private/qqmlpropertycache_p.h>
19#include <private/qbipointer_p.h>
20
21#include <QtCore/qtaggedpointer.h>
22
23QT_BEGIN_NAMESPACE
24
25class QQmlPropertyCacheVector
26{
27public:
28 QQmlPropertyCacheVector() = default;
29 QQmlPropertyCacheVector(QQmlPropertyCacheVector &&) = default;
30 QQmlPropertyCacheVector &operator=(QQmlPropertyCacheVector &&) = default;
31
32 ~QQmlPropertyCacheVector() { clear(); }
33 void resize(int size)
34 {
35 Q_ASSERT(size >= data.size());
36 return data.resize(size);
37 }
38
39 int count() const {
40 // the property cache vector will never contain more thant INT_MAX many elements
41 return int(data.size());
42 }
43
44 bool isEmpty() const { return data.isEmpty(); }
45
46 void clear()
47 {
48 for (int i = 0; i < data.size(); ++i)
49 releaseElement(i);
50 data.clear();
51 }
52
53 void resetAndResize(int size)
54 {
55 for (int i = 0; i < data.size(); ++i) {
56 releaseElement(i);
57 data[i] = BiPointer();
58 }
59 data.resize(size);
60 }
61
62 void append(const QQmlPropertyCache::ConstPtr &cache) {
63 cache->addref();
64 data.append(BiPointer(cache.data()));
65 Q_ASSERT(data.last().isT1());
66 Q_ASSERT(data.size() <= std::numeric_limits<int>::max());
67 }
68
69 void appendOwn(const QQmlPropertyCache::Ptr &cache) {
70 cache->addref();
71 data.append(BiPointer(cache.data()));
72 Q_ASSERT(data.last().isT2());
73 Q_ASSERT(data.size() <= std::numeric_limits<int>::max());
74 }
75
76 QQmlPropertyCache::ConstPtr at(int index) const
77 {
78 const auto entry = data.at(index);
79 if (entry.isT2())
80 return entry.asT2();
81 return entry.asT1();
82 }
83
84 QQmlPropertyCache::Ptr ownAt(int index) const
85 {
86 const auto entry = data.at(index);
87 if (entry.isT2())
88 return entry.asT2();
89 return QQmlPropertyCache::Ptr();
90 }
91
92 void set(int index, const QQmlPropertyCache::ConstPtr &replacement) {
93 if (QQmlPropertyCache::ConstPtr oldCache = at(index)) {
94 // If it is our own, we keep it our own
95 if (replacement.data() == oldCache.data())
96 return;
97 oldCache->release();
98 }
99 data[index] = replacement.data();
100 if (replacement)
101 replacement->addref();
102 Q_ASSERT(data[index].isT1());
103 }
104
105 void setOwn(int index, const QQmlPropertyCache::Ptr &replacement) {
106 if (QQmlPropertyCache::ConstPtr oldCache = at(index)) {
107 if (replacement.data() != oldCache.data()) {
108 oldCache->release();
109 replacement->addref();
110 }
111 } else {
112 replacement->addref();
113 }
114 data[index] = replacement.data();
115 Q_ASSERT(data[index].isT2());
116 }
117
118 void setNeedsVMEMetaObject(int index) { data[index].setFlag(); }
119 bool needsVMEMetaObject(int index) const { return data.at(index).flag(); }
120
121 void seal()
122 {
123 for (auto &entry: data) {
124 if (entry.isT2())
125 entry = static_cast<const QQmlPropertyCache *>(entry.asT2());
126 Q_ASSERT(entry.isT1());
127 }
128 }
129
130private:
131 void releaseElement(int i)
132 {
133 const auto &cache = data.at(i);
134 if (cache.isT2()) {
135 if (QQmlPropertyCache *data = cache.asT2())
136 data->release();
137 } else if (const QQmlPropertyCache *data = cache.asT1()) {
138 data->release();
139 }
140 }
141
142 Q_DISABLE_COPY(QQmlPropertyCacheVector)
143 using BiPointer = QBiPointer<const QQmlPropertyCache, QQmlPropertyCache>;
144 QList<BiPointer> data;
145};
146
147QT_END_NAMESPACE
148
149#endif // QQMLPROPERTYCACHEVECTOR_P_H