123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197 | // Copyright (C) 2020 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QMETACONTAINER_H#define QMETACONTAINER_H#include <QtCore/qcontainerinfo.h>#include <QtCore/qcompare.h>#include <QtCore/qflags.h>#include <QtCore/qglobal.h>#include <iterator> QT_BEGIN_NAMESPACE class QMetaType;namespace QtPrivate {class QMetaTypeInterface;template<typename T>constexprconst QMetaTypeInterface *qMetaTypeInterfaceForType();}namespace QtMetaContainerPrivate {enum IteratorCapability : quint8 { InputCapability =1<<0, ForwardCapability =1<<1, BiDirectionalCapability =1<<2, RandomAccessCapability =1<<3,};Q_DECLARE_FLAGS(IteratorCapabilities, IteratorCapability)Q_DECLARE_OPERATORS_FOR_FLAGS(IteratorCapabilities)enum AddRemoveCapability : quint8 { CanAddAtBegin =1<<0, CanRemoveAtBegin =1<<1, CanAddAtEnd =1<<2, CanRemoveAtEnd =1<<3};Q_DECLARE_FLAGS(AddRemoveCapabilities, AddRemoveCapability)Q_DECLARE_OPERATORS_FOR_FLAGS(AddRemoveCapabilities)class QMetaContainerInterface {public:enum Position : quint8 { AtBegin, AtEnd, Unspecified }; ushort revision =0; IteratorCapabilities iteratorCapabilities;using SizeFn =qsizetype(*)(const void*); SizeFn sizeFn;using ClearFn =void(*)(void*); ClearFn clearFn;using CreateIteratorFn =void*(*)(void*, Position); CreateIteratorFn createIteratorFn;using DestroyIteratorFn =void(*)(const void*); DestroyIteratorFn destroyIteratorFn;using CompareIteratorFn =bool(*)(const void*,const void*); CompareIteratorFn compareIteratorFn;using CopyIteratorFn =void(*)(void*,const void*); CopyIteratorFn copyIteratorFn;using AdvanceIteratorFn =void(*)(void*, qsizetype); AdvanceIteratorFn advanceIteratorFn;using DiffIteratorFn =qsizetype(*)(const void*,const void*); DiffIteratorFn diffIteratorFn;using CreateConstIteratorFn =void*(*)(const void*, Position); CreateConstIteratorFn createConstIteratorFn; DestroyIteratorFn destroyConstIteratorFn; CompareIteratorFn compareConstIteratorFn; CopyIteratorFn copyConstIteratorFn; AdvanceIteratorFn advanceConstIteratorFn; DiffIteratorFn diffConstIteratorFn;QMetaContainerInterface() =default;template<typename MetaContainer>constexprQMetaContainerInterface(const MetaContainer &):iteratorCapabilities(MetaContainer::getIteratorCapabilities()),sizeFn(MetaContainer::getSizeFn()),clearFn(MetaContainer::getClearFn()),createIteratorFn(MetaContainer::getCreateIteratorFn()),destroyIteratorFn(MetaContainer::getDestroyIteratorFn()),compareIteratorFn(MetaContainer::getCompareIteratorFn()),copyIteratorFn(MetaContainer::getCopyIteratorFn()),advanceIteratorFn(MetaContainer::getAdvanceIteratorFn()),diffIteratorFn(MetaContainer::getDiffIteratorFn()),createConstIteratorFn(MetaContainer::getCreateConstIteratorFn()),destroyConstIteratorFn(MetaContainer::getDestroyConstIteratorFn()),compareConstIteratorFn(MetaContainer::getCompareConstIteratorFn()),copyConstIteratorFn(MetaContainer::getCopyConstIteratorFn()),advanceConstIteratorFn(MetaContainer::getAdvanceConstIteratorFn()),diffConstIteratorFn(MetaContainer::getDiffConstIteratorFn()){}};class QMetaSequenceInterface :public QMetaContainerInterface {public:constQtPrivate::QMetaTypeInterface *valueMetaType; AddRemoveCapabilities addRemoveCapabilities;using ValueAtIndexFn =void(*)(const void*, qsizetype,void*); ValueAtIndexFn valueAtIndexFn;using SetValueAtIndexFn =void(*)(void*, qsizetype,const void*); SetValueAtIndexFn setValueAtIndexFn;using AddValueFn =void(*)(void*,const void*, Position); AddValueFn addValueFn;using RemoveValueFn =void(*)(void*, Position); RemoveValueFn removeValueFn;using ValueAtIteratorFn =void(*)(const void*,void*); ValueAtIteratorFn valueAtIteratorFn;using SetValueAtIteratorFn =void(*)(const void*,const void*); SetValueAtIteratorFn setValueAtIteratorFn;using InsertValueAtIteratorFn =void(*)(void*,const void*,const void*); InsertValueAtIteratorFn insertValueAtIteratorFn; ValueAtIteratorFn valueAtConstIteratorFn;using EraseValueAtIteratorFn =void(*)(void*,const void*); EraseValueAtIteratorFn eraseValueAtIteratorFn;using EraseRangeAtIteratorFn =void(*)(void*,const void*,const void*); EraseRangeAtIteratorFn eraseRangeAtIteratorFn;QMetaSequenceInterface() =default;template<typename MetaSequence>constexprQMetaSequenceInterface(const MetaSequence &m):QMetaContainerInterface(m),valueMetaType(MetaSequence::getValueMetaType()),addRemoveCapabilities(MetaSequence::getAddRemoveCapabilities()),valueAtIndexFn(MetaSequence::getValueAtIndexFn()),setValueAtIndexFn(MetaSequence::getSetValueAtIndexFn()),addValueFn(MetaSequence::getAddValueFn()),removeValueFn(MetaSequence::getRemoveValueFn()),valueAtIteratorFn(MetaSequence::getValueAtIteratorFn()),setValueAtIteratorFn(MetaSequence::getSetValueAtIteratorFn()),insertValueAtIteratorFn(MetaSequence::getInsertValueAtIteratorFn()),valueAtConstIteratorFn(MetaSequence::getValueAtConstIteratorFn()),eraseValueAtIteratorFn(MetaSequence::getEraseValueAtIteratorFn()),eraseRangeAtIteratorFn(MetaSequence::getEraseRangeAtIteratorFn()){}};class QMetaAssociationInterface :public QMetaContainerInterface {public:constQtPrivate::QMetaTypeInterface *keyMetaType;constQtPrivate::QMetaTypeInterface *mappedMetaType;using InsertKeyFn =void(*)(void*,const void*); InsertKeyFn insertKeyFn;using RemoveKeyFn =void(*)(void*,const void*); RemoveKeyFn removeKeyFn;using ContainsKeyFn =bool(*)(const void*,const void*); ContainsKeyFn containsKeyFn;using MappedAtKeyFn =void(*)(const void*,const void*,void*); MappedAtKeyFn mappedAtKeyFn;using SetMappedAtKeyFn =void(*)(void*,const void*,const void*); SetMappedAtKeyFn setMappedAtKeyFn;using CreateIteratorAtKeyFn =void*(*)(void*,const void*); CreateIteratorAtKeyFn createIteratorAtKeyFn;using CreateConstIteratorAtKeyFn =void*(*)(const void*,const void*); CreateConstIteratorAtKeyFn createConstIteratorAtKeyFn;using KeyAtIteratorFn =void(*)(const void*,void*); KeyAtIteratorFn keyAtIteratorFn; KeyAtIteratorFn keyAtConstIteratorFn;using MappedAtIteratorFn =void(*)(const void*,void*); MappedAtIteratorFn mappedAtIteratorFn; MappedAtIteratorFn mappedAtConstIteratorFn;using SetMappedAtIteratorFn =void(*)(const void*,const void*); SetMappedAtIteratorFn setMappedAtIteratorFn;using EraseKeyAtIteratorFn =void(*)(void*,const void*); EraseKeyAtIteratorFn eraseKeyAtIteratorFn;QMetaAssociationInterface() =default;template<typename MetaAssociation>constexprQMetaAssociationInterface(const MetaAssociation &m):QMetaContainerInterface(m),keyMetaType(MetaAssociation::getKeyMetaType()),mappedMetaType(MetaAssociation::getMappedMetaType()),insertKeyFn(MetaAssociation::getInsertKeyFn()),removeKeyFn(MetaAssociation::getRemoveKeyFn()),containsKeyFn(MetaAssociation::getContainsKeyFn()),mappedAtKeyFn(MetaAssociation::getMappedAtKeyFn()),setMappedAtKeyFn(MetaAssociation::getSetMappedAtKeyFn()),createIteratorAtKeyFn(MetaAssociation::createIteratorAtKeyFn()),createConstIteratorAtKeyFn(MetaAssociation::createConstIteratorAtKeyFn()),keyAtIteratorFn(MetaAssociation::getKeyAtIteratorFn()),keyAtConstIteratorFn(MetaAssociation::getKeyAtConstIteratorFn()),mappedAtIteratorFn(MetaAssociation::getMappedAtIteratorFn()),mappedAtConstIteratorFn(MetaAssociation::getMappedAtConstIteratorFn()),setMappedAtIteratorFn(MetaAssociation::getSetMappedAtIteratorFn()),eraseKeyAtIteratorFn(MetaAssociation::getEraseKeyAtIteratorFn()){}};template<typename C>class QMetaContainerForContainer {friend QMetaContainerInterface;template<typename Iterator>staticconstexpr IteratorCapabilities capabilitiesForIterator(){using Tag = typename std::iterator_traits<Iterator>::iterator_category; IteratorCapabilities caps {};ifconstexpr(std::is_base_of_v<std::input_iterator_tag, Tag>) caps |= InputCapability;ifconstexpr(std::is_base_of_v<std::forward_iterator_tag, Tag>) caps |= ForwardCapability;ifconstexpr(std::is_base_of_v<std::bidirectional_iterator_tag, Tag>) caps |= BiDirectionalCapability;ifconstexpr(std::is_base_of_v<std::random_access_iterator_tag, Tag>) caps |= RandomAccessCapability;return caps;}staticconstexpr IteratorCapabilities getIteratorCapabilities(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>)return capabilitiesForIterator<QContainerInfo::iterator<C>>();else ifconstexpr(QContainerInfo::has_const_iterator_v<C>)return capabilitiesForIterator<QContainerInfo::const_iterator<C>>();elsereturn{};}staticconstexpr QMetaContainerInterface::SizeFn getSizeFn(){ifconstexpr(QContainerInfo::has_size_v<C>) {return[](const void*c) -> qsizetype {return static_cast<const C *>(c)->size(); };}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::ClearFn getClearFn(){ifconstexpr(QContainerInfo::has_clear_v<C>) {return[](void*c) {return static_cast<C *>(c)->clear(); };}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CreateIteratorFn getCreateIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](void*c,QMetaContainerInterface::Position p) ->void* {using Iterator =QContainerInfo::iterator<C>;switch(p) {caseQMetaContainerInterface::Unspecified:return new Iterator;caseQMetaContainerInterface::AtBegin:return newIterator(static_cast<C *>(c)->begin());caseQMetaContainerInterface::AtEnd:return newIterator(static_cast<C *>(c)->end());}returnnullptr;};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::DestroyIteratorFn getDestroyIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](const void*i) {using Iterator =QContainerInfo::iterator<C>;delete static_cast<const Iterator *>(i);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CompareIteratorFn getCompareIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](const void*i,const void*j) {using Iterator =QContainerInfo::iterator<C>;return*static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CopyIteratorFn getCopyIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](void*i,const void*j) {using Iterator =QContainerInfo::iterator<C>;*static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](void*i, qsizetype step) {std::advance(*static_cast<QContainerInfo::iterator<C> *>(i), step);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::DiffIteratorFn getDiffIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C> && !std::is_const_v<C>) {return[](const void*i,const void*j) -> qsizetype {returnstd::distance(*static_cast<constQContainerInfo::iterator<C> *>(j),*static_cast<constQContainerInfo::iterator<C> *>(i));};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CreateConstIteratorFn getCreateConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](const void*c,QMetaContainerInterface::Position p) ->void* {using Iterator =QContainerInfo::const_iterator<C>;switch(p) {caseQMetaContainerInterface::Unspecified:return new Iterator;caseQMetaContainerInterface::AtBegin:return newIterator(static_cast<const C *>(c)->begin());caseQMetaContainerInterface::AtEnd:return newIterator(static_cast<const C *>(c)->end());}returnnullptr;};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::DestroyIteratorFn getDestroyConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](const void*i) {using Iterator =QContainerInfo::const_iterator<C>;delete static_cast<const Iterator *>(i);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CompareIteratorFn getCompareConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](const void*i,const void*j) {using Iterator =QContainerInfo::const_iterator<C>;return*static_cast<const Iterator *>(i) == *static_cast<const Iterator *>(j);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::CopyIteratorFn getCopyConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](void*i,const void*j) {using Iterator =QContainerInfo::const_iterator<C>;*static_cast<Iterator *>(i) = *static_cast<const Iterator *>(j);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::AdvanceIteratorFn getAdvanceConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](void*i, qsizetype step) {std::advance(*static_cast<QContainerInfo::const_iterator<C> *>(i), step);};}else{returnnullptr;}}staticconstexpr QMetaContainerInterface::DiffIteratorFn getDiffConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>) {return[](const void*i,const void*j) -> qsizetype {returnstd::distance(*static_cast<constQContainerInfo::const_iterator<C> *>(j),*static_cast<constQContainerInfo::const_iterator<C> *>(i));};}else{returnnullptr;}}protected:template<typename EraseFn>staticconstexpr EraseFn getEraseAtIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C>&&QContainerInfo::can_erase_at_iterator_v<C> && !std::is_const_v<C>) {return[](void*c,const void*i) {static_cast<C *>(c)->erase(*static_cast<constQContainerInfo::iterator<C> *>(i));};}else{returnnullptr;}}};template<typename C>class QMetaSequenceForContainer :public QMetaContainerForContainer<C>{friend QMetaSequenceInterface;staticconstexprconstQtPrivate::QMetaTypeInterface *getValueMetaType(){ifconstexpr(QContainerInfo::has_value_type_v<C>)returnQtPrivate::qMetaTypeInterfaceForType<typename C::value_type>();elsereturnnullptr;}staticconstexpr AddRemoveCapabilities getAddRemoveCapabilities(){ AddRemoveCapabilities caps;ifconstexpr(QContainerInfo::has_push_back_v<C>) caps |= CanAddAtEnd;ifconstexpr(QContainerInfo::has_pop_back_v<C>) caps |= CanRemoveAtEnd;ifconstexpr(QContainerInfo::has_push_front_v<C>) caps |= CanAddAtBegin;ifconstexpr(QContainerInfo::has_pop_front_v<C>) caps |= CanRemoveAtBegin;return caps;}staticconstexpr QMetaSequenceInterface::ValueAtIndexFn getValueAtIndexFn(){ifconstexpr(QContainerInfo::has_at_index_v<C>) {return[](const void*c, qsizetype i,void*r) {*static_cast<QContainerInfo::value_type<C> *>(r)=static_cast<const C *>(c)->at(i);};}else ifconstexpr(QContainerInfo::can_get_at_index_v<C>) {return[](const void*c, qsizetype i,void*r) {*static_cast<QContainerInfo::value_type<C> *>(r)= (*static_cast<const C *>(c))[i];};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::SetValueAtIndexFn getSetValueAtIndexFn(){ifconstexpr(QContainerInfo::can_set_at_index_v<C>) {return[](void*c, qsizetype i,const void*e) {(*static_cast<C *>(c))[i]= *static_cast<constQContainerInfo::value_type<C> *>(e);};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::AddValueFn getAddValueFn(){ifconstexpr(QContainerInfo::has_push_back_v<C>) {ifconstexpr(QContainerInfo::has_push_front_v<C>) {return[](void*c,const void*v,QMetaSequenceInterface::Position position) {constauto&value = *static_cast<constQContainerInfo::value_type<C> *>(v);switch(position) {caseQMetaSequenceInterface::AtBegin:static_cast<C *>(c)->push_front(value);break;caseQMetaSequenceInterface::AtEnd:caseQMetaSequenceInterface::Unspecified:static_cast<C *>(c)->push_back(value);break;}};}else{return[](void*c,const void*v,QMetaSequenceInterface::Position position) {constauto&value = *static_cast<constQContainerInfo::value_type<C> *>(v);switch(position) {caseQMetaSequenceInterface::AtBegin:break;caseQMetaSequenceInterface::AtEnd:caseQMetaSequenceInterface::Unspecified:static_cast<C *>(c)->push_back(value);break;}};}}else ifconstexpr(QContainerInfo::has_push_front_v<C>) {return[](void*c,const void*v,QMetaSequenceInterface::Position position) {constauto&value = *static_cast<constQContainerInfo::value_type<C> *>(v);switch(position) {caseQMetaSequenceInterface::Unspecified:caseQMetaSequenceInterface::AtBegin:static_cast<C *>(c)->push_front(value);caseQMetaSequenceInterface::AtEnd:break;}};}else ifconstexpr(QContainerInfo::has_insert_v<C>) {return[](void*c,const void*v,QMetaSequenceInterface::Position position) {if(position ==QMetaSequenceInterface::Unspecified) {static_cast<C *>(c)->insert(*static_cast<constQContainerInfo::value_type<C> *>(v));}};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::RemoveValueFn getRemoveValueFn(){ifconstexpr(QContainerInfo::has_pop_back_v<C>) {ifconstexpr(QContainerInfo::has_pop_front_v<C>) {return[](void*c,QMetaSequenceInterface::Position position) {switch(position) {caseQMetaSequenceInterface::AtBegin:static_cast<C *>(c)->pop_front();break;caseQMetaSequenceInterface::AtEnd:caseQMetaSequenceInterface::Unspecified:static_cast<C *>(c)->pop_back();break;}};}else{return[](void*c,QMetaSequenceInterface::Position position) {switch(position) {caseQMetaSequenceInterface::AtBegin:break;caseQMetaSequenceInterface::Unspecified:caseQMetaSequenceInterface::AtEnd:static_cast<C *>(c)->pop_back();break;}};}}else ifconstexpr(QContainerInfo::has_pop_front_v<C>) {return[](void*c,QMetaSequenceInterface::Position position) {switch(position) {caseQMetaSequenceInterface::Unspecified:caseQMetaSequenceInterface::AtBegin:static_cast<C *>(c)->pop_front();break;caseQMetaSequenceInterface::AtEnd:break;}};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C>&&QContainerInfo::iterator_dereferences_to_value_v<C> && !std::is_const_v<C>) {return[](const void*i,void*r) {*static_cast<QContainerInfo::value_type<C> *>(r) =*(*static_cast<constQContainerInfo::iterator<C> *>(i));};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::SetValueAtIteratorFn getSetValueAtIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C>&&QContainerInfo::can_set_value_at_iterator_v<C> && !std::is_const_v<C>) {return[](const void*i,const void*e) {*(*static_cast<constQContainerInfo::iterator<C> *>(i))= *static_cast<constQContainerInfo::value_type<C> *>(e);};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::InsertValueAtIteratorFn getInsertValueAtIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C>&&QContainerInfo::can_insert_value_at_iterator_v<C> && !std::is_const_v<C>) {return[](void*c,const void*i,const void*e) {static_cast<C *>(c)->insert(*static_cast<constQContainerInfo::iterator<C> *>(i),*static_cast<constQContainerInfo::value_type<C> *>(e));};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::ValueAtIteratorFn getValueAtConstIteratorFn(){ifconstexpr(QContainerInfo::has_const_iterator_v<C>&&QContainerInfo::iterator_dereferences_to_value_v<C>) {return[](const void*i,void*r) {*static_cast<QContainerInfo::value_type<C> *>(r) =*(*static_cast<constQContainerInfo::const_iterator<C> *>(i));};}else{returnnullptr;}}staticconstexpr QMetaSequenceInterface::EraseValueAtIteratorFn getEraseValueAtIteratorFn(){return QMetaContainerForContainer<C>::template getEraseAtIteratorFn<QMetaSequenceInterface::EraseValueAtIteratorFn>();}staticconstexpr QMetaSequenceInterface::EraseRangeAtIteratorFn getEraseRangeAtIteratorFn(){ifconstexpr(QContainerInfo::has_iterator_v<C>&&QContainerInfo::can_erase_range_at_iterator_v<C> && !std::is_const_v<C>) {return[](void*c,const void*i,const void*j) {static_cast<C *>(c)->erase(*static_cast<constQContainerInfo::iterator<C> *>(i),*static_cast<constQContainerInfo::iterator<C> *>(j));};}else{returnnullptr;}}};template<typename C>class QMetaAssociationForContainer :public QMetaContainerForContainer<C>{friend QMetaAssociationInterface;staticconstexprconstQtPrivate::QMetaTypeInterface *getKeyMetaType(){ifconstexpr(QContainerInfo::has_key_type_v<C>)returnQtPrivate::qMetaTypeInterfaceForType<typename C::key_type>();elsereturnnullptr;}staticconstexprconstQtPrivate::QMetaTypeInterface *getMappedMetaType(){ifconstexpr(QContainerInfo::has_mapped_type_v<C>)returnQtPrivate::qMetaTypeInterfaceForType<typename C::mapped_type>();elsereturnnullptr;}staticconstexpr QMetaAssociationInterface::InsertKeyFn getInsertKeyFn(){ifconstexpr(QContainerInfo::can_insert_key_v<C>) {return[](void*c,const void*k) {static_cast<C *>(c)->insert(*static_cast<constQContainerInfo::key_type<C> *>(k));};}else ifconstexpr(QContainerInfo::can_insert_pair_v<C>) {return[](void*c,const void*k) {static_cast<C *>(c)->insert({*static_cast<constQContainerInfo::key_type<C> *>(k), {}});};}else ifconstexpr(QContainerInfo::can_insert_key_mapped_v<C>) {return[](void*c,const void*k) {static_cast<C *>(c)->insert(*static_cast<constQContainerInfo::key_type<C> *>(k), {});};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::RemoveKeyFn getRemoveKeyFn(){ifconstexpr(QContainerInfo::can_erase_at_key_v<C>) {return[](void*c,const void*k) {static_cast<C *>(c)->erase(*static_cast<constQContainerInfo::key_type<C> *>(k));};}else ifconstexpr(QContainerInfo::can_remove_at_key_v<C>) {return[](void*c,const void*k) {static_cast<C *>(c)->remove(*static_cast<constQContainerInfo::key_type<C> *>(k));};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::ContainsKeyFn getContainsKeyFn(){ifconstexpr(QContainerInfo::has_contains_v<C>) {return[](const void*c,const void*k) {return static_cast<const C *>(c)->contains(*static_cast<constQContainerInfo::key_type<C> *>(k));};}else if(QContainerInfo::has_find_v<C>) {return[](const void*c,const void*k) {const C *container =static_cast<const C *>(c);return container->find(*static_cast<constQContainerInfo::key_type<C> *>(k))!= container->end();};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::MappedAtKeyFn getMappedAtKeyFn(){ifconstexpr(QContainerInfo::has_at_key_v<C>) {return[](const void*c,const void*k,void*r) {*static_cast<QContainerInfo::mapped_type<C> *>(r)=static_cast<const C *>(c)->at(*static_cast<constQContainerInfo::key_type<C> *>(k));};}else ifconstexpr(QContainerInfo::can_get_at_key_v<C>) {return[](const void*c,const void*k,void*r) {*static_cast<QContainerInfo::mapped_type<C> *>(r)= (*static_cast<const C *>(c))[*static_cast<constQContainerInfo::key_type<C> *>(k)];};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::SetMappedAtKeyFn getSetMappedAtKeyFn(){ifconstexpr(QContainerInfo::can_set_at_key_v<C>) {return[](void*c,const void*k,const void*m) {(*static_cast<C *>(c))[*static_cast<constQContainerInfo::key_type<C> *>(k)] =*static_cast<constQContainerInfo::mapped_type<C> *>(m);};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::CreateIteratorAtKeyFn createIteratorAtKeyFn(){ifconstexpr(QContainerInfo::has_find_v<C>) {return[](void*c,const void*k) ->void* {using Iterator =QContainerInfo::iterator<C>;return newIterator(static_cast<C *>(c)->find(*static_cast<constQContainerInfo::key_type<C> *>(k)));};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::CreateConstIteratorAtKeyFn createConstIteratorAtKeyFn(){ifconstexpr(QContainerInfo::has_find_v<C>) {return[](const void*c,const void*k) ->void* {using Iterator =QContainerInfo::const_iterator<C>;return newIterator(static_cast<const C *>(c)->find(*static_cast<constQContainerInfo::key_type<C> *>(k)));};}else{returnnullptr;}}template<typename Iterator>staticconstexpr QMetaAssociationInterface::KeyAtIteratorFn keyAtIteratorFn(){ifconstexpr(QContainerInfo::iterator_has_key_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::key_type<C> *>(k)=static_cast<const Iterator *>(i)->key();};}else ifconstexpr(QContainerInfo::iterator_dereferences_to_value_v<C>&&QContainerInfo::value_type_has_first_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::key_type<C> *>(k)= (*static_cast<const Iterator *>(i))->first;};}else ifconstexpr(QContainerInfo::iterator_dereferences_to_key_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::key_type<C> *>(k)= *(*static_cast<const Iterator *>(i));};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtIteratorFn(){return keyAtIteratorFn<QContainerInfo::iterator<C>>();}staticconstexpr QMetaAssociationInterface::KeyAtIteratorFn getKeyAtConstIteratorFn(){return keyAtIteratorFn<QContainerInfo::const_iterator<C>>();}template<typename Iterator>staticconstexpr QMetaAssociationInterface::MappedAtIteratorFn mappedAtIteratorFn(){ifconstexpr(QContainerInfo::iterator_has_value_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::mapped_type<C> *>(k)=static_cast<const Iterator *>(i)->value();};}else ifconstexpr(QContainerInfo::iterator_dereferences_to_value_v<C>&&QContainerInfo::value_type_has_second_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::mapped_type<C> *>(k)= (*static_cast<const Iterator *>(i))->second;};}else ifconstexpr(QContainerInfo::iterator_dereferences_to_mapped_v<C>) {return[](const void*i,void*k) {*static_cast<QContainerInfo::mapped_type<C> *>(k)= *static_cast<const Iterator *>(i);};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtIteratorFn(){return mappedAtIteratorFn<QContainerInfo::iterator<C>>();}staticconstexpr QMetaAssociationInterface::MappedAtIteratorFn getMappedAtConstIteratorFn(){return mappedAtIteratorFn<QContainerInfo::const_iterator<C>>();}staticconstexpr QMetaAssociationInterface::SetMappedAtIteratorFn getSetMappedAtIteratorFn(){ifconstexpr(QContainerInfo::can_set_mapped_at_iterator_v<C> && !std::is_const_v<C>) {return[](const void*i,const void*m) {*(*static_cast<constQContainerInfo::iterator<C> *>(i))= *static_cast<constQContainerInfo::mapped_type<C> *>(m);};}else ifconstexpr(QContainerInfo::iterator_dereferences_to_value_v<C>&&QContainerInfo::value_type_has_second_v<C>) {return[](const void*i,const void*m) {(*static_cast<constQContainerInfo::iterator<C> *>(i))->second = *static_cast<constQContainerInfo::mapped_type<C> *>(m);};}else{returnnullptr;}}staticconstexpr QMetaAssociationInterface::EraseKeyAtIteratorFn getEraseKeyAtIteratorFn(){return QMetaContainerForContainer<C>::template getEraseAtIteratorFn<QMetaAssociationInterface::EraseKeyAtIteratorFn>();}};}// namespace QtMetaContainerPrivateclass Q_CORE_EXPORT QMetaContainer {public:QMetaContainer() =default;explicitQMetaContainer(constQtMetaContainerPrivate::QMetaContainerInterface *d) :d_ptr(d) {}boolhasInputIterator()const;boolhasForwardIterator()const;boolhasBidirectionalIterator()const;boolhasRandomAccessIterator()const;boolhasSize()const; qsizetype size(const void*container)const;boolcanClear()const;voidclear(void*container)const;boolhasIterator()const;void*begin(void*container)const;void*end(void*container)const;voiddestroyIterator(const void*iterator)const;boolcompareIterator(const void*i,const void*j)const;voidcopyIterator(void*target,const void*source)const;voidadvanceIterator(void*iterator, qsizetype step)const; qsizetype diffIterator(const void*i,const void*j)const;boolhasConstIterator()const;void*constBegin(const void*container)const;void*constEnd(const void*container)const;voiddestroyConstIterator(const void*iterator)const;boolcompareConstIterator(const void*i,const void*j)const;voidcopyConstIterator(void*target,const void*source)const;voidadvanceConstIterator(void*iterator, qsizetype step)const; qsizetype diffConstIterator(const void*i,const void*j)const;protected:constQtMetaContainerPrivate::QMetaContainerInterface *d_ptr =nullptr;};class Q_CORE_EXPORT QMetaSequence :public QMetaContainer {public:QMetaSequence() =default;explicitQMetaSequence(constQtMetaContainerPrivate::QMetaSequenceInterface *d) :QMetaContainer(d) {}template<typename T>staticconstexpr QMetaSequence fromContainer(){returnQMetaSequence(&MetaSequence<T>::value);} QMetaType valueMetaType()const;boolisSortable()const;boolcanAddValueAtBegin()const;voidaddValueAtBegin(void*container,const void*value)const;boolcanAddValueAtEnd()const;voidaddValueAtEnd(void*container,const void*value)const;boolcanRemoveValueAtBegin()const;voidremoveValueAtBegin(void*container)const;boolcanRemoveValueAtEnd()const;voidremoveValueAtEnd(void*container)const;boolcanGetValueAtIndex()const;voidvalueAtIndex(const void*container, qsizetype index,void*result)const;boolcanSetValueAtIndex()const;voidsetValueAtIndex(void*container, qsizetype index,const void*value)const;boolcanAddValue()const;voidaddValue(void*container,const void*value)const;boolcanRemoveValue()const;voidremoveValue(void*container)const;boolcanGetValueAtIterator()const;voidvalueAtIterator(const void*iterator,void*result)const;boolcanSetValueAtIterator()const;voidsetValueAtIterator(const void*iterator,const void*value)const;boolcanInsertValueAtIterator()const;voidinsertValueAtIterator(void*container,const void*iterator,const void*value)const;boolcanEraseValueAtIterator()const;voideraseValueAtIterator(void*container,const void*iterator)const;boolcanEraseRangeAtIterator()const;voideraseRangeAtIterator(void*container,const void*iterator1,const void*iterator2)const;boolcanGetValueAtConstIterator()const;voidvalueAtConstIterator(const void*iterator,void*result)const;constQtMetaContainerPrivate::QMetaSequenceInterface *iface()const{returnd(); }private:friendboolcomparesEqual(const QMetaSequence &lhs,const QMetaSequence &rhs) noexcept {return lhs.d() == rhs.d();}Q_DECLARE_EQUALITY_COMPARABLE(QMetaSequence)template<typename T>struct MetaSequence {staticconstexprconstQtMetaContainerPrivate::QMetaSequenceInterface value =QtMetaContainerPrivate::QMetaSequenceInterface(QtMetaContainerPrivate::QMetaSequenceForContainer<T>());};constQtMetaContainerPrivate::QMetaSequenceInterface *d()const{return static_cast<constQtMetaContainerPrivate::QMetaSequenceInterface *>(d_ptr);}};class Q_CORE_EXPORT QMetaAssociation :public QMetaContainer {public:QMetaAssociation() =default;explicitQMetaAssociation(constQtMetaContainerPrivate::QMetaAssociationInterface *d) :QMetaContainer(d) {}template<typename T>staticconstexpr QMetaAssociation fromContainer(){returnQMetaAssociation(&MetaAssociation<T>::value);} QMetaType keyMetaType()const; QMetaType mappedMetaType()const;boolcanInsertKey()const{if(auto iface =d())return iface->insertKeyFn;return false;}voidinsertKey(void*container,const void*key)const{if(canInsertKey())d()->insertKeyFn(container, key);}boolcanRemoveKey()const{if(auto iface =d())return iface->removeKeyFn;return false;}voidremoveKey(void*container,const void*key)const{if(canRemoveKey())d()->removeKeyFn(container, key);}boolcanContainsKey()const{if(auto iface =d())return iface->containsKeyFn;return false;}boolcontainsKey(const void*container,const void*key)const{if(canContainsKey())returnd()->containsKeyFn(container, key);return false;}boolcanGetMappedAtKey()const{if(auto iface =d())return iface->mappedAtKeyFn;return false;}voidmappedAtKey(const void*container,const void*key,void*mapped)const{if(canGetMappedAtKey())d()->mappedAtKeyFn(container, key, mapped);}boolcanSetMappedAtKey()const{if(auto iface =d())return iface->setMappedAtKeyFn;return false;}voidsetMappedAtKey(void*container,const void*key,const void*mapped)const{if(canSetMappedAtKey())d()->setMappedAtKeyFn(container, key, mapped);}boolcanGetKeyAtIterator()const{if(auto iface =d())return iface->keyAtIteratorFn;return false;}voidkeyAtIterator(const void*iterator,void*key)const{if(canGetKeyAtIterator())d()->keyAtIteratorFn(iterator, key);}boolcanGetKeyAtConstIterator()const{if(auto iface =d())return iface->keyAtConstIteratorFn;return false;}voidkeyAtConstIterator(const void*iterator,void*key)const{if(canGetKeyAtConstIterator())d()->keyAtConstIteratorFn(iterator, key);}boolcanGetMappedAtIterator()const{if(auto iface =d())return iface->mappedAtIteratorFn;return false;}voidmappedAtIterator(const void*iterator,void*mapped)const{if(canGetMappedAtIterator())d()->mappedAtIteratorFn(iterator, mapped);}boolcanGetMappedAtConstIterator()const{if(auto iface =d())return iface->mappedAtConstIteratorFn;return false;}voidmappedAtConstIterator(const void*iterator,void*mapped)const{if(canGetMappedAtConstIterator())d()->mappedAtConstIteratorFn(iterator, mapped);}boolcanSetMappedAtIterator()const{if(auto iface =d())return iface->setMappedAtIteratorFn;return false;}voidsetMappedAtIterator(const void*iterator,const void*mapped)const{if(canSetMappedAtIterator())d()->setMappedAtIteratorFn(iterator, mapped);}boolcanCreateIteratorAtKey()const{if(auto iface =d())return iface->createIteratorAtKeyFn;return false;}void*createIteratorAtKey(void*container,const void*key)const{if(canCreateIteratorAtKey())returnd()->createIteratorAtKeyFn(container, key);returnnullptr;}boolcanCreateConstIteratorAtKey()const{if(auto iface =d())return iface->createConstIteratorAtKeyFn;return false;}void*createConstIteratorAtKey(const void*container,const void*key)const{if(canCreateConstIteratorAtKey())returnd()->createConstIteratorAtKeyFn(container, key);returnnullptr;}constQtMetaContainerPrivate::QMetaAssociationInterface *iface()const{returnd(); }private:friendboolcomparesEqual(const QMetaAssociation &lhs,const QMetaAssociation &rhs) noexcept {return lhs.d() == rhs.d();}Q_DECLARE_EQUALITY_COMPARABLE(QMetaAssociation)template<typename T>struct MetaAssociation {staticconstexprconstQtMetaContainerPrivate::QMetaAssociationInterface value =QtMetaContainerPrivate::QMetaAssociationInterface(QtMetaContainerPrivate::QMetaAssociationForContainer<T>());};constQtMetaContainerPrivate::QMetaAssociationInterface *d()const{return static_cast<constQtMetaContainerPrivate::QMetaAssociationInterface *>(d_ptr);}}; QT_END_NAMESPACE #endif// QMETACONTAINER_H
|