dependency_context.cpp serif/utils/dependencies/dependency_context.hpp serif/utils/dependencies/key_list_operations.hpp serif/utils/dependencies/keys.hpp concepts memory type_traits utility #include"serif/utils/dependencies/dependency_context.hpp" #include"serif/utils/dependencies/key_list_operations.hpp" #include"serif/utils/dependencies/keys.hpp" #include<concepts> #include<memory> #include<type_traits> #include<utility> namespace{ namespacedependencies=serif::utils::dependencies; structFirst{}; structSecond{}; structMissing{}; usingFirstResource=decltype(dependencies::own<First>(1)); usingSecondResource=decltype(dependencies::own<Second>(2)); usingDependencyContext=dependencies::DependencyContext<FirstResource,SecondResource>; usingSelection=decltype(std::declval<constDependencyContext&>().select(dependencies::KeyList<Second>{})); template<typename...Resources> conceptCanMakeContext=requires(Resources&&...resources){ dependencies::make_dependency_context(std::forward<Resources>(resources)...); }; template<typenameContextT,typenameKeyT> conceptCanRead=requires(constContextT&context){context.templateget<KeyT>();}; template<typenameContextT> conceptCanSelect=requires(ContextT&&context){ std::forward<ContextT>(context).select(dependencies::KeyList<First>{}); }; template<typenameValueT> conceptCanBorrow=requires(ValueT&&value){dependencies::borrow<First>(std::forward<ValueT>(value));}; static_assert(dependencies::IsDependencyContext<DependencyContext>); static_assert(dependencies::IsDependencyContext<constDependencyContext&>); static_assert(dependencies::IsDependencyContext<Selection>); static_assert(!dependencies::IsDependencyContext<int>); static_assert(CanMakeContext<>); static_assert(CanMakeContext<FirstResource, SecondResource>); static_assert(!CanMakeContext<FirstResource, FirstResource>); static_assert(!CanMakeContext<int>); static_assert(CanRead<DependencyContext, First>&&CanRead<DependencyContext, Second>); static_assert(!CanRead<DependencyContext, Missing>); static_assert(CanRead<Selection, Second>&&!CanRead<Selection, First>); static_assert(std::same_as<decltype(std::declval<constDependencyContext&>().get<First>()),constint&>); static_assert(std::same_as<dependencies::bound_type_t<Selection::Bindings,Second>,int>); static_assert(CanSelect<DependencyContext&>&&CanSelect<const DependencyContext&>); static_assert(!CanSelect<DependencyContext>&&!CanSelect<const DependencyContext>); static_assert(!std::constructible_from<Selection,DependencyContext&&>); static_assert(CanBorrow<int&>&&CanBorrow<const int&>); static_assert(!CanBorrow<int>&&!CanBorrow<const int>); usingQualifiedContext=decltype(dependencies::make_dependency_context( dependencies::own<First>(1),dependencies::own<constFirst>(2),dependencies::own<First&>(3) )); static_assert(CanRead<QualifiedContext, First>&&CanRead<QualifiedContext, const First>&&CanRead<QualifiedContext, First&>); usingCombined=dependencies::CombinedKeyList< dependencies::KeyList<First,Second>,dependencies::KeyList<Second,Missing>,constdependencies::KeyList<First>& >; static_assert(std::same_as<Combined,dependencies::KeyList<First,Second,Missing>>); static_assert(std::same_as<dependencies::CombinedKeyList<>,dependencies::KeyList<>>); usingGeneralKeys=dependencies::KeyList<dependencies::keys::Input,dependencies::keys::Output, dependencies::keys::Scale,dependencies::keys::Parameters,dependencies::keys::Coordinates>; static_assert(dependencies::IsKeyList<GeneralKeys>); static_assert(std::same_as<dependencies::InputList<First,Second>,dependencies::KeyList<First,Second>>); static_assert(std::same_as<dependencies::RequestedResults<First>,dependencies::KeyList<First>>); //Keysdescriberoles;evenanonconstructibledescriptorwithdatacannameone. structCustomTerm{ intmember; CustomTerm()=delete; }; usingCustomContext=decltype(dependencies::make_dependency_context(dependencies::own<CustomTerm>(1))); static_assert(CanRead<CustomContext,CustomTerm>); structNonComparable{}; structReferenceSnapshot{ constint&capture(constint&)const; boolmatches(constint&,constint&)const; }; structRvalueOnlySnapshot{ intcapture(constint&)const; boolmatches(int&&,constint&)const; }; structMoveOnlySnapshot{ std::unique_ptr<int>capture(constint&)const; boolmatches(conststd::unique_ptr<int>&,constint&)const; }; static_assert(dependencies::SnapshotPolicyFor<dependencies::ValueSnapshot,int>); static_assert(!dependencies::SnapshotPolicyFor<dependencies::ValueSnapshot,NonComparable>); static_assert(!dependencies::SnapshotPolicyFor<dependencies::ValueSnapshot,std::unique_ptr<int>>); static_assert(!dependencies::SnapshotPolicyFor<ReferenceSnapshot,int>); static_assert(!dependencies::SnapshotPolicyFor<RvalueOnlySnapshot,int>); static_assert(dependencies::SnapshotPolicyFor<MoveOnlySnapshot,int>); usingProjection=decltype(dependencies::track_by([](constint&value){returnvalue;})); usingInvalidProjection=decltype(dependencies::track_by([](constint&){returnNonComparable{};})); static_assert(dependencies::SnapshotPolicyFor<Projection,int>); static_assert(!dependencies::SnapshotPolicyFor<InvalidProjection,int>); template<typename...Contexts> conceptCanCombineContexts=requires(constContexts&...contexts) { dependencies::combine_dependency_contexts(contexts...); }; usingFirstContext=dependencies::DependencyContext<FirstResource>; usingSecondContext=dependencies::DependencyContext<SecondResource>; structDefaultInputs{ dependencies::DependencyContext<>inputs; }; static_assert(requires{DefaultInputs{};}); static_assert(std::constructible_from<FirstContext,FirstResource>); static_assert(!std::convertible_to<FirstResource,FirstContext>); static_assert(!std::default_initializable<FirstContext>); usingMoveOnlyContext=decltype(dependencies::make_dependency_context(dependencies::own<First>(std::make_unique<int>(3)))); static_assert(CanCombineContexts<>); static_assert(CanCombineContexts<FirstContext,SecondContext>); static_assert(CanCombineContexts<FirstContext,Selection>); static_assert(!CanCombineContexts<FirstContext,FirstContext>); static_assert(!CanCombineContexts<DependencyContext,Selection>); static_assert(!CanCombineContexts<MoveOnlyContext>); static_assert(!CanCombineContexts<int>); static_assert(std::same_as<DependencyContext::Keys,dependencies::KeyList<First,Second>>); static_assert(std::same_as<Selection::Keys,dependencies::KeyList<Second>>); }