module; #include #include #include #include #include #include export module test_helpers; import mean_field; template struct Tag { std::array chars{}; // ReSharper disable once CppNonExplicitConvertingConstructor consteval Tag(std::array arr) : chars(arr) {} // ReSharper disable once CppNonExplicitConversionOperator constexpr operator const char*() const { return chars.data(); } // ReSharper disable once CppNonExplicitConversionOperator constexpr operator Catch::StringRef() const { return Catch::StringRef(chars.data(), N - 1); } template consteval Tag operator&(const Tag& other) const { std::array res{}; std::ranges::copy(chars.begin(), chars.end() - 1, res.begin()); std::ranges::copy(other.chars, res.begin() + (N - 1)); return {res}; } }; template consteval auto make_tag(const char (&str)[N]) { std::array res{}; res[0] = '['; std::ranges::copy(str, str + N - 1, res.begin() + 1); res[N] = ']'; res[N + 1] = '\0'; return Tag{res}; } template consteval auto sub_tag(const Tag& parent, const char (&str)[M]) { return parent & make_tag(str); } namespace test_utils::detail { std::optional configured_args; mean_field::utils::Args make_default_args() { mean_field::utils::Args args; args.mesh_file = "sandbox.smesh"; args.p.rtol = 1.0e-12; args.p.atol = 1.0e-12; return args; } } export namespace test_utils { void set_args(mean_field::utils::Args args) { detail::configured_args = std::move(args); } mean_field::utils::Args setup_args() { if (detail::configured_args.has_value()) { return *detail::configured_args; } return detail::make_default_args(); } } export namespace tags { inline constexpr auto geometry = make_tag("geometry"); inline constexpr auto physics = make_tag("physics"); inline constexpr auto unit = make_tag("unit"); inline constexpr auto mesh = make_tag("mesh"); inline constexpr auto integration = make_tag("integration"); inline constexpr auto solver = make_tag("solver"); inline constexpr auto gravity = sub_tag(physics, "gravity"); inline constexpr auto hydro = sub_tag(physics, "hydro"); inline constexpr auto jacobian = sub_tag(integration & physics , "jacobian"); inline constexpr auto residuals = sub_tag(integration & physics , "residuals"); inline constexpr auto h_refinement = sub_tag(mesh & solver , "h_refinement"); inline constexpr auto volume = sub_tag(mesh & geometry , "volume"); inline constexpr auto quadrature = sub_tag(mesh & geometry & solver , "quadrature"); inline constexpr auto analytic_comparison = sub_tag(solver & physics & residuals , "analytic_comparison"); inline constexpr auto self_consistency = sub_tag(solver & physics , "self_consistency"); }