1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2020 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #ifndef QMETACONTAINER_H |
41 | #define QMETACONTAINER_H |
42 | |
43 | #include <QtCore/qcontainerinfo.h> |
44 | #include <QtCore/qflags.h> |
45 | #include <QtCore/qglobal.h> |
46 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | class QMetaType; |
50 | namespace QtPrivate { |
51 | class QMetaTypeInterface; |
52 | template<typename T> |
53 | constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType(); |
54 | } |
55 | |
56 | namespace QtMetaContainerPrivate { |
57 | |
58 | enum IteratorCapability : quint8 { |
59 | InputCapability = 1 << 0, |
60 | ForwardCapability = 1 << 1, |
61 | BiDirectionalCapability = 1 << 2, |
62 | RandomAccessCapability = 1 << 3, |
63 | }; |
64 | |
65 | Q_DECLARE_FLAGS(IteratorCapabilities, IteratorCapability) |
66 | Q_DECLARE_OPERATORS_FOR_FLAGS(IteratorCapabilities) |
67 | |
68 | enum AddRemoveCapability : quint8 { |
69 | CanAddAtBegin = 1 << 0, |
70 | CanRemoveAtBegin = 1 << 1, |
71 | CanAddAtEnd = 1 << 2, |
72 | CanRemoveAtEnd = 1 << 3 |
73 | }; |
74 | Q_DECLARE_FLAGS(AddRemoveCapabilities, AddRemoveCapability) |
75 | Q_DECLARE_OPERATORS_FOR_FLAGS(AddRemoveCapabilities) |
76 | |
77 | class QMetaContainerInterface |
78 | { |
79 | public: |
80 | enum Position : quint8 { AtBegin, AtEnd, Unspecified }; |
81 | ushort revision = 0; |
82 | IteratorCapabilities iteratorCapabilities; |
83 | |
84 | using SizeFn = qsizetype(*)(const void *); |
85 | SizeFn sizeFn; |
86 | using ClearFn = void(*)(void *); |
87 | ClearFn clearFn; |
88 | |
89 | using CreateIteratorFn = void *(*)(void *, Position); |
90 | CreateIteratorFn createIteratorFn; |
91 | using DestroyIteratorFn = void(*)(const void *); |
92 | DestroyIteratorFn destroyIteratorFn; |
93 | using CompareIteratorFn = bool(*)(const void *, const void *); |
94 | CompareIteratorFn compareIteratorFn; |
95 | using CopyIteratorFn = void(*)(void *, const void *); |
96 | CopyIteratorFn copyIteratorFn; |
97 | using AdvanceIteratorFn = void(*)(void *, qsizetype); |
98 | AdvanceIteratorFn advanceIteratorFn; |
99 | using DiffIteratorFn = qsizetype(*)(const void *, const void *); |
100 | DiffIteratorFn diffIteratorFn; |
101 | |
102 | using CreateConstIteratorFn = void *(*)(const void *, Position); |
103 | CreateConstIteratorFn createConstIteratorFn; |
104 | DestroyIteratorFn destroyConstIteratorFn; |
105 | CompareIteratorFn compareConstIteratorFn; |
106 | CopyIteratorFn copyConstIteratorFn; |
107 | AdvanceIteratorFn advanceConstIteratorFn; |
108 | DiffIteratorFn diffConstIteratorFn; |
109 | |
110 | QMetaContainerInterface() = default; |
111 | |
112 | template<typename MetaContainer> |
113 | constexpr QMetaContainerInterface(const MetaContainer &) |
114 | : iteratorCapabilities(MetaContainer::getIteratorCapabilities()) |
115 | , sizeFn(MetaContainer::getSizeFn()) |
116 | , clearFn(MetaContainer::getClearFn()) |
117 | , createIteratorFn(MetaContainer::getCreateIteratorFn()) |
118 | , destroyIteratorFn(MetaContainer::getDestroyIteratorFn()) |
119 | , compareIteratorFn(MetaContainer::getCompareIteratorFn()) |
120 | , copyIteratorFn(MetaContainer::getCopyIteratorFn()) |
121 | , advanceIteratorFn(MetaContainer::getAdvanceIteratorFn()) |
122 | , diffIteratorFn(MetaContainer::getDiffIteratorFn()) |
123 | , createConstIteratorFn(MetaContainer::getCreateConstIteratorFn()) |
124 | , destroyConstIteratorFn(MetaContainer::getDestroyConstIteratorFn()) |
125 | , compareConstIteratorFn(MetaContainer::getCompareConstIteratorFn()) |
126 | , copyConstIteratorFn(MetaContainer::getCopyConstIteratorFn()) |
127 | , advanceConstIteratorFn(MetaContainer::getAdvanceConstIteratorFn()) |
128 | , diffConstIteratorFn(MetaContainer::getDiffConstIteratorFn()) |
129 | {} |
130 | }; |
131 | |
132 | class QMetaSequenceInterface : public QMetaContainerInterface |
133 | { |
134 | public: |
135 | const QtPrivate::QMetaTypeInterface *valueMetaType; |
136 | AddRemoveCapabilities addRemoveCapabilities; |
137 | |
138 | using ValueAtIndexFn = void(*)(const void *, qsizetype, void *); |
139 | ValueAtIndexFn valueAtIndexFn; |
140 | using SetValueAtIndexFn = void(*)(void *, qsizetype, const void *); |
141 | SetValueAtIndexFn setValueAtIndexFn; |
142 | |
143 | using AddValueFn = void(*)(void *, const void *, Position); |
144 | AddValueFn addValueFn; |
145 | using RemoveValueFn = void(*)(void *, Position); |
146 | RemoveValueFn removeValueFn; |
147 | |
148 | using ValueAtIteratorFn = void(*)(const void *, void *); |
149 | ValueAtIteratorFn valueAtIteratorFn; |
150 | using SetValueAtIteratorFn = void(*)(const void *, const void *); |
151 | SetValueAtIteratorFn setValueAtIteratorFn; |
152 | using InsertValueAtIteratorFn = void(*)(void *, const void *, const void *); |
153 | InsertValueAtIteratorFn insertValueAtIteratorFn; |
154 | |
155 | ValueAtIteratorFn valueAtConstIteratorFn; |
156 | |
157 | using EraseValueAtIteratorFn = void(*)(void *, const void *); |
158 | EraseValueAtIteratorFn eraseValueAtIteratorFn; |
159 | |
160 | using EraseRangeAtIteratorFn = void(*)(void *, const void *, const void *); |
161 | EraseRangeAtIteratorFn eraseRangeAtIteratorFn; |
162 | |
163 | QMetaSequenceInterface() = default; |
164 | |
165 | template<typename MetaSequence> |
166 | constexpr QMetaSequenceInterface(const MetaSequence &m) |
167 | : QMetaContainerInterface(m) |
168 | , valueMetaType(MetaSequence::getValueMetaType()) |
169 | , addRemoveCapabilities(MetaSequence::getAddRemoveCapabilities()) |
170 | , valueAtIndexFn(MetaSequence::getValueAtIndexFn()) |
171 | , setValueAtIndexFn(MetaSequence::getSetValueAtIndexFn()) |
172 | , addValueFn(MetaSequence::getAddValueFn()) |
173 | , removeValueFn(MetaSequence::getRemoveValueFn()) |
174 | , valueAtIteratorFn(MetaSequence::getValueAtIteratorFn()) |
175 | , setValueAtIteratorFn(MetaSequence::getSetValueAtIteratorFn()) |
176 | , insertValueAtIteratorFn(MetaSequence::getInsertValueAtIteratorFn()) |
177 | , valueAtConstIteratorFn(MetaSequence::getValueAtConstIteratorFn()) |
178 | , eraseValueAtIteratorFn(MetaSequence::getEraseValueAtIteratorFn()) |
179 | , eraseRangeAtIteratorFn(MetaSequence::getEraseRangeAtIteratorFn()) |
180 | {} |
181 | }; |
182 | |
183 | class QMetaAssociationInterface : public QMetaContainerInterface |
184 | { |
185 | public: |
186 | const QtPrivate::QMetaTypeInterface *keyMetaType; |
187 | const QtPrivate::QMetaTypeInterface *mappedMetaType; |
188 | |
189 | using InsertKeyFn = void(*)(void *, const void *); |
190 | InsertKeyFn insertKeyFn; |
191 | using RemoveKeyFn = void(*)(void *, const void *); |
192 | RemoveKeyFn removeKeyFn; |
193 | using ContainsKeyFn = bool(*)(const void *, const void *); |
194 | ContainsKeyFn containsKeyFn; |
195 | |
196 | using MappedAtKeyFn = void(*)(const void *, const void *, void *); |
197 | MappedAtKeyFn mappedAtKeyFn; |
198 | using SetMappedAtKeyFn = void(*)(void *, const void *, const void *); |
199 | SetMappedAtKeyFn setMappedAtKeyFn; |
200 | |
201 | using CreateIteratorAtKeyFn = void *(*)(void *, const void *); |
202 | CreateIteratorAtKeyFn createIteratorAtKeyFn; |
203 | using CreateConstIteratorAtKeyFn = void *(*)(const void *, const void *); |
204 | CreateConstIteratorAtKeyFn createConstIteratorAtKeyFn; |
205 | |
206 | using KeyAtIteratorFn = void(*)(const void *, void *); |
207 | KeyAtIteratorFn keyAtIteratorFn; |
208 | KeyAtIteratorFn keyAtConstIteratorFn; |
209 | |
210 | using MappedAtIteratorFn = void(*)(const void *, void *); |
211 | MappedAtIteratorFn mappedAtIteratorFn; |
212 | MappedAtIteratorFn mappedAtConstIteratorFn; |
213 | |
214 | using SetMappedAtIteratorFn = void(*)(const void *, const void *); |
215 | SetMappedAtIteratorFn setMappedAtIteratorFn; |
216 | |
217 | using EraseKeyAtIteratorFn = void(*)(void *, const void *); |
218 | EraseKeyAtIteratorFn eraseKeyAtIteratorFn; |
219 | |
220 | QMetaAssociationInterface() = default; |
221 | |
222 | template<typename MetaAssociation> |
223 | constexpr QMetaAssociationInterface(const MetaAssociation &m) |
224 | : QMetaContainerInterface(m) |
225 | , keyMetaType(MetaAssociation::getKeyMetaType()) |
226 | , mappedMetaType(MetaAssociation::getMappedMetaType()) |
227 | , insertKeyFn(MetaAssociation::getInsertKeyFn()) |
228 | , removeKeyFn(MetaAssociation::getRemoveKeyFn()) |
229 | , containsKeyFn(MetaAssociation::getContainsKeyFn()) |
230 | , mappedAtKeyFn(MetaAssociation::getMappedAtKeyFn()) |
231 | , setMappedAtKeyFn(MetaAssociation::getSetMappedAtKeyFn()) |
232 | , createIteratorAtKeyFn(MetaAssociation::createIteratorAtKeyFn()) |
233 | , createConstIteratorAtKeyFn(MetaAssociation::createConstIteratorAtKeyFn()) |
234 | , keyAtIteratorFn(MetaAssociation::getKeyAtIteratorFn()) |
235 | , keyAtConstIteratorFn(MetaAssociation::getKeyAtConstIteratorFn()) |
236 | , mappedAtIteratorFn(MetaAssociation::getMappedAtIteratorFn()) |
237 | , mappedAtConstIteratorFn(MetaAssociation::getMappedAtConstIteratorFn()) |
238 | , setMappedAtIteratorFn(MetaAssociation::getSetMappedAtIteratorFn()) |
239 | , eraseKeyAtIteratorFn(MetaAssociation::getEraseKeyAtIteratorFn()) |
240 | {} |
241 | }; |
242 | |
243 | template<typename C> |
244 | class QMetaContainerForContainer |
245 | { |
246 | friend QMetaContainerInterface; |
247 | |
248 | template <typename Iterator> |
249 | static constexpr IteratorCapabilities capabilitiesForIterator() |
250 | { |
251 | using Tag = typename std::iterator_traits<Iterator>::iterator_category; |
252 | IteratorCapabilities caps {}; |
253 | if constexpr (std::is_base_of_v<std::input_iterator_tag, Tag>) |
254 | caps |= InputCapability; |
255 | if constexpr (std::is_base_of_v<std::forward_iterator_tag, Tag>) |
256 | caps |= ForwardCapability; |
257 | if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, Tag>) |
258 | caps |= BiDirectionalCapability; |
259 | if constexpr (std::is_base_of_v<std::random_access_iterator_tag, Tag>) |
260 | caps |= RandomAccessCapability; |
261 | return caps; |
262 | } |
263 | |
264 | static constexpr IteratorCapabilities getIteratorCapabilities() |
265 | { |
266 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) |
267 | return capabilitiesForIterator<QContainerTraits::iterator<C>>(); |
268 | else if constexpr (QContainerTraits::has_const_iterator_v<C>) |
269 | return capabilitiesForIterator<QContainerTraits::const_iterator<C>>(); |
270 | else |
271 | return {}; |
272 | } |
273 | |
274 | static constexpr QMetaContainerInterface::SizeFn getSizeFn() |
275 | { |
276 | if constexpr (QContainerTraits::has_size_v<C>) { |
277 | return [](const void *c) -> qsizetype { return static_cast<const C *>(c)->size(); }; |
278 | } else { |
279 | return nullptr; |
280 | } |
281 | } |
282 | |
283 | static constexpr QMetaContainerInterface::ClearFn getClearFn() |
284 | { |
285 | if constexpr (QContainerTraits::has_clear_v<C>) { |
286 | return [](void *c) { return static_cast<C *>(c)->clear(); }; |
287 | } else { |
288 | return nullptr; |
289 | } |
290 | } |
291 | |
292 | static constexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn() |
293 | { |
294 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
295 | return [](void *c, QMetaContainerInterface::Position p) -> void* { |
296 | using Iterator = QContainerTraits::iterator<C>; |
297 | switch (p) { |
298 | case QMetaContainerInterface::Unspecified: |
299 | return new Iterator; |
300 | case QMetaContainerInterface::AtBegin: |
301 | return new Iterator(static_cast<C *>(c)->begin()); |
302 | break; |
303 | case QMetaContainerInterface::AtEnd: |
304 | return new Iterator(static_cast<C *>(c)->end()); |
305 | break; |
306 | } |
307 | return nullptr; |
308 | }; |
309 | } else { |
310 | return nullptr; |
311 | } |
312 | } |
313 | |
314 | static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn() |
315 | { |
316 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
317 | return [](const void *i) { |
318 | using Iterator = QContainerTraits::iterator<C>; |
319 | delete static_cast<const Iterator *>(i); |
320 | }; |
321 | } else { |
322 | return nullptr; |
323 | } |
324 | } |
325 | |
326 | static constexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn() |
327 | { |
328 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
329 | return [](const void *i, const void *j) { |
330 | using Iterator = QContainerTraits::iterator<C>; |
331 | return *static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j); |
332 | }; |
333 | } else { |
334 | return nullptr; |
335 | } |
336 | } |
337 | |
338 | static constexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn() |
339 | { |
340 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
341 | return [](void *i, const void *j) { |
342 | using Iterator = QContainerTraits::iterator<C>; |
343 | *static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j); |
344 | }; |
345 | } else { |
346 | return nullptr; |
347 | } |
348 | } |
349 | |
350 | static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn() |
351 | { |
352 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
353 | return [](void *i, qsizetype step) { |
354 | std::advance(*static_cast<QContainerTraits::iterator<C> *>(i), step); |
355 | }; |
356 | } else { |
357 | return nullptr; |
358 | } |
359 | } |
360 | |
361 | static constexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn() |
362 | { |
363 | if constexpr (QContainerTraits::has_iterator_v<C> && !std::is_const_v<C>) { |
364 | return [](const void *i, const void *j) -> qsizetype { |
365 | return std::distance(*static_cast<const QContainerTraits::iterator<C> *>(j), |
366 | *static_cast<const QContainerTraits::iterator<C> *>(i)); |
367 | }; |
368 | } else { |
369 | return nullptr; |
370 | } |
371 | } |
372 | |
373 | static constexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn() |
374 | { |
375 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
376 | return [](const void *c, QMetaContainerInterface::Position p) -> void* { |
377 | using Iterator = QContainerTraits::const_iterator<C>; |
378 | switch (p) { |
379 | case QMetaContainerInterface::Unspecified: |
380 | return new Iterator; |
381 | case QMetaContainerInterface::AtBegin: |
382 | return new Iterator(static_cast<const C *>(c)->begin()); |
383 | case QMetaContainerInterface::AtEnd: |
384 | return new Iterator(static_cast<const C *>(c)->end()); |
385 | } |
386 | return nullptr; |
387 | }; |
388 | } else { |
389 | return nullptr; |
390 | } |
391 | } |
392 | |
393 | static constexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn() |
394 | { |
395 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
396 | return [](const void *i) { |
397 | using Iterator = QContainerTraits::const_iterator<C>; |
398 | delete static_cast<const Iterator *>(i); |
399 | }; |
400 | } else { |
401 | return nullptr; |
402 | } |
403 | } |
404 | |
405 | static constexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn() |
406 | { |
407 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
408 | return [](const void *i, const void *j) { |
409 | using Iterator = QContainerTraits::const_iterator<C>; |
410 | return *static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j); |
411 | }; |
412 | } else { |
413 | return nullptr; |
414 | } |
415 | } |
416 | |
417 | static constexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn() |
418 | { |
419 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
420 | return [](void *i, const void *j) { |
421 | using Iterator = QContainerTraits::const_iterator<C>; |
422 | *static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j); |
423 | }; |
424 | } else { |
425 | return nullptr; |
426 | } |
427 | } |
428 | |
429 | static constexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn() |
430 | { |
431 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
432 | return [](void *i, qsizetype step) { |
433 | std::advance(*static_cast<QContainerTraits::const_iterator<C> *>(i), step); |
434 | }; |
435 | } else { |
436 | return nullptr; |
437 | } |
438 | } |
439 | |
440 | static constexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn() |
441 | { |
442 | if constexpr (QContainerTraits::has_const_iterator_v<C>) { |
443 | return [](const void *i, const void *j) -> qsizetype { |
444 | return std::distance(*static_cast<const QContainerTraits::const_iterator<C> *>(j), |
445 | *static_cast<const QContainerTraits::const_iterator<C> *>(i)); |
446 | }; |
447 | } else { |
448 | return nullptr; |
449 | } |
450 | } |
451 | |
452 | protected: |
453 | |
454 | template<typename EraseFn> |
455 | static constexpr EraseFn getEraseAtIteratorFn() |
456 | { |
457 | if constexpr (QContainerTraits::has_iterator_v<C> |
458 | && QContainerTraits::can_erase_at_iterator_v<C> && !std::is_const_v<C>) { |
459 | return [](void *c, const void *i) { |
460 | static_cast<C *>(c)->erase(*static_cast<const QContainerTraits::iterator<C> *>(i)); |
461 | }; |
462 | } else { |
463 | return nullptr; |
464 | } |
465 | } |
466 | }; |
467 | |
468 | template<typename C> |
469 | class QMetaSequenceForContainer : public QMetaContainerForContainer<C> |
470 | { |
471 | friend QMetaSequenceInterface; |
472 | |
473 | static constexpr const QtPrivate::QMetaTypeInterface *getValueMetaType() |
474 | { |
475 | if constexpr (QContainerTraits::has_value_type_v<C>) |
476 | return QtPrivate::qMetaTypeInterfaceForType<typename C::value_type>(); |
477 | else |
478 | return nullptr; |
479 | } |
480 | |
481 | static constexpr AddRemoveCapabilities getAddRemoveCapabilities() |
482 | { |
483 | AddRemoveCapabilities caps; |
484 | if constexpr (QContainerTraits::has_push_back_v<C>) |
485 | caps |= CanAddAtEnd; |
486 | if constexpr (QContainerTraits::has_pop_back_v<C>) |
487 | caps |= CanRemoveAtEnd; |
488 | if constexpr (QContainerTraits::has_push_front_v<C>) |
489 | caps |= CanAddAtBegin; |
490 | if constexpr (QContainerTraits::has_pop_front_v<C>) |
491 | caps |= CanRemoveAtBegin; |
492 | return caps; |
493 | } |
494 | |
495 | static constexpr QMetaSequenceInterface::ValueAtIndexFn getValueAtIndexFn() |
496 | { |
497 | if constexpr (QContainerTraits::has_at_index_v<C>) { |
498 | return [](const void *c, qsizetype i, void *r) { |
499 | *static_cast<QContainerTraits::value_type<C> *>(r) |
500 | = static_cast<const C *>(c)->at(i); |
501 | }; |
502 | } else if constexpr (QContainerTraits::can_get_at_index_v<C>) { |
503 | return [](const void *c, qsizetype i, void *r) { |
504 | *static_cast<QContainerTraits::value_type<C> *>(r) |
505 | = (*static_cast<const C *>(c))[i]; |
506 | }; |
507 | } else { |
508 | return nullptr; |
509 | } |
510 | } |
511 | |
512 | static constexpr QMetaSequenceInterface::SetValueAtIndexFn getSetValueAtIndexFn() |
513 | { |
514 | if constexpr (QContainerTraits::can_set_at_index_v<C>) { |
515 | return [](void *c, qsizetype i, const void *e) { |
516 | (*static_cast<C *>(c))[i] |
517 | = *static_cast<const QContainerTraits::value_type<C> *>(e); |
518 | }; |
519 | } else { |
520 | return nullptr; |
521 | } |
522 | } |
523 | |
524 | static constexpr QMetaSequenceInterface::AddValueFn getAddValueFn() |
525 | { |
526 | if constexpr (QContainerTraits::has_push_back_v<C>) { |
527 | if constexpr (QContainerTraits::has_push_front_v<C>) { |
528 | return [](void *c, const void *v, QMetaSequenceInterface::Position position) { |
529 | const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v); |
530 | switch (position) { |
531 | case QMetaSequenceInterface::AtBegin: |
532 | static_cast<C *>(c)->push_front(value); |
533 | break; |
534 | case QMetaSequenceInterface::AtEnd: |
535 | case QMetaSequenceInterface::Unspecified: |
536 | static_cast<C *>(c)->push_back(value); |
537 | break; |
538 | } |
539 | }; |
540 | } else { |
541 | return [](void *c, const void *v, QMetaSequenceInterface::Position position) { |
542 | const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v); |
543 | switch (position) { |
544 | case QMetaSequenceInterface::AtBegin: |
545 | break; |
546 | case QMetaSequenceInterface::AtEnd: |
547 | case QMetaSequenceInterface::Unspecified: |
548 | static_cast<C *>(c)->push_back(value); |
549 | break; |
550 | } |
551 | }; |
552 | } |
553 | } else if constexpr (QContainerTraits::has_push_front_v<C>) { |
554 | return [](void *c, const void *v, QMetaSequenceInterface::Position position) { |
555 | const auto &value = *static_cast<const QContainerTraits::value_type<C> *>(v); |
556 | switch (position) { |
557 | case QMetaSequenceInterface::Unspecified: |
558 | case QMetaSequenceInterface::AtBegin: |
559 | static_cast<C *>(c)->push_front(value); |
560 | case QMetaSequenceInterface::AtEnd: |
561 | break; |
562 | } |
563 | }; |
564 | } else if constexpr (QContainerTraits::has_insert_v<C>) { |
565 | return [](void *c, const void *v, QMetaSequenceInterface::Position position) { |
566 | if (position == QMetaSequenceInterface::Unspecified) { |
567 | static_cast<C *>(c)->insert( |
568 | *static_cast<const QContainerTraits::value_type<C> *>(v)); |
569 | } |
570 | }; |
571 | } else { |
572 | return nullptr; |
573 | } |
574 | } |
575 | |
576 | static constexpr QMetaSequenceInterface::RemoveValueFn getRemoveValueFn() |
577 | { |
578 | if constexpr (QContainerTraits::has_pop_back_v<C>) { |
579 | if constexpr (QContainerTraits::has_pop_front_v<C>) { |
580 | return [](void *c, QMetaSequenceInterface::Position position) { |
581 | switch (position) { |
582 | case QMetaSequenceInterface::AtBegin: |
583 | static_cast<C *>(c)->pop_front(); |
584 | break; |
585 | case QMetaSequenceInterface::AtEnd: |
586 | case QMetaSequenceInterface::Unspecified: |
587 | static_cast<C *>(c)->pop_back(); |
588 | break; |
589 | } |
590 | }; |
591 | } else { |
592 | return [](void *c, QMetaSequenceInterface::Position position) { |
593 | switch (position) { |
594 | case QMetaSequenceInterface::AtBegin: |
595 | break; |
596 | case QMetaSequenceInterface::Unspecified: |
597 | case QMetaSequenceInterface::AtEnd: |
598 | static_cast<C *>(c)->pop_back(); |
599 | break; |
600 | } |
601 | }; |
602 | } |
603 | } else if constexpr (QContainerTraits::has_pop_front_v<C>) { |
604 | return [](void *c, QMetaSequenceInterface::Position position) { |
605 | switch (position) { |
606 | case QMetaSequenceInterface::Unspecified: |
607 | case QMetaSequenceInterface::AtBegin: |
608 | static_cast<C *>(c)->pop_front(); |
609 | break; |
610 | case QMetaSequenceInterface::AtEnd: |
611 | break; |
612 | } |
613 | }; |
614 | } else { |
615 | return nullptr; |
616 | } |
617 | } |
618 | |
619 | static constexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtIteratorFn() |
620 | { |
621 | if constexpr (QContainerTraits::has_iterator_v<C> |
622 | && QContainerTraits::iterator_dereferences_to_value_v<C> && !std::is_const_v<C>) { |
623 | return [](const void *i, void *r) { |
624 | *static_cast<QContainerTraits::value_type<C> *>(r) = |
625 | *(*static_cast<const QContainerTraits::iterator<C> *>(i)); |
626 | }; |
627 | } else { |
628 | return nullptr; |
629 | } |
630 | } |
631 | |
632 | static constexpr QMetaSequenceInterface::SetValueAtIteratorFn getSetValueAtIteratorFn() |
633 | { |
634 | if constexpr (QContainerTraits::has_iterator_v<C> |
635 | && QContainerTraits::can_set_value_at_iterator_v<C> && !std::is_const_v<C>) { |
636 | return [](const void *i, const void *e) { |
637 | *(*static_cast<const QContainerTraits::iterator<C> *>(i)) |
638 | = *static_cast<const QContainerTraits::value_type<C> *>(e); |
639 | }; |
640 | } else { |
641 | return nullptr; |
642 | } |
643 | } |
644 | |
645 | static constexpr QMetaSequenceInterface::InsertValueAtIteratorFn getInsertValueAtIteratorFn() |
646 | { |
647 | if constexpr (QContainerTraits::has_iterator_v<C> |
648 | && QContainerTraits::can_insert_value_at_iterator_v<C> && !std::is_const_v<C>) { |
649 | return [](void *c, const void *i, const void *e) { |
650 | static_cast<C *>(c)->insert( |
651 | *static_cast<const QContainerTraits::iterator<C> *>(i), |
652 | *static_cast<const QContainerTraits::value_type<C> *>(e)); |
653 | }; |
654 | } else { |
655 | return nullptr; |
656 | } |
657 | } |
658 | |
659 | static constexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtConstIteratorFn() |
660 | { |
661 | if constexpr (QContainerTraits::has_const_iterator_v<C> |
662 | && QContainerTraits::iterator_dereferences_to_value_v<C>) { |
663 | return [](const void *i, void *r) { |
664 | *static_cast<QContainerTraits::value_type<C> *>(r) = |
665 | *(*static_cast<const QContainerTraits::const_iterator<C> *>(i)); |
666 | }; |
667 | } else { |
668 | return nullptr; |
669 | } |
670 | } |
671 | |
672 | static constexpr QMetaSequenceInterface::EraseValueAtIteratorFn getEraseValueAtIteratorFn() |
673 | { |
674 | return QMetaContainerForContainer<C>::template getEraseAtIteratorFn< |
675 | QMetaSequenceInterface::EraseValueAtIteratorFn>(); |
676 | } |
677 | |
678 | static constexpr QMetaSequenceInterface::EraseRangeAtIteratorFn getEraseRangeAtIteratorFn() |
679 | { |
680 | if constexpr (QContainerTraits::has_iterator_v<C> |
681 | && QContainerTraits::can_erase_range_at_iterator_v<C> && !std::is_const_v<C>) { |
682 | return [](void *c, const void *i, const void *j) { |
683 | static_cast<C *>(c)->erase(*static_cast<const QContainerTraits::iterator<C> *>(i), |
684 | *static_cast<const QContainerTraits::iterator<C> *>(j)); |
685 | }; |
686 | } else { |
687 | return nullptr; |
688 | } |
689 | } |
690 | }; |
691 | |
692 | template<typename C> |
693 | class QMetaAssociationForContainer : public QMetaContainerForContainer<C> |
694 | { |
695 | friend QMetaAssociationInterface; |
696 | |
697 | static constexpr const QtPrivate::QMetaTypeInterface *getKeyMetaType() |
698 | { |
699 | if constexpr (QContainerTraits::has_key_type_v<C>) |
700 | return QtPrivate::qMetaTypeInterfaceForType<typename C::key_type>(); |
701 | else |
702 | return nullptr; |
703 | } |
704 | |
705 | static constexpr const QtPrivate::QMetaTypeInterface *getMappedMetaType() |
706 | { |
707 | if constexpr (QContainerTraits::has_mapped_type_v<C>) |
708 | return QtPrivate::qMetaTypeInterfaceForType<typename C::mapped_type>(); |
709 | else |
710 | return nullptr; |
711 | } |
712 | |
713 | static constexpr QMetaAssociationInterface::InsertKeyFn getInsertKeyFn() |
714 | { |
715 | if constexpr (QContainerTraits::can_insert_key_v<C>) { |
716 | return [](void *c, const void *k) { |
717 | static_cast<C *>(c)->insert( |
718 | *static_cast<const QContainerTraits::key_type<C> *>(k)); |
719 | }; |
720 | } else if constexpr (QContainerTraits::can_insert_pair_v<C>) { |
721 | return [](void *c, const void *k) { |
722 | static_cast<C *>(c)->insert( |
723 | {*static_cast<const QContainerTraits::key_type<C> *>(k), {}}); |
724 | }; |
725 | } else if constexpr (QContainerTraits::can_insert_key_mapped_v<C>) { |
726 | return [](void *c, const void *k) { |
727 | static_cast<C *>(c)->insert( |
728 | *static_cast<const QContainerTraits::key_type<C> *>(k), {}); |
729 | }; |
730 | } else { |
731 | return nullptr; |
732 | } |
733 | } |
734 | |
735 | static constexpr QMetaAssociationInterface::RemoveKeyFn getRemoveKeyFn() |
736 | { |
737 | if constexpr (QContainerTraits::can_erase_at_key_v<C>) { |
738 | return [](void *c, const void *k) { |
739 | static_cast<C *>(c)->erase(*static_cast<const QContainerTraits::key_type<C> *>(k)); |
740 | }; |
741 | } else if constexpr (QContainerTraits::can_remove_at_key_v<C>) { |
742 | return [](void *c, const void *k) { |
743 | static_cast<C *>(c)->remove(*static_cast<const QContainerTraits::key_type<C> *>(k)); |
744 | }; |
745 | } else { |
746 | return nullptr; |
747 | } |
748 | } |
749 | |
750 | static constexpr QMetaAssociationInterface::ContainsKeyFn getContainsKeyFn() |
751 | { |
752 | if constexpr (QContainerTraits::has_contains_v<C>) { |
753 | return [](const void *c, const void *k) { |
754 | return static_cast<const C *>(c)->contains( |
755 | *static_cast<const QContainerTraits::key_type<C> *>(k)); |
756 | }; |
757 | } else if (QContainerTraits::has_find_v<C>) { |
758 | return [](const void *c, const void *k) { |
759 | const C *container = static_cast<const C *>(c); |
760 | return container->find( |
761 | *static_cast<const QContainerTraits::key_type<C> *>(k)) |
762 | != container->end(); |
763 | }; |
764 | } else { |
765 | return nullptr; |
766 | } |
767 | } |
768 | |
769 | static constexpr QMetaAssociationInterface::MappedAtKeyFn getMappedAtKeyFn() |
770 | { |
771 | if constexpr (QContainerTraits::has_at_key_v<C>) { |
772 | return [](const void *c, const void *k, void *r) { |
773 | *static_cast<QContainerTraits::mapped_type<C> *>(r) |
774 | = static_cast<const C *>(c)->at( |
775 | *static_cast<const QContainerTraits::key_type<C> *>(k)); |
776 | }; |
777 | } else if constexpr (QContainerTraits::can_get_at_key_v<C>) { |
778 | return [](const void *c, const void *k, void *r) { |
779 | *static_cast<QContainerTraits::mapped_type<C> *>(r) |
780 | = (*static_cast<const C *>(c))[ |
781 | *static_cast<const QContainerTraits::key_type<C> *>(k)]; |
782 | }; |
783 | } else { |
784 | return nullptr; |
785 | } |
786 | } |
787 | |
788 | static constexpr QMetaAssociationInterface::SetMappedAtKeyFn getSetMappedAtKeyFn() |
789 | { |
790 | if constexpr (QContainerTraits::can_set_at_key_v<C>) { |
791 | return [](void *c, const void *k, const void *m) { |
792 | (*static_cast<C *>(c))[*static_cast<const QContainerTraits::key_type<C> *>(k)] = |
793 | *static_cast<const QContainerTraits::mapped_type<C> *>(m); |
794 | }; |
795 | } else { |
796 | return nullptr; |
797 | } |
798 | } |
799 | |
800 | static constexpr QMetaAssociationInterface::CreateIteratorAtKeyFn createIteratorAtKeyFn() |
801 | { |
802 | if constexpr (QContainerTraits::has_find_v<C>) { |
803 | return [](void *c, const void *k) -> void* { |
804 | using Iterator = QContainerTraits::iterator<C>; |
805 | return new Iterator(static_cast<C *>(c)->find( |
806 | *static_cast<const QContainerTraits::key_type<C> *>(k))); |
807 | }; |
808 | } else { |
809 | return nullptr; |
810 | } |
811 | } |
812 | |
813 | static constexpr QMetaAssociationInterface::CreateConstIteratorAtKeyFn createConstIteratorAtKeyFn() |
814 | { |
815 | if constexpr (QContainerTraits::has_find_v<C>) { |
816 | return [](const void *c, const void *k) -> void* { |
817 | using Iterator = QContainerTraits::const_iterator<C>; |
818 | return new Iterator(static_cast<const C *>(c)->find( |
819 | *static_cast<const QContainerTraits::key_type<C> *>(k))); |
820 | }; |
821 | } else { |
822 | return nullptr; |
823 | } |
824 | } |
825 | |
826 | template<typename Iterator> |
827 | static constexpr QMetaAssociationInterface::KeyAtIteratorFn keyAtIteratorFn() |
828 | { |
829 | if constexpr (QContainerTraits::iterator_has_key_v<C>) { |
830 | return [](const void *i, void *k) { |
831 | *static_cast<QContainerTraits::key_type<C> *>(k) |
832 | = static_cast<const Iterator *>(i)->key(); |
833 | }; |
834 | } else if constexpr (QContainerTraits::iterator_dereferences_to_value_v<C> |
835 | && QContainerTraits::value_type_has_first_v<C>) { |
836 | return [](const void *i, void *k) { |
837 | *static_cast<QContainerTraits::key_type<C> *>(k) |
838 | = (*static_cast<const Iterator *>(i))->first; |
839 | }; |
840 | } else if constexpr (QContainerTraits::iterator_dereferences_to_key_v<C>) { |
841 | return [](const void *i, void *k) { |
842 | *static_cast<QContainerTraits::key_type<C> *>(k) |
843 | = *(*static_cast<const Iterator *>(i)); |
844 | }; |
845 | } else { |
846 | return nullptr; |
847 | } |
848 | } |
849 | |
850 | static constexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtIteratorFn() |
851 | { |
852 | return keyAtIteratorFn<QContainerTraits::iterator<C>>(); |
853 | } |
854 | |
855 | static constexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtConstIteratorFn() |
856 | { |
857 | return keyAtIteratorFn<QContainerTraits::const_iterator<C>>(); |
858 | } |
859 | |
860 | template<typename Iterator> |
861 | static constexpr QMetaAssociationInterface::MappedAtIteratorFn mappedAtIteratorFn() |
862 | { |
863 | if constexpr (QContainerTraits::iterator_has_value_v<C>) { |
864 | return [](const void *i, void *k) { |
865 | *static_cast<QContainerTraits::mapped_type<C> *>(k) |
866 | = static_cast<const Iterator *>(i)->value(); |
867 | }; |
868 | } else if constexpr (QContainerTraits::iterator_dereferences_to_value_v<C> |
869 | && QContainerTraits::value_type_has_second_v<C>) { |
870 | return [](const void *i, void *k) { |
871 | *static_cast<QContainerTraits::mapped_type<C> *>(k) |
872 | = (*static_cast<const Iterator *>(i))->second; |
873 | }; |
874 | } else if constexpr (QContainerTraits::iterator_dereferences_to_mapped_v<C>) { |
875 | return [](const void *i, void *k) { |
876 | *static_cast<QContainerTraits::mapped_type<C> *>(k) |
877 | = *static_cast<const Iterator *>(i); |
878 | }; |
879 | } else { |
880 | return nullptr; |
881 | } |
882 | } |
883 | |
884 | static constexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtIteratorFn() |
885 | { |
886 | return mappedAtIteratorFn<QContainerTraits::iterator<C>>(); |
887 | } |
888 | |
889 | static constexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtConstIteratorFn() |
890 | { |
891 | return mappedAtIteratorFn<QContainerTraits::const_iterator<C>>(); |
892 | } |
893 | |
894 | static constexpr QMetaAssociationInterface::SetMappedAtIteratorFn getSetMappedAtIteratorFn() |
895 | { |
896 | if constexpr (QContainerTraits::can_set_mapped_at_iterator_v<C> && !std::is_const_v<C>) { |
897 | return [](const void *i, const void *m) { |
898 | *(*static_cast<const QContainerTraits::iterator<C> *>(i)) |
899 | = *static_cast<const QContainerTraits::mapped_type<C> *>(m); |
900 | }; |
901 | } else if constexpr (QContainerTraits::iterator_dereferences_to_value_v<C> |
902 | && QContainerTraits::value_type_has_second_v<C>) { |
903 | return [](const void *i, const void *m) { |
904 | (*static_cast<const QContainerTraits::iterator<C> *>(i))->second |
905 | = *static_cast<const QContainerTraits::mapped_type<C> *>(m); |
906 | }; |
907 | } else { |
908 | return nullptr; |
909 | } |
910 | } |
911 | |
912 | static constexpr QMetaAssociationInterface::EraseKeyAtIteratorFn getEraseKeyAtIteratorFn() |
913 | { |
914 | return QMetaContainerForContainer<C>::template getEraseAtIteratorFn< |
915 | QMetaAssociationInterface::EraseKeyAtIteratorFn>(); |
916 | } |
917 | }; |
918 | |
919 | } // namespace QtMetaContainerPrivate |
920 | |
921 | class Q_CORE_EXPORT QMetaContainer |
922 | { |
923 | public: |
924 | QMetaContainer() = default; |
925 | explicit QMetaContainer(const QtMetaContainerPrivate::QMetaContainerInterface *d) : d_ptr(d) {} |
926 | |
927 | bool hasInputIterator() const; |
928 | bool hasForwardIterator() const; |
929 | bool hasBidirectionalIterator() const; |
930 | bool hasRandomAccessIterator() const; |
931 | |
932 | bool hasSize() const; |
933 | qsizetype size(const void *container) const; |
934 | |
935 | bool canClear() const; |
936 | void clear(void *container) const; |
937 | |
938 | bool hasIterator() const; |
939 | void *begin(void *container) const; |
940 | void *end(void *container) const; |
941 | void destroyIterator(const void *iterator) const; |
942 | bool compareIterator(const void *i, const void *j) const; |
943 | void copyIterator(void *target, const void *source) const; |
944 | void advanceIterator(void *iterator, qsizetype step) const; |
945 | qsizetype diffIterator(const void *i, const void *j) const; |
946 | |
947 | bool hasConstIterator() const; |
948 | void *constBegin(const void *container) const; |
949 | void *constEnd(const void *container) const; |
950 | void destroyConstIterator(const void *iterator) const; |
951 | bool compareConstIterator(const void *i, const void *j) const; |
952 | void copyConstIterator(void *target, const void *source) const; |
953 | void advanceConstIterator(void *iterator, qsizetype step) const; |
954 | qsizetype diffConstIterator(const void *i, const void *j) const; |
955 | |
956 | protected: |
957 | const QtMetaContainerPrivate::QMetaContainerInterface *d_ptr = nullptr; |
958 | }; |
959 | |
960 | class Q_CORE_EXPORT QMetaSequence : public QMetaContainer |
961 | { |
962 | public: |
963 | QMetaSequence() = default; |
964 | explicit QMetaSequence(const QtMetaContainerPrivate::QMetaSequenceInterface *d) : QMetaContainer(d) {} |
965 | |
966 | template<typename T> |
967 | static constexpr QMetaSequence fromContainer() |
968 | { |
969 | return QMetaSequence(&MetaSequence<T>::value); |
970 | } |
971 | |
972 | QMetaType valueMetaType() const; |
973 | |
974 | bool isSortable() const; |
975 | bool canAddValueAtBegin() const; |
976 | void addValueAtBegin(void *container, const void *value) const; |
977 | bool canAddValueAtEnd() const; |
978 | void addValueAtEnd(void *container, const void *value) const; |
979 | bool canRemoveValueAtBegin() const; |
980 | void removeValueAtBegin(void *container) const; |
981 | bool canRemoveValueAtEnd() const; |
982 | void removeValueAtEnd(void *container) const; |
983 | |
984 | bool canGetValueAtIndex() const; |
985 | void valueAtIndex(const void *container, qsizetype index, void *result) const; |
986 | |
987 | bool canSetValueAtIndex() const; |
988 | void setValueAtIndex(void *container, qsizetype index, const void *value) const; |
989 | |
990 | bool canAddValue() const; |
991 | void addValue(void *container, const void *value) const; |
992 | |
993 | bool canRemoveValue() const; |
994 | void removeValue(void *container) const; |
995 | |
996 | bool canGetValueAtIterator() const; |
997 | void valueAtIterator(const void *iterator, void *result) const; |
998 | |
999 | bool canSetValueAtIterator() const; |
1000 | void setValueAtIterator(const void *iterator, const void *value) const; |
1001 | |
1002 | bool canInsertValueAtIterator() const; |
1003 | void insertValueAtIterator(void *container, const void *iterator, const void *value) const; |
1004 | |
1005 | bool canEraseValueAtIterator() const; |
1006 | void eraseValueAtIterator(void *container, const void *iterator) const; |
1007 | |
1008 | bool canEraseRangeAtIterator() const; |
1009 | void eraseRangeAtIterator(void *container, const void *iterator1, const void *iterator2) const; |
1010 | |
1011 | bool canGetValueAtConstIterator() const; |
1012 | void valueAtConstIterator(const void *iterator, void *result) const; |
1013 | |
1014 | friend bool operator==(const QMetaSequence &a, const QMetaSequence &b) |
1015 | { |
1016 | return a.d() == b.d(); |
1017 | } |
1018 | friend bool operator!=(const QMetaSequence &a, const QMetaSequence &b) |
1019 | { |
1020 | return a.d() != b.d(); |
1021 | } |
1022 | |
1023 | private: |
1024 | template<typename T> |
1025 | struct MetaSequence |
1026 | { |
1027 | static constexpr const QtMetaContainerPrivate::QMetaSequenceInterface value |
1028 | = QtMetaContainerPrivate::QMetaSequenceInterface( |
1029 | QtMetaContainerPrivate::QMetaSequenceForContainer<T>()); |
1030 | }; |
1031 | |
1032 | const QtMetaContainerPrivate::QMetaSequenceInterface *d() const |
1033 | { |
1034 | return static_cast<const QtMetaContainerPrivate::QMetaSequenceInterface *>(d_ptr); |
1035 | } |
1036 | }; |
1037 | |
1038 | class Q_CORE_EXPORT QMetaAssociation : public QMetaContainer |
1039 | { |
1040 | public: |
1041 | QMetaAssociation() = default; |
1042 | explicit QMetaAssociation(const QtMetaContainerPrivate::QMetaAssociationInterface *d) : QMetaContainer(d) {} |
1043 | |
1044 | template<typename T> |
1045 | static constexpr QMetaAssociation fromContainer() |
1046 | { |
1047 | return QMetaAssociation(&MetaAssociation<T>::value); |
1048 | } |
1049 | |
1050 | QMetaType keyMetaType() const; |
1051 | QMetaType mappedMetaType() const; |
1052 | |
1053 | bool canInsertKey() const |
1054 | { |
1055 | if (auto iface = d()) |
1056 | return iface->insertKeyFn; |
1057 | return false; |
1058 | } |
1059 | void insertKey(void *container, const void *key) const |
1060 | { |
1061 | if (canInsertKey()) |
1062 | d()->insertKeyFn(container, key); |
1063 | } |
1064 | |
1065 | bool canRemoveKey() const |
1066 | { |
1067 | if (auto iface = d()) |
1068 | return iface->removeKeyFn; |
1069 | return false; |
1070 | } |
1071 | void removeKey(void *container, const void *key) const |
1072 | { |
1073 | if (canRemoveKey()) |
1074 | d()->removeKeyFn(container, key); |
1075 | } |
1076 | |
1077 | bool canContainsKey() const |
1078 | { |
1079 | if (auto iface = d()) |
1080 | return iface->containsKeyFn; |
1081 | return false; |
1082 | } |
1083 | bool containsKey(const void *container, const void *key) const |
1084 | { |
1085 | if (canContainsKey()) |
1086 | return d()->containsKeyFn(container, key); |
1087 | return false; |
1088 | } |
1089 | |
1090 | |
1091 | bool canGetMappedAtKey() const |
1092 | { |
1093 | if (auto iface = d()) |
1094 | return iface->mappedAtKeyFn; |
1095 | return false; |
1096 | } |
1097 | void mappedAtKey(const void *container, const void *key, void *mapped) const |
1098 | { |
1099 | if (canGetMappedAtKey()) |
1100 | d()->mappedAtKeyFn(container, key, mapped); |
1101 | } |
1102 | |
1103 | bool canSetMappedAtKey() const |
1104 | { |
1105 | if (auto iface = d()) |
1106 | return iface->setMappedAtKeyFn; |
1107 | return false; |
1108 | } |
1109 | void setMappedAtKey(void *container, const void *key, const void *mapped) const |
1110 | { |
1111 | if (canSetMappedAtKey()) |
1112 | d()->setMappedAtKeyFn(container, key, mapped); |
1113 | } |
1114 | |
1115 | bool canGetKeyAtIterator() const |
1116 | { |
1117 | if (auto iface = d()) |
1118 | return iface->keyAtIteratorFn; |
1119 | return false; |
1120 | } |
1121 | |
1122 | void keyAtIterator(const void *iterator, void *key) const |
1123 | { |
1124 | if (canGetKeyAtIterator()) |
1125 | d()->keyAtIteratorFn(iterator, key); |
1126 | } |
1127 | |
1128 | bool canGetKeyAtConstIterator() const |
1129 | { |
1130 | if (auto iface = d()) |
1131 | return iface->keyAtConstIteratorFn; |
1132 | return false; |
1133 | } |
1134 | |
1135 | void keyAtConstIterator(const void *iterator, void *key) const |
1136 | { |
1137 | if (canGetKeyAtConstIterator()) |
1138 | d()->keyAtConstIteratorFn(iterator, key); |
1139 | } |
1140 | |
1141 | bool canGetMappedAtIterator() const |
1142 | { |
1143 | if (auto iface = d()) |
1144 | return iface->mappedAtIteratorFn; |
1145 | return false; |
1146 | } |
1147 | |
1148 | void mappedAtIterator(const void *iterator, void *mapped) const |
1149 | { |
1150 | if (canGetMappedAtIterator()) |
1151 | d()->mappedAtIteratorFn(iterator, mapped); |
1152 | } |
1153 | |
1154 | bool canGetMappedAtConstIterator() const |
1155 | { |
1156 | if (auto iface = d()) |
1157 | return iface->mappedAtConstIteratorFn; |
1158 | return false; |
1159 | } |
1160 | |
1161 | void mappedAtConstIterator(const void *iterator, void *mapped) const |
1162 | { |
1163 | if (canGetMappedAtConstIterator()) |
1164 | d()->mappedAtConstIteratorFn(iterator, mapped); |
1165 | } |
1166 | |
1167 | bool canSetMappedAtIterator() const |
1168 | { |
1169 | if (auto iface = d()) |
1170 | return iface->setMappedAtIteratorFn; |
1171 | return false; |
1172 | } |
1173 | |
1174 | void setMappedAtIterator(const void *iterator, const void *mapped) const |
1175 | { |
1176 | if (canSetMappedAtIterator()) |
1177 | d()->setMappedAtIteratorFn(iterator, mapped); |
1178 | } |
1179 | |
1180 | bool canCreateIteratorAtKey() const |
1181 | { |
1182 | if (auto iface = d()) |
1183 | return iface->createIteratorAtKeyFn; |
1184 | return false; |
1185 | } |
1186 | |
1187 | void *createIteratorAtKey(void *container, const void *key) const |
1188 | { |
1189 | if (canCreateIteratorAtKey()) |
1190 | return d()->createIteratorAtKeyFn(container, key); |
1191 | return nullptr; |
1192 | } |
1193 | |
1194 | bool canCreateConstIteratorAtKey() const |
1195 | { |
1196 | if (auto iface = d()) |
1197 | return iface->createConstIteratorAtKeyFn; |
1198 | return false; |
1199 | } |
1200 | |
1201 | void *createConstIteratorAtKey(const void *container, const void *key) const |
1202 | { |
1203 | if (canCreateConstIteratorAtKey()) |
1204 | return d()->createConstIteratorAtKeyFn(container, key); |
1205 | return nullptr; |
1206 | } |
1207 | |
1208 | friend bool operator==(const QMetaAssociation &a, const QMetaAssociation &b) |
1209 | { |
1210 | return a.d() == b.d(); |
1211 | } |
1212 | friend bool operator!=(const QMetaAssociation &a, const QMetaAssociation &b) |
1213 | { |
1214 | return a.d() != b.d(); |
1215 | } |
1216 | |
1217 | private: |
1218 | template<typename T> |
1219 | struct MetaAssociation |
1220 | { |
1221 | static constexpr const QtMetaContainerPrivate::QMetaAssociationInterface value |
1222 | = QtMetaContainerPrivate::QMetaAssociationInterface( |
1223 | QtMetaContainerPrivate::QMetaAssociationForContainer<T>()); |
1224 | }; |
1225 | |
1226 | const QtMetaContainerPrivate::QMetaAssociationInterface *d() const |
1227 | { |
1228 | return static_cast<const QtMetaContainerPrivate::QMetaAssociationInterface *>(d_ptr); |
1229 | } |
1230 | }; |
1231 | |
1232 | QT_END_NAMESPACE |
1233 | |
1234 | #endif // QMETACONTAINER_H |
1235 | |