preparation.hpp cstddef expected serif/utils/dependencies/preparation.hpp serif/backend/mfem/operators/rejection.hpp src/include/serif/backend/mfem/operators/volume_stages.hpp serif::operators::backend::mfem::NumericalWork serif serif::operators serif::operators::backend serif::operators::backend::mfem #pragmaonce #include<cstddef> #include<expected> #include"serif/utils/dependencies/preparation.hpp" #include"serif/backend/mfem/operators/rejection.hpp" namespaceserif::operators::backend::mfem{ usingPreparationMode=utils::dependencies::PreparationMode; structNumericalWork{ std::size_treused_elements{0}; std::size_tgeometry_points{0}; std::size_tsampled_operands{0}; std::size_tphysics_points{0}; std::size_trefreshed_scalars{0}; [[nodiscard]]booldid_work()constnoexcept{ returngeometry_points!=0||sampled_operands!=0||physics_points!=0||refreshed_scalars!=0; } }; template<typenameCacheT,typenamePrepareT> [[nodiscard]]std::expected<void,PreparationRejection>try_prepare_validated(CacheT&cache,PrepareT&&prepare){ //Stackunwindingmustinvalidatethecachewithoutinterceptingunrelatedcallererrors. structInvalidateOnFailurefinal{ CacheT&cache; boolprepared{false}; ~InvalidateOnFailure(){ if(!prepared){ cache.invalidate(); } } }; InvalidateOnFailureguard{.cache=cache}; try{ constautoresult=prepare(); if(!result){ returnstd::unexpected(result.error().error); } guard.prepared=true; return{}; }catch(conststd::domain_error&error){ returnstd::unexpected(PreparationRejection{ .reason=PreparationRejectionReason::NON_FINITE, .message=error.what() }); } } }//namespaceserif::operators::backend::mfem