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