snapshot.hpp concepts functional memory type_traits utility src/include/serif/backend/mfem/model/normalization/computations.hpp src/include/serif/utils/dependencies/dependencies.hpp src/include/serif/utils/dependencies/resource.hpp serif::utils::dependencies::ValueSnapshot serif::utils::dependencies::ProjectedSnapshot serif serif::utils serif::utils::dependencies #pragmaonce #include<concepts> #include<functional> #include<memory> #include<type_traits> #include<utility> namespaceserif::utils::dependencies{ structValueSnapshot{ template<typenameT>requiresstd::copy_constructible<T>&&std::equality_comparable<T> [[nodiscard]]Tcapture(constT&value)const{returnvalue;} template<typenameT>requiresstd::equality_comparable<T> [[nodiscard]]boolmatches(constT&captured,constT&value)const{returncaptured==value;} }; template<typenameFunctionT> classProjectedSnapshot{ public: explicitProjectedSnapshot(FunctionTfunction):m_function(std::move(function)){} template<typenameT>requiresstd::invocable<constFunctionT&,constT&> [[nodiscard]]autocapture(constT&value)const{returnstd::invoke(m_function,value);} template<typenameCapturedT,typenameT> requiresrequires(constCapturedT&captured,constProjectedSnapshot&policy,constT&value){ {captured==policy.capture(value)}->std::convertible_to<bool>; } [[nodiscard]]boolmatches(constCapturedT&captured,constT&value)const{returncaptured==capture(value);} private: FunctionTm_function; }; template<typenameFunctionT> [[nodiscard]]autotrack_by(FunctionT&&function){ returnProjectedSnapshot<std::decay_t<FunctionT>>(std::forward<FunctionT>(function)); } template<typenamePolicyT,typenameValueT> conceptSnapshotPolicyFor=requires(constPolicyT&policy,constValueT&value){ policy.capture(value); requiresstd::is_object_v<decltype(policy.capture(value))>; requiresstd::move_constructible<decltype(policy.capture(value))>; {policy.matches(std::declval<constdecltype(policy.capture(value))&>(),value)}->std::convertible_to<bool>; }&&(!requires(constPolicyT&policy,constValueT&value){policy.identity(value);}|| requires(constPolicyT&policy,constValueT&value){{policy.identity(value)}->std::convertible_to<constvoid*>;}); template<typenamePolicyT,typenameValueT>requiresSnapshotPolicyFor<PolicyT,ValueT> [[nodiscard]]constvoid*source_identity(constPolicyT&policy,constValueT&value){ ifconstexpr(requires{policy.identity(value);}){returnpolicy.identity(value);} else{returnstd::addressof(value);} } }