mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 04:22:12 +00:00
rework policies
This commit is contained in:
committed by
Jean-Louis Leroy
parent
0b44fc5973
commit
dba92d1d39
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user