Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qjslist.h
Go to the documentation of this file.
1// Copyright (C) 2023 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 QJSLIST_H
5#define QJSLIST_H
6
7#include <QtQml/qtqmlglobal.h>
8#include <QtQml/qqmllist.h>
9#include <QtQml/qjsengine.h>
10#include <QtCore/qobject.h>
11#include <QtCore/qstring.h>
12
13#include <algorithm>
14
15//
16// W A R N I N G
17// -------------
18//
19// This file is not part of the Qt API. It exists purely as an
20// implementation detail. This header file may change from version to
21// version. It will be kept compatible with the intended usage by
22// code generated using qmlcachegen.
23//
24// We mean it.
25//
26
28
30{
32 {
33 Q_ASSERT(min >= 0);
34 Q_ASSERT(min <= max);
35 return std::clamp(start < 0 ? max + qsizetype(start) : qsizetype(start), min, max);
36 }
37};
38
39template<typename List, typename Value = typename List::value_type>
40struct QJSList : private QJSListIndexClamp
41{
42 Q_DISABLE_COPY_MOVE(QJSList)
43
44 QJSList(List *list, QJSEngine *engine) : m_list(list), m_engine(engine) {}
45
46 Value at(qsizetype index) const
47 {
48 Q_ASSERT(index >= 0 && index < size());
49 return *(m_list->cbegin() + index);
50 }
51
52 qsizetype size() const { return m_list->size(); }
53
55 {
56 m_list->resize(size);
57 }
58
59 bool includes(const Value &value) const
60 {
61 return std::find(m_list->cbegin(), m_list->cend(), value) != m_list->cend();
62 }
63
64 bool includes(const Value &value, qsizetype start) const
65 {
66 return std::find(m_list->cbegin() + clamp(start, m_list->size()), m_list->cend(), value)
67 != m_list->cend();
68 }
69
70 QString join(const QString &separator = QStringLiteral(",")) const
71 {
73 bool atBegin = true;
74 std::for_each(m_list->cbegin(), m_list->cend(), [&](const Value &value) {
75 if (atBegin)
76 atBegin = false;
77 else
78 result += separator;
79 result += m_engine->coerceValue<Value, QString>(value);
80 });
81 return result;
82 }
83
84 List slice() const
85 {
86 return *m_list;
87 }
88 List slice(qsizetype start) const
89 {
90 List result;
91 std::copy(m_list->cbegin() + clamp(start, m_list->size()), m_list->cend(),
92 std::back_inserter(result));
93 return result;
94 }
96 {
97 const qsizetype size = m_list->size();
98 const qsizetype clampedStart = clamp(start, size);
99 const qsizetype clampedEnd = clamp(end, size, clampedStart);
100
101 List result;
102 std::copy(m_list->cbegin() + clampedStart, m_list->cbegin() + clampedEnd,
103 std::back_inserter(result));
104 return result;
105 }
106
107 qsizetype indexOf(const Value &value) const
108 {
109 const auto begin = m_list->cbegin();
110 const auto end = m_list->cend();
111 const auto it = std::find(begin, end, value);
112 if (it == end)
113 return -1;
114 const qsizetype result = it - begin;
115 Q_ASSERT(result >= 0);
116 return result;
117 }
118 qsizetype indexOf(const Value &value, qsizetype start) const
119 {
120 const auto begin = m_list->cbegin();
121 const auto end = m_list->cend();
122 const auto it = std::find(begin + clamp(start, m_list->size()), end, value);
123 if (it == end)
124 return -1;
125 const qsizetype result = it - begin;
126 Q_ASSERT(result >= 0);
127 return result;
128 }
129
130 qsizetype lastIndexOf(const Value &value) const
131 {
132 const auto begin = std::make_reverse_iterator(m_list->cend());
133 const auto end = std::make_reverse_iterator(m_list->cbegin());
134 const auto it = std::find(begin, end, value);
135 return (end - it) - 1;
136 }
138 {
139 const qsizetype size = m_list->size();
140 if (size == 0)
141 return -1;
142
143 // Construct a one-past-end iterator as input.
144 const qsizetype clampedStart = std::min(clamp(start, size), size - 1);
145 const auto begin = std::make_reverse_iterator(m_list->cbegin() + clampedStart + 1);
146
147 const auto end = std::make_reverse_iterator(m_list->cbegin());
148 const auto it = std::find(begin, end, value);
149 return (end - it) - 1;
150 }
151
152 QString toString() const { return join(); }
153
154private:
155 List *m_list = nullptr;
156 QJSEngine *m_engine = nullptr;
157};
158
159template<>
161{
162 Q_DISABLE_COPY_MOVE(QJSList)
163
165
167 {
168 Q_ASSERT(index >= 0 && index < size());
169 return m_list->at(m_list, index);
170 }
171
173 {
174 return m_list->count(m_list);
175 }
176
178 {
179 qsizetype current = m_list->count(m_list);
180 if (current < size && m_list->append) {
181 do {
182 m_list->append(m_list, nullptr);
183 } while (++current < size);
184 } else if (current > size && m_list->removeLast) {
185 do {
186 m_list->removeLast(m_list);
187 } while (--current > size);
188 }
189 }
190
191 bool includes(const QObject *value) const
192 {
193 if (!m_list->count || !m_list->at)
194 return false;
195
196 const qsizetype size = m_list->count(m_list);
197 for (qsizetype i = 0; i < size; ++i) {
198 if (m_list->at(m_list, i) == value)
199 return true;
200 }
201
202 return false;
203 }
205 {
206 if (!m_list->count || !m_list->at)
207 return false;
208
209 const qsizetype size = m_list->count(m_list);
210 for (qsizetype i = clamp(start, size); i < size; ++i) {
211 if (m_list->at(m_list, i) == value)
212 return true;
213 }
214
215 return false;
216 }
217
218 QString join(const QString &separator = QStringLiteral(",")) const
219 {
220 if (!m_list->count || !m_list->at)
221 return QString();
222
224 for (qsizetype i = 0, end = m_list->count(m_list); i < end; ++i) {
225 if (i != 0)
226 result += separator;
227 result += m_engine->coerceValue<QObject *, QString>(m_list->at(m_list, i));
228 }
229
230 return result;
231 }
232
234 {
235 return m_list->toList<QObjectList>();
236 }
238 {
239 if (!m_list->count || !m_list->at)
240 return QObjectList();
241
242 const qsizetype size = m_list->count(m_list);
243 const qsizetype clampedStart = clamp(start, size);
245 result.reserve(size - clampedStart);
246 for (qsizetype i = clampedStart; i < size; ++i)
247 result.append(m_list->at(m_list, i));
248 return result;
249 }
251 {
252 if (!m_list->count || !m_list->at)
253 return QObjectList();
254
255 const qsizetype size = m_list->count(m_list);
256 const qsizetype clampedStart = clamp(start, size);
257 const qsizetype clampedEnd = clamp(end, size, clampedStart);
259 result.reserve(clampedEnd - clampedStart);
260 for (qsizetype i = clampedStart; i < clampedEnd; ++i)
261 result.append(m_list->at(m_list, i));
262 return result;
263 }
264
266 {
267 if (!m_list->count || !m_list->at)
268 return -1;
269
270 const qsizetype end = m_list->count(m_list);
271 for (qsizetype i = 0; i < end; ++i) {
272 if (m_list->at(m_list, i) == value)
273 return i;
274 }
275 return -1;
276 }
278 {
279 if (!m_list->count || !m_list->at)
280 return -1;
281
282 const qsizetype size = m_list->count(m_list);
283 for (qsizetype i = clamp(start, size); i < size; ++i) {
284 if (m_list->at(m_list, i) == value)
285 return i;
286 }
287 return -1;
288 }
289
291 {
292 if (!m_list->count || !m_list->at)
293 return -1;
294
295 for (qsizetype i = m_list->count(m_list) - 1; i >= 0; --i) {
296 if (m_list->at(m_list, i) == value)
297 return i;
298 }
299 return -1;
300 }
302 {
303 if (!m_list->count || !m_list->at)
304 return -1;
305
306 const qsizetype size = m_list->count(m_list);
307 if (size == 0)
308 return -1;
309
310 qsizetype clampedStart = std::min(clamp(start, size), size - 1);
311 for (qsizetype i = clampedStart; i >= 0; --i) {
312 if (m_list->at(m_list, i) == value)
313 return i;
314 }
315 return -1;
316 }
317
318 QString toString() const { return join(); }
319
320private:
321 QQmlListProperty<QObject> *m_list = nullptr;
322 QJSEngine *m_engine = nullptr;
323};
324
326{
327public:
329 template<typename List, typename Value>
330 void init(const QJSList<List, Value> &list)
331 {
332 m_index = 0;
333 m_size = list.size();
334 }
335
336 bool hasNext() const { return m_index < m_size; }
337 qsizetype next() { return m_index++; }
338
339private:
340 qsizetype m_index;
341 qsizetype m_size;
342};
343
344// QJSListForInIterator must not require initialization so that we can jump over it with goto.
345static_assert(std::is_trivial_v<QJSListForInIterator>);
346
348{
349public:
351 void init() { m_index = 0; }
352
353 template<typename List, typename Value>
354 bool hasNext(const QJSList<List, Value> &list) const { return m_index < list.size(); }
355
356 template<typename List, typename Value>
357 Value next(const QJSList<List, Value> &list) { return list.at(m_index++); }
358
359private:
360 qsizetype m_index;
361};
362
363// QJSListForOfIterator must not require initialization so that we can jump over it with goto.
364static_assert(std::is_trivial_v<QJSListForOfIterator>);
365
367
368#endif // QJSLIST_H
The QJSEngine class provides an environment for evaluating JavaScript code.
Definition qjsengine.h:26
qsizetype size() const noexcept
Definition qlist.h:397
QList< T > toList() const noexcept
Definition qlist.h:723
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void reserve(qsizetype size)
Definition qlist.h:753
\inmodule QtCore
Definition qobject.h:103
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Definition qqmllist.h:24
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
list append(new Employee("Blackpool", "Stephen"))
QSet< QString >::iterator it
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
QList< QObject * > QObjectList
Definition qobject.h:45
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLfloat GLfloat clamp
GLuint start
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define QStringLiteral(str)
ptrdiff_t qsizetype
Definition qtypes.h:165
QList< int > list
[14]
QJSEngine engine
[0]
bool hasNext() const
Definition qjslist.h:336
void init(const QJSList< List, Value > &list)
Definition qjslist.h:330
qsizetype next()
Definition qjslist.h:337
Value next(const QJSList< List, Value > &list)
Definition qjslist.h:357
bool hasNext(const QJSList< List, Value > &list) const
Definition qjslist.h:354
static qsizetype clamp(qsizetype start, qsizetype max, qsizetype min=0)
Definition qjslist.h:31
bool includes(const QObject *value, qsizetype start) const
Definition qjslist.h:204
QObjectList slice(qsizetype start, qsizetype end) const
Definition qjslist.h:250
qsizetype indexOf(const QObject *value, qsizetype start) const
Definition qjslist.h:277
qsizetype lastIndexOf(const QObject *value, qsizetype start) const
Definition qjslist.h:301
QObject * at(qsizetype index) const
Definition qjslist.h:166
bool includes(const QObject *value) const
Definition qjslist.h:191
QString join(const QString &separator=QStringLiteral(",")) const
Definition qjslist.h:218
QObjectList slice(qsizetype start) const
Definition qjslist.h:237
qsizetype indexOf(const QObject *value) const
Definition qjslist.h:265
qsizetype lastIndexOf(const QObject *value) const
Definition qjslist.h:290
qsizetype size() const
Definition qjslist.h:52
bool includes(const Value &value) const
Definition qjslist.h:59
List slice(qsizetype start) const
Definition qjslist.h:88
void resize(qsizetype size)
Definition qjslist.h:54
QString join(const QString &separator=QStringLiteral(",")) const
Definition qjslist.h:70
qsizetype indexOf(const Value &value) const
Definition qjslist.h:107
List slice(qsizetype start, qsizetype end) const
Definition qjslist.h:95
bool includes(const Value &value, qsizetype start) const
Definition qjslist.h:64
List slice() const
Definition qjslist.h:84
QString toString() const
Definition qjslist.h:152
qsizetype lastIndexOf(const Value &value) const
Definition qjslist.h:130
qsizetype indexOf(const Value &value, qsizetype start) const
Definition qjslist.h:118
Value at(qsizetype index) const
Definition qjslist.h:46
qsizetype lastIndexOf(const Value &value, qsizetype start) const
Definition qjslist.h:137