From dba92d1d397b02a67882d8103944d980a4b6cff5 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Sun, 18 May 2025 10:59:40 -0400 Subject: [PATCH] rework policies --- include/boost/openmethod/compiler.hpp | 23 +++++++++++++--- include/boost/openmethod/core.hpp | 2 -- include/boost/openmethod/detail/trace.hpp | 21 ++++++--------- include/boost/openmethod/registry.hpp | 33 ++++++++++++----------- test/test_blackbox.cpp | 7 +++++ test/test_compiler.cpp | 3 --- test/test_policies.cpp | 4 +-- 7 files changed, 54 insertions(+), 39 deletions(-) diff --git a/include/boost/openmethod/compiler.hpp b/include/boost/openmethod/compiler.hpp index a7c12a3..5997cab 100644 --- a/include/boost/openmethod/compiler.hpp +++ b/include/boost/openmethod/compiler.hpp @@ -229,7 +229,7 @@ struct compiler : detail::generic_compiler { decltype(Registry::template policy::type_index(0)); typename detail::aggregate_reports< - mp11::mp_list, typename Registry::policies>::type report; + mp11::mp_list, typename Registry::policy_list>::type report; std::unordered_map class_map; @@ -1340,10 +1340,27 @@ auto initialize() -> compiler { return compiler; } +namespace detail { + +template +struct has_finalize_aux : std::false_type {}; + +template +struct has_finalize_aux> + : std::true_type {}; + +} // namespace detail + template auto finalize() -> void { - mp11::mp_for_each( - [](auto policy) { decltype(policy)::finalize(); }); + mp11::mp_for_each([](auto policy) { + using fn = typename decltype(policy)::template fn< + typename Registry::RegistryType>; + if constexpr (detail::has_finalize_aux::value) { + fn::finalize(); + } + }); + Registry::dispatch_data.clear(); } diff --git a/include/boost/openmethod/core.hpp b/include/boost/openmethod/core.hpp index 72ecc51..0d9e596 100644 --- a/include/boost/openmethod/core.hpp +++ b/include/boost/openmethod/core.hpp @@ -357,8 +357,6 @@ inline vptr_type null_vptr = nullptr; template class virtual_ptr_impl { - using Policies = typename Registry::policies; - public: using traits = virtual_traits; using element_type = Class; diff --git a/include/boost/openmethod/detail/trace.hpp b/include/boost/openmethod/detail/trace.hpp index d25262b..bec5317 100644 --- a/include/boost/openmethod/detail/trace.hpp +++ b/include/boost/openmethod/detail/trace.hpp @@ -33,15 +33,11 @@ struct type_name { template struct trace_type { - static constexpr bool trace_enabled = - Registry::template has_policy; - std::size_t indentation_level{0}; auto operator++() -> trace_type& { - if constexpr (trace_enabled) { - using trace = - typename Registry::template policy; + if constexpr (Registry::Trace) { + using trace = typename Registry::template policy; if (trace::trace_enabled) { for (std::size_t i = 0; i < indentation_level; ++i) { Registry::template policy::os << " "; @@ -68,7 +64,7 @@ struct trace_type { template auto write_range(trace_type& trace, range range, F fn) -> auto& { - if constexpr (trace_type::trace_enabled) { + if constexpr (Registry::Trace) { if (Registry::template policy::trace_enabled) { trace << "("; const char* sep = ""; @@ -86,7 +82,7 @@ auto write_range(trace_type& trace, range range, F fn) -> auto& { template auto operator<<(trace_type& trace, const T& value) -> auto& { - if constexpr (trace_type::trace_enabled) { + if constexpr (Registry::Trace) { if (Registry::template policy::trace_enabled) { Registry::template policy::os << value; } @@ -96,7 +92,7 @@ auto operator<<(trace_type& trace, const T& value) -> auto& { template auto operator<<(trace_type& trace, const rflush& rf) -> auto& { - if constexpr (trace_type::trace_enabled) { + if constexpr (Registry::Trace) { if (Registry::template policy::trace_enabled) { std::size_t digits = 1; auto tmp = rf.value / 10; @@ -121,7 +117,7 @@ auto operator<<(trace_type& trace, const rflush& rf) -> auto& { template auto operator<<( trace_type& trace, const boost::dynamic_bitset<>& bits) -> auto& { - if constexpr (trace_type::trace_enabled) { + if constexpr (Registry::Trace) { if (Registry::template policy::trace_enabled) { auto i = bits.size(); while (i != 0) { @@ -147,9 +143,8 @@ auto operator<<(trace_type& trace, const range& range) -> auto& { template auto operator<<(trace_type& trace, const type_name& manip) -> auto& { - if constexpr (Registry::template has_policy) { - Registry::template policy::type_name( - manip.type, trace); + if constexpr (Registry::Trace) { + Registry::template policy::type_name(manip.type, trace); } return trace; diff --git a/include/boost/openmethod/registry.hpp b/include/boost/openmethod/registry.hpp index a30de1a..0a5a763 100644 --- a/include/boost/openmethod/registry.hpp +++ b/include/boost/openmethod/registry.hpp @@ -12,10 +12,7 @@ namespace boost::openmethod { namespace policies { -struct policy { - static auto finalize() -> void { - } -}; +struct policy {}; struct rtti : policy { using category = rtti; @@ -52,7 +49,7 @@ struct extern_vptr : vptr {}; struct indirect_vptr : policy { using category = indirect_vptr; template - using fn = indirect_vptr; + struct fn {}; }; struct output : policy { @@ -73,12 +70,14 @@ struct trace : policy { struct runtime_checks : policy { using category = runtime_checks; template - using fn = runtime_checks; + struct fn {}; }; template struct unique : policy { using category = unique; + template + struct fn {}; }; } // namespace policies @@ -95,10 +94,10 @@ constexpr bool is_not_void = !std::is_same_v; template< class Registry, class Index, - class Size = mp11::mp_size> + class Size = mp11::mp_size> struct get_policy_aux { using type = typename mp11::mp_at< - typename Registry::policies, Index>::template fn; + typename Registry::policy_list, Index>::template fn; }; template @@ -159,13 +158,13 @@ struct registry : detail::registry_base { inline static vptr_type static_vptr; inline static std::vector dispatch_data; - using policies = mp11::mp_list; + using policy_list = mp11::mp_list; template using policy = typename detail::get_policy_aux< registry, mp11::mp_find_if_q< - policies, + policy_list, mp11::mp_bind_front_q< mp11::mp_quote_trait, PolicyCategory>>>::type; @@ -175,17 +174,19 @@ struct registry : detail::registry_base { template using with = boost::mp11::mp_apply< - registry, typename detail::with_aux::type>; + registry, typename detail::with_aux::type>; template using without = boost::mp11::mp_apply< registry, - typename detail::without_aux::type>; + typename detail::without_aux::type>; - using Rtti = policy; - using ErrorHandler = policy; - static constexpr auto RuntimeChecks = - has_policy; + // Following typedefs are shortcuts reserved for implementation. DO NOT USE! + using RegistryType = registry; + using Rtti = policy; + using ErrorHandler = policy; + static constexpr auto RuntimeChecks = has_policy; + static constexpr auto Trace = has_policy; }; } // namespace boost::openmethod diff --git a/test/test_blackbox.cpp b/test/test_blackbox.cpp index d7327a5..c4130c9 100644 --- a/test/test_blackbox.cpp +++ b/test/test_blackbox.cpp @@ -361,6 +361,13 @@ BOOST_AUTO_TEST_CASE(simple) { BOOST_TEST(times(dense, 2) == Types(MATRIX_SCALAR, NONE)); BOOST_TEST(times(diag, 2) == Types(DIAGONAL_SCALAR, MATRIX_SCALAR)); } + + BOOST_TEST(!test_registry::dispatch_data.empty()); + BOOST_TEST(!detail::vptr_vector_vptrs.empty()); + finalize(); + static_assert(detail::has_finalize_aux>::value); + BOOST_TEST(test_registry::dispatch_data.empty()); + BOOST_TEST(detail::vptr_vector_vptrs.empty()); } } // namespace TEST_NS diff --git a/test/test_compiler.cpp b/test/test_compiler.cpp index 7fded74..47a8ccd 100644 --- a/test/test_compiler.cpp +++ b/test/test_compiler.cpp @@ -247,9 +247,6 @@ BOOST_AUTO_TEST_CASE(test_assign_slots_a_b1_c) { BOOST_TEST(get_class(comp)->vtbl.size() == 0u); BOOST_TEST(get_class(comp)->vtbl.size() == 1u); BOOST_TEST(get_class(comp)->vtbl.size() == 0u); - - finalize(); - BOOST_TEST(test_registry::dispatch_data.empty()); } BOOST_AUTO_TEST_CASE(test_assign_slots_a1_b1_c1) { diff --git a/test/test_policies.cpp b/test/test_policies.cpp index 1855a18..55f970a 100644 --- a/test/test_policies.cpp +++ b/test/test_policies.cpp @@ -36,8 +36,8 @@ static_assert(detail::is_registry); struct not_a_policy {}; static_assert(!detail::is_registry); -struct registry1 : registry, default_registry::policies> {}; -struct registry2 : registry, default_registry::policies> {}; +struct registry1 : default_registry::with> {}; +struct registry2 : default_registry::with> {}; struct foo : policy { using category = foo;