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 replacement->addref();
101 Q_ASSERT(data[index].isT1());
102 }
103
104 void setOwn(int index, const QQmlPropertyCache::Ptr &replacement) {
105 if (QQmlPropertyCache::ConstPtr oldCache = at(index)) {
106 if (replacement.data() != oldCache.data()) {
107 oldCache->release();
108 replacement->addref();
109 }
110 } else {
111 replacement->addref();
112 }
113 data[index] = replacement.data();
114 Q_ASSERT(data[index].isT2());
115 }
116
117 void setNeedsVMEMetaObject(int index) { data[index].setFlag(); }
118 bool needsVMEMetaObject(int index) const { return data.at(index).flag(); }
119
120 void seal()
121 {
122 for (auto &entry: data) {
123 if (entry.isT2())
124 entry = static_cast<const QQmlPropertyCache *>(entry.asT2());
125 Q_ASSERT(entry.isT1());
126 }
127 }
128
129private:
130 void releaseElement(int i)
131 {
132 const auto &cache = data.at(i);
133 if (cache.isT2()) {
134 if (QQmlPropertyCache *data = cache.asT2())
135 data->release();
136 } else if (const QQmlPropertyCache *data = cache.asT1()) {
137 data->release();
138 }
139 }
140
141 Q_DISABLE_COPY(QQmlPropertyCacheVector)
142 using BiPointer = QBiPointer<const QQmlPropertyCache, QQmlPropertyCache>;
143 QVector<BiPointer> data;
144};
145
146QT_END_NAMESPACE
147
148#endif // QQMLPROPERTYCACHEVECTOR_P_H