specification_list.hpp tuple utility serif/model/specification.hpp serif/utils/misc/concepts/filter.hpp src/include/serif/model/stellar_model.hpp serif::model::detail::InsertSpecification< Specification, utils::types::TypeList<> > serif::model::detail::InsertSpecification< Specification, utils::types::TypeList< Head, Tail... > > serif::model::detail::CanonicalSpecifications<> serif::model::detail::CanonicalSpecifications< Head, Tail... > serif::model::detail::SelectRole serif::model::detail::ArgumentsMatch< utils::types::TypeList< Specifications... >, Arguments... > serif serif::model serif::model::detail #pragmaonce #include<tuple> #include<utility> #include"serif/model/specification.hpp" #include"serif/utils/misc/concepts/filter.hpp" namespaceserif::model::detail { template<ModelSpecificationLeft,ModelSpecificationRight> [[nodiscard]]constevalboolspecification_precedes() { usingL=typenameLeft::ModelDefinition; usingR=typenameRight::ModelDefinition; returnstd::tuple{L::role,L::generated_state_kind,L::name}<std::tuple{R::role,R::generated_state_kind,R::name}; } template<typenameSpecification,typenameList> structInsertSpecification; template<typenameSpecification> structInsertSpecification<Specification,utils::types::TypeList<>> { usingType=utils::types::TypeList<Specification>; }; template<typenameSpecification,typenameHead,typename...Tail> structInsertSpecification<Specification,utils::types::TypeList<Head,Tail...>> { usingType=std::conditional_t<specification_precedes<Specification,Head>(),utils::types::TypeList<Specification,Head,Tail...>, utils::misc::concepts::PrependT<Head,typenameInsertSpecification<Specification,utils::types::TypeList<Tail...>>::Type>>; }; template<typename...Specifications> structCanonicalSpecifications; template<> structCanonicalSpecifications<> { usingType=utils::types::TypeList<>; }; template<typenameHead,typename...Tail> structCanonicalSpecifications<Head,Tail...> { usingType=typenameInsertSpecification<Head,typenameCanonicalSpecifications<Tail...>::Type>::Type; }; template<ModelSpecification...Specifications> [[nodiscard]]constevalboolunique_specification_names() { constexprstd::array<SpecificationDescriptor,sizeof...(Specifications)>descriptions{{ {Specifications::ModelDefinition::name,Specifications::ModelDefinition::role,Specifications::ModelDefinition::generated_state_kind}... }}; for(std::size_tleft=0;left<descriptions.size();++left) { for(std::size_tright=left+1;right<descriptions.size();++right) { if(descriptions[left].role==descriptions[right].role&&descriptions[left].name==descriptions[right].name) { returnfalse; } } } returntrue; } template<SpecificationRoleRole,typename...Specifications> structSelectRole { template<typenameSpecification> usingHasRole=std::bool_constant<Specification::ModelDefinition::role==Role>; usingType=utils::misc::concepts::FilterT<utils::types::TypeList<Specifications...>,HasRole>; }; template<typenameList,typename...Arguments> structArgumentsMatch; template<typename...Specifications,typename...Arguments> structArgumentsMatch<utils::types::TypeList<Specifications...>,Arguments...> { template<typenameSpecification> staticconstexprstd::size_tcount=(std::size_t{0}+...+std::size_t{std::same_as<Specification,std::remove_cvref_t<Arguments>>}); staticconstexprboolvalue=sizeof...(Specifications)==sizeof...(Arguments)&&((count<Specifications>==1)&&...); }; template<typename...Specifications,typename...Arguments> [[nodiscard]]std::tuple<Specifications...>canonical_specifications(utils::types::TypeList<Specifications...>,Arguments&&...arguments) { std::tuple<std::remove_cvref_t<Arguments>...>values{std::forward<Arguments>(arguments)...}; return{std::get<Specifications>(std::move(values))...}; } }//namespaceserif::model::detail