1 | // Copyright (C) 2016 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 QQMLLIST_P_H |
5 | #define QQMLLIST_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 "qqmllist.h" |
19 | #include "qqmlmetaobject_p.h" |
20 | #include "qqmlmetatype_p.h" |
21 | #include <QtQml/private/qbipointer_p.h> |
22 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | class QQmlListReferencePrivate |
26 | { |
27 | public: |
28 | QQmlListReferencePrivate(); |
29 | |
30 | static QQmlListReference init(const QQmlListProperty<QObject> &, QMetaType); |
31 | |
32 | QPointer<QObject> object; |
33 | QQmlListProperty<QObject> property; |
34 | QMetaType propertyType; |
35 | |
36 | void addref(); |
37 | void release(); |
38 | int refCount; |
39 | |
40 | static inline QQmlListReferencePrivate *get(QQmlListReference *ref) { |
41 | return ref->d; |
42 | } |
43 | |
44 | const QMetaObject *elementType() |
45 | { |
46 | if (!m_elementType) { |
47 | m_elementType = QQmlMetaType::rawMetaObjectForType( |
48 | metaType: QQmlMetaType::listValueType(type: propertyType)).metaObject(); |
49 | } |
50 | |
51 | return m_elementType; |
52 | } |
53 | |
54 | private: |
55 | const QMetaObject *m_elementType = nullptr; |
56 | }; |
57 | |
58 | template<typename T> |
59 | class QQmlListIterator { |
60 | public: |
61 | using difference_type = qsizetype; |
62 | using iterator_category = std::random_access_iterator_tag; |
63 | using value_type = T*; |
64 | |
65 | class reference |
66 | { |
67 | public: |
68 | explicit reference(const QQmlListIterator *iter) : m_iter(iter) {} |
69 | reference(const reference &) = default; |
70 | reference(reference &&) = default; |
71 | ~reference() = default; |
72 | |
73 | operator T *() const |
74 | { |
75 | if (m_iter == nullptr) |
76 | return nullptr; |
77 | return m_iter->m_list->at(m_iter->m_list, m_iter->m_i); |
78 | } |
79 | |
80 | reference &operator=(T *value) { |
81 | m_iter->m_list->replace(m_iter->m_list, m_iter->m_i, value); |
82 | return *this; |
83 | } |
84 | |
85 | reference &operator=(const reference &value) { return operator=((T *)(value)); } |
86 | reference &operator=(reference &&value) { return operator=((T *)(value)); } |
87 | |
88 | friend void swap(reference a, reference b) |
89 | { |
90 | T *tmp = a; |
91 | a = b; |
92 | b = std::move(tmp); |
93 | } |
94 | private: |
95 | const QQmlListIterator *m_iter; |
96 | }; |
97 | |
98 | class pointer |
99 | { |
100 | public: |
101 | explicit pointer(const QQmlListIterator *iter) : m_iter(iter) {} |
102 | reference operator*() const { return reference(m_iter); } |
103 | QQmlListIterator operator->() const { return *m_iter; } |
104 | |
105 | private: |
106 | const QQmlListIterator *m_iter; |
107 | }; |
108 | |
109 | QQmlListIterator() = default; |
110 | QQmlListIterator(QQmlListProperty<T> *list, qsizetype i) : m_list(list), m_i(i) {} |
111 | |
112 | QQmlListIterator &operator++() |
113 | { |
114 | ++m_i; |
115 | return *this; |
116 | } |
117 | |
118 | QQmlListIterator operator++(int) |
119 | { |
120 | QQmlListIterator result = *this; |
121 | ++m_i; |
122 | return result; |
123 | } |
124 | |
125 | QQmlListIterator &operator--() |
126 | { |
127 | --m_i; |
128 | return *this; |
129 | } |
130 | |
131 | QQmlListIterator operator--(int) |
132 | { |
133 | QQmlListIterator result = *this; |
134 | --m_i; |
135 | return result; |
136 | } |
137 | |
138 | QQmlListIterator &operator+=(qsizetype j) |
139 | { |
140 | m_i += j; |
141 | return *this; |
142 | } |
143 | |
144 | QQmlListIterator &operator-=(qsizetype j) |
145 | { |
146 | m_i -= j; |
147 | return *this; |
148 | } |
149 | |
150 | QQmlListIterator operator+(qsizetype j) |
151 | { |
152 | return QQmlListIterator(m_list, m_i + j); |
153 | } |
154 | |
155 | QQmlListIterator operator-(qsizetype j) |
156 | { |
157 | return QQmlListIterator(m_list, m_i - j); |
158 | } |
159 | |
160 | reference operator*() const |
161 | { |
162 | return reference(this); |
163 | } |
164 | |
165 | pointer operator->() const |
166 | { |
167 | return pointer(this); |
168 | } |
169 | |
170 | private: |
171 | friend inline bool operator==(const QQmlListIterator &a, const QQmlListIterator &b) |
172 | { |
173 | return a.m_list == b.m_list && a.m_i == b.m_i; |
174 | } |
175 | |
176 | friend inline bool operator!=(const QQmlListIterator &a, const QQmlListIterator &b) |
177 | { |
178 | return a.m_list != b.m_list || a.m_i != b.m_i; |
179 | } |
180 | |
181 | friend inline bool operator<(const QQmlListIterator &i, const QQmlListIterator &j) |
182 | { |
183 | return i - j < 0; |
184 | } |
185 | |
186 | friend inline bool operator>=(const QQmlListIterator &i, const QQmlListIterator &j) |
187 | { |
188 | return !(i < j); |
189 | } |
190 | |
191 | friend inline bool operator>(const QQmlListIterator &i, const QQmlListIterator &j) |
192 | { |
193 | return i - j > 0; |
194 | } |
195 | |
196 | friend inline bool operator<=(const QQmlListIterator &i, const QQmlListIterator &j) |
197 | { |
198 | return !(i > j); |
199 | } |
200 | |
201 | friend inline QQmlListIterator operator+(qsizetype i, const QQmlListIterator &j) |
202 | { |
203 | return j + i; |
204 | } |
205 | |
206 | friend inline qsizetype operator-(const QQmlListIterator &i, const QQmlListIterator &j) |
207 | { |
208 | return i.m_i - j.m_i; |
209 | } |
210 | |
211 | QQmlListProperty<T> *m_list = nullptr; |
212 | qsizetype m_i = 0; |
213 | }; |
214 | |
215 | template<typename T> |
216 | QQmlListIterator<T> begin(QQmlListProperty<T> &list) |
217 | { |
218 | return QQmlListIterator<T>(&list, 0); |
219 | } |
220 | |
221 | template<typename T> |
222 | QQmlListIterator<T> end(QQmlListProperty<T> &list) |
223 | { |
224 | return QQmlListIterator<T>(&list, list.count(&list)); |
225 | } |
226 | |
227 | QT_END_NAMESPACE |
228 | |
229 | #endif // QQMLLIST_P_H |
230 | |