[openmethod] [policies]

Hi all, and in particular Joaquín, Christian, Ruben and Steven who contributed remarks on the policy system. I followed some of Ruben's suggestions. There is now a registry that contains collections of classes and methods, and, after initialize(), dispatch data. It also contains a collection of policies. In part this is "just" renaming: what used to be a Policy is now a Registry, and what used to be a Facet is now a Policy. But this is not just cosmetic. The registry mechanism is clearly separated from the policies. Many old facets were CRTP templates, but not always. Now a policy (ex-facet) is - always - a Mp11 quoted meta-function that takes a registry as a single argument. This complicates creating policies a bit, but makes using them much easier, I think. CRTP is gone from the interface (in fact it is hidden). `fork` is gone. The debug and release stock policies looked like this: struct release : basic_policy< release, std_rtti, fast_perfect_hash<release>, vptr_vector<release>, vectored_error_handler<release>> {}; struct debug : release::fork<debug>::with< runtime_checks, basic_error_output<debug>, basic_trace_output<debug>> {}; Now they are: struct release : registry< std_rtti, fast_perfect_hash, vptr_vector, vectored_error_handler, stderr_output> {}; struct debug : registry< std_rtti, fast_perfect_hash, vptr_vector, vectored_error_handler, stderr_output, runtime_checks, trace> {}; An application that wants to use a standard map instead of a fast hash table, and keep all the rest the same, could say: struct my_registry : default_registry::with<vptr_map<>> {}; Or, using an unordered_flat_map: struct my_registry : default_registry::with< vptr_map<boost::mp11::mp_quote<boost::unordered_flat_map>>> {}; I also took Ruben's suggestion of having only one output policy, instead of one for error reporting, and one for tracing. Now, even in release builds, the default handler writes a diagnostic to stderr, before calling abort(). Policies are not aggregated via multiple inheritance anymore. At the moment, I am not convinced with Ruben's approach of making the registry (formerly policy) an object. There would still need to be a static instance of that object, which would contain instances of policy objects. Six of one or half of a dozen of the other. From there Ruben suggested making the dependencies between policies (ex-facets) explicit, as far as I can see this leads to a mess of conditionally enabled constructors. You can see the changes here: https://github.com/jll63/Boost.OpenMethod/pull/22 It's still a draft. The documentation is not yet updated, I'll do a big doc pass when things stabilize again. If you want to post comments directly to the PRs, drop me a line and I will invite you as a collaborator. J-L

I thought the ML would add [boost] at the beginning of the subject, but no...sorry for that. I am leaving the entire post as a quote below for the benefit of those who may have missed it because they have filters on [boost]. Steven found the name `vectored_error_handler` confusing. What about `indirect_error_handler` or `function_error_handler`? On Sun, May 18, 2025 at 1:31 PM Jean-Louis Leroy <jl@leroy.nyc> wrote:
Hi all, and in particular Joaquín, Christian, Ruben and Steven who contributed remarks on the policy system.
I followed some of Ruben's suggestions. There is now a registry that contains collections of classes and methods, and, after initialize(), dispatch data. It also contains a collection of policies. In part this is "just" renaming: what used to be a Policy is now a Registry, and what used to be a Facet is now a Policy. But this is not just cosmetic. The registry mechanism is clearly separated from the policies.
Many old facets were CRTP templates, but not always. Now a policy (ex-facet) is - always - a Mp11 quoted meta-function that takes a registry as a single argument. This complicates creating policies a bit, but makes using them much easier, I think. CRTP is gone from the interface (in fact it is hidden). `fork` is gone.
The debug and release stock policies looked like this:
struct release : basic_policy< release, std_rtti, fast_perfect_hash<release>, vptr_vector<release>, vectored_error_handler<release>> {};
struct debug : release::fork<debug>::with< runtime_checks, basic_error_output<debug>, basic_trace_output<debug>> {};
Now they are:
struct release : registry< std_rtti, fast_perfect_hash, vptr_vector, vectored_error_handler, stderr_output> {};
struct debug : registry< std_rtti, fast_perfect_hash, vptr_vector, vectored_error_handler, stderr_output, runtime_checks, trace> {};
An application that wants to use a standard map instead of a fast hash table, and keep all the rest the same, could say:
struct my_registry : default_registry::with<vptr_map<>> {};
Or, using an unordered_flat_map:
struct my_registry : default_registry::with< vptr_map<boost::mp11::mp_quote<boost::unordered_flat_map>>> {};
I also took Ruben's suggestion of having only one output policy, instead of one for error reporting, and one for tracing.
Now, even in release builds, the default handler writes a diagnostic to stderr, before calling abort().
Policies are not aggregated via multiple inheritance anymore.
At the moment, I am not convinced with Ruben's approach of making the registry (formerly policy) an object. There would still need to be a static instance of that object, which would contain instances of policy objects. Six of one or half of a dozen of the other. From there Ruben suggested making the dependencies between policies (ex-facets) explicit, as far as I can see this leads to a mess of conditionally enabled constructors.
You can see the changes here: https://github.com/jll63/Boost.OpenMethod/pull/22 It's still a draft. The documentation is not yet updated, I'll do a big doc pass when things stabilize again. If you want to post comments directly to the PRs, drop me a line and I will invite you as a collaborator.
J-L

On Sun, 18 May 2025 at 19:57, Jean-Louis Leroy via Boost < boost@lists.boost.org> wrote:
I thought the ML would add [boost] at the beginning of the subject, but no...sorry for that. I am leaving the entire post as a quote below for the benefit of those who may have missed it because they have filters on [boost].
Steven found the name `vectored_error_handler` confusing. What about `indirect_error_handler` or `function_error_handler`?
function_error_handler looks good to me. default_error_handler or maybe just error_handler (although I think the name might already be taken by the base policy) could also be reasonable. vectored_error_handler seems confusing to me. Regards, Ruben.
participants (2)
-
Jean-Louis Leroy
-
Ruben Perez