computation_store.hpp serif/utils/error/errors.hpp concepts cstddef memory stdexcept tuple type_traits utility serif/utils/dependencies/binding.hpp serif/utils/dependencies/detail/type_lists.hpp src/compile_time_checks/serif/utils/dependencies/computation_store.cpp src/include/serif/utils/dependencies/dependencies.hpp serif::utils::dependencies::OwnedComputation serif::utils::dependencies::ComputationStore serif serif::utils serif::utils::dependencies #pragmaonce #include"serif/utils/error/errors.hpp" #include<concepts> #include<cstddef> #include<memory> #include<stdexcept> #include<tuple> #include<type_traits> #include<utility> #include"serif/utils/dependencies/binding.hpp" #include"serif/utils/dependencies/detail/type_lists.hpp" namespaceserif::utils::dependencies{ template<typenameKeyT,typenameComputationT> classOwnedComputation{ public: usingKey=KeyT; usingTarget=ComputationT; template<typenameValueT>requiresstd::constructible_from<Target,ValueT> explicitOwnedComputation(ValueT&&value):m_value(std::make_unique<Target>(std::forward<ValueT>(value))){} OwnedComputation(constOwnedComputation&)=delete; OwnedComputation&operator=(constOwnedComputation&)=delete; OwnedComputation(OwnedComputation&&)noexcept=default; OwnedComputation&operator=(OwnedComputation&&)=delete; [[nodiscard]]Target&get()&{returnchecked_value();} [[nodiscard]]constTarget&get()const&{returnchecked_value();} Target&get()&&=delete; constTarget&get()const&&=delete; private: [[nodiscard]]Target&checked_value()const{ if(!m_value){ serif::utils::errors::serif_error<std::logic_error, serif::utils::errors::SERiFErrorCode::INVALID_ARGUMENT>("dependencies::OwnedComputation::get:ownershiphasmovedtoanotherentry.Accessthedestinationownerinstead."); } return*m_value; } std::unique_ptr<Target>m_value; }; template<typenameT> inlineconstexprboolis_owned_computation_v=false; template<typenameKeyT,typenameComputationT> inlineconstexprboolis_owned_computation_v<OwnedComputation<KeyT, ComputationT>>=true; template<typenameT> conceptIsOwnedComputation=is_owned_computation_v<std::remove_cvref_t<T>>; template<typenameKeyT,typenameComputationT> requiresstd::constructible_from<std::remove_cvref_t<ComputationT>,ComputationT> [[nodiscard]]autoown_computation(ComputationT&&computation){ returnOwnedComputation<KeyT, std::remove_cvref_t<ComputationT>>(std::forward<ComputationT>(computation)); } template<IsOwnedComputation...EntryTs> requiresmisc::traits::all_unique_types_v<typenameEntryTs::Key...> classComputationStore{ public: usingBindings=dependencies::Bindings<Binding<typename EntryTs::Key, typename EntryTs::Target>...>; explicitComputationStore(EntryTs...entries):m_entries(std::move(entries)...){} ComputationStore(constComputationStore&)=delete; ComputationStore&operator=(constComputationStore&)=delete; ComputationStore(ComputationStore&&)noexcept=default; ComputationStore&operator=(ComputationStore&&)=delete; template<typenameKeyT>requiresBindingsWithBinding<Bindings, KeyT> [[nodiscard]]auto&get()&{ constexprstd::size_tindex=detail::type_index<KeyT>(types::TypeList<typename EntryTs::Key...>{}); returnstd::get<index>(m_entries).get(); } template<typenameKeyT>requiresBindingsWithBinding<Bindings, KeyT> [[nodiscard]]constauto&get()const&{ constexprstd::size_tindex=detail::type_index<KeyT>(types::TypeList<typename EntryTs::Key...>{}); returnstd::get<index>(m_entries).get(); } template<typenameKeyT>autoget()&&=delete; template<typenameKeyT>autoget()const&&=delete; private: std::tuple<EntryTs...>m_entries; }; template<typename...EntryTs> requires(IsOwnedComputation<EntryTs>&&...)&& misc::traits::all_unique_types_v<typename std::remove_cvref_t<EntryTs>::Key...>&& (std::constructible_from<std::remove_cvref_t<EntryTs>,EntryTs>&&...) [[nodiscard]]automake_computation_store(EntryTs&&...entries){ returnComputationStore<std::remove_cvref_t<EntryTs>...>(std::forward<EntryTs>(entries)...); } }