rework policies

This commit is contained in:
Jean-Louis Leroy
2025-05-18 10:59:40 -04:00
committed by Jean-Louis Leroy
parent 0b44fc5973
commit dba92d1d39
7 changed files with 54 additions and 39 deletions

View File

@@ -229,7 +229,7 @@ struct compiler : detail::generic_compiler {
decltype(Registry::template policy<policies::rtti>::type_index(0));
typename detail::aggregate_reports<
mp11::mp_list<report>, typename Registry::policies>::type report;
mp11::mp_list<report>, typename Registry::policy_list>::type report;
std::unordered_map<type_index_type, class_*> class_map;
@@ -1340,10 +1340,27 @@ auto initialize() -> compiler<Registry> {
return compiler;
}
namespace detail {
template<class Policy, typename = void>
struct has_finalize_aux : std::false_type {};
template<class Policy>
struct has_finalize_aux<Policy, std::void_t<decltype(Policy::finalize)>>
: std::true_type {};
} // namespace detail
template<class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
auto finalize() -> void {
mp11::mp_for_each<typename Registry::policies>(
[](auto policy) { decltype(policy)::finalize(); });
mp11::mp_for_each<typename Registry::policy_list>([](auto policy) {
using fn = typename decltype(policy)::template fn<
typename Registry::RegistryType>;
if constexpr (detail::has_finalize_aux<fn>::value) {
fn::finalize();
}
});
Registry::dispatch_data.clear();
}

View File

@@ -357,8 +357,6 @@ inline vptr_type null_vptr = nullptr;
template<class Class, class Registry, typename = void>
class virtual_ptr_impl {
using Policies = typename Registry::policies;
public:
using traits = virtual_traits<Class&, Registry>;
using element_type = Class;

View File

@@ -33,15 +33,11 @@ struct type_name {
template<class Registry>
struct trace_type {
static constexpr bool trace_enabled =
Registry::template has_policy<policies::trace>;
std::size_t indentation_level{0};
auto operator++() -> trace_type& {
if constexpr (trace_enabled) {
using trace =
typename Registry::template policy<policies::trace>;
if constexpr (Registry::Trace) {
using trace = typename Registry::template policy<policies::trace>;
if (trace::trace_enabled) {
for (std::size_t i = 0; i < indentation_level; ++i) {
Registry::template policy<policies::output>::os << " ";
@@ -68,7 +64,7 @@ struct trace_type {
template<class Registry, typename T, typename F>
auto write_range(trace_type<Registry>& trace, range<T> range, F fn) -> auto& {
if constexpr (trace_type<Registry>::trace_enabled) {
if constexpr (Registry::Trace) {
if (Registry::template policy<policies::trace>::trace_enabled) {
trace << "(";
const char* sep = "";
@@ -86,7 +82,7 @@ auto write_range(trace_type<Registry>& trace, range<T> range, F fn) -> auto& {
template<class Registry, typename T>
auto operator<<(trace_type<Registry>& trace, const T& value) -> auto& {
if constexpr (trace_type<Registry>::trace_enabled) {
if constexpr (Registry::Trace) {
if (Registry::template policy<policies::trace>::trace_enabled) {
Registry::template policy<policies::output>::os << value;
}
@@ -96,7 +92,7 @@ auto operator<<(trace_type<Registry>& trace, const T& value) -> auto& {
template<class Registry>
auto operator<<(trace_type<Registry>& trace, const rflush& rf) -> auto& {
if constexpr (trace_type<Registry>::trace_enabled) {
if constexpr (Registry::Trace) {
if (Registry::template policy<policies::trace>::trace_enabled) {
std::size_t digits = 1;
auto tmp = rf.value / 10;
@@ -121,7 +117,7 @@ auto operator<<(trace_type<Registry>& trace, const rflush& rf) -> auto& {
template<class Registry>
auto operator<<(
trace_type<Registry>& trace, const boost::dynamic_bitset<>& bits) -> auto& {
if constexpr (trace_type<Registry>::trace_enabled) {
if constexpr (Registry::Trace) {
if (Registry::template policy<policies::trace>::trace_enabled) {
auto i = bits.size();
while (i != 0) {
@@ -147,9 +143,8 @@ auto operator<<(trace_type<Registry>& trace, const range<T>& range) -> auto& {
template<class Registry>
auto operator<<(trace_type<Registry>& trace, const type_name& manip) -> auto& {
if constexpr (Registry::template has_policy<policies::trace>) {
Registry::template policy<policies::rtti>::type_name(
manip.type, trace);
if constexpr (Registry::Trace) {
Registry::template policy<policies::rtti>::type_name(manip.type, trace);
}
return trace;

View File

@@ -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<class Registry>
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<class Registry>
using fn = runtime_checks;
struct fn {};
};
template<typename Key>
struct unique : policy {
using category = unique;
template<class Registry>
struct fn {};
};
} // namespace policies
@@ -95,10 +94,10 @@ constexpr bool is_not_void = !std::is_same_v<T, void>;
template<
class Registry, class Index,
class Size = mp11::mp_size<typename Registry::policies>>
class Size = mp11::mp_size<typename Registry::policy_list>>
struct get_policy_aux {
using type = typename mp11::mp_at<
typename Registry::policies, Index>::template fn<Registry>;
typename Registry::policy_list, Index>::template fn<Registry>;
};
template<class Registry, class Size>
@@ -159,13 +158,13 @@ struct registry : detail::registry_base {
inline static vptr_type static_vptr;
inline static std::vector<std::uintptr_t> dispatch_data;
using policies = mp11::mp_list<Policies...>;
using policy_list = mp11::mp_list<Policies...>;
template<class PolicyCategory>
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<std::is_base_of>, PolicyCategory>>>::type;
@@ -175,17 +174,19 @@ struct registry : detail::registry_base {
template<class... NewPolicies>
using with = boost::mp11::mp_apply<
registry, typename detail::with_aux<policies, NewPolicies...>::type>;
registry, typename detail::with_aux<policy_list, NewPolicies...>::type>;
template<class... RemovePolicies>
using without = boost::mp11::mp_apply<
registry,
typename detail::without_aux<policies, RemovePolicies...>::type>;
typename detail::without_aux<policy_list, RemovePolicies...>::type>;
using Rtti = policy<openmethod::policies::rtti>;
using ErrorHandler = policy<openmethod::policies::error_handler>;
static constexpr auto RuntimeChecks =
has_policy<openmethod::policies::runtime_checks>;
// Following typedefs are shortcuts reserved for implementation. DO NOT USE!
using RegistryType = registry;
using Rtti = policy<policies::rtti>;
using ErrorHandler = policy<policies::error_handler>;
static constexpr auto RuntimeChecks = has_policy<policies::runtime_checks>;
static constexpr auto Trace = has_policy<policies::trace>;
};
} // namespace boost::openmethod

View File

@@ -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<test_registry::RegistryType>.empty());
finalize<test_registry>();
static_assert(detail::has_finalize_aux<test_registry::policy<policies::vptr>>::value);
BOOST_TEST(test_registry::dispatch_data.empty());
BOOST_TEST(detail::vptr_vector_vptrs<test_registry::RegistryType>.empty());
}
} // namespace TEST_NS

View File

@@ -247,9 +247,6 @@ BOOST_AUTO_TEST_CASE(test_assign_slots_a_b1_c) {
BOOST_TEST(get_class<A>(comp)->vtbl.size() == 0u);
BOOST_TEST(get_class<B>(comp)->vtbl.size() == 1u);
BOOST_TEST(get_class<C>(comp)->vtbl.size() == 0u);
finalize<test_registry>();
BOOST_TEST(test_registry::dispatch_data.empty());
}
BOOST_AUTO_TEST_CASE(test_assign_slots_a1_b1_c1) {

View File

@@ -36,8 +36,8 @@ static_assert(detail::is_registry<default_registry>);
struct not_a_policy {};
static_assert(!detail::is_registry<not_a_policy>);
struct registry1 : registry<unique<registry1>, default_registry::policies> {};
struct registry2 : registry<unique<registry2>, default_registry::policies> {};
struct registry1 : default_registry::with<unique<registry1>> {};
struct registry2 : default_registry::with<unique<registry2>> {};
struct foo : policy {
using category = foo;