@@ -13,6 +13,33 @@ namespace boost::openmethod {
1313
1414// ! Namespace containing the policy framework.
1515// !
16+ // ! A registry contains a list of policies that control how some operations are
17+ // ! performed. Policies fall into categories, depending on which subset of
18+ // ! operations they control. Each category has a corresponding class:
19+ // !
20+ // ! - @ref vptr: v-table pointer acquisition.
21+ // !
22+ // ! - @ref rtti: type information acquisition and manipulation.
23+ // !
24+ // ! - @ref type_hash: hashing of `type_id`s.
25+ // !
26+ // ! - @ref error_handler: perform operations when errors are detected.
27+ // !
28+ // ! - @ref output: output stream for logging and debugging.
29+ // !
30+ // ! - @ref runtime_checks: detect and report common errors.
31+ // !
32+ // ! - @ref trace: report how dispatch tables are built.
33+ // !
34+ // ! - @ref n2216: handle ambiguities according to the N2216 proposal.
35+ // !
36+ // ! The last three policy categories act like flags. They can appear in the
37+ // ! registry's policy list, and enable existing blocks of code.
38+ // !
39+ // ! The other categories cannot be used directly. They must be subclassed, and
40+ // ! the subclass must contain a `template<class Registry> struct fn` that
41+ // ! provides a set of static members that depends on the policy's category.
42+ // !
1643// ! A @e policy is a class that controls how some fundamental operations are
1744// ! performed by the library: type information acquisition (`rtti`), v-table
1845// ! pointer acquisition (`vptr`), error handling (`error_handler`), etc.
@@ -36,12 +63,10 @@ namespace policies {
3663// ! A @e rtti policy is responsible for acquiring and manipulating type
3764// ! information, dynamic casting, and identifying polymorphic classes.
3865// !
39- // ! Class `rtti` provides a default implementation for some of these operations.
40- // !
4166// ! @par Requirements
4267// !
43- // ! A @e rtti policy must derive from class `rtti`, and contain a `fn<Registry>`
44- // ! class template with the following public static members:
68+ // ! A subclass of `rtti` must contain a `fn<Registry>` class template with the
69+ // ! following public static members:
4570// !
4671// ! - `template<class Class> constexpr bool is_polymorphic`: evaluates to `true`
4772// ! if `Class` is polymorphic.
@@ -50,16 +75,21 @@ namespace policies {
5075// ! for `Class`.
5176// !
5277// ! - `template<class Class> type_id dynamic_type(const Class& obj)`:
53- // ! returns the type_id of an object's dynamic type.
54- // !
55- // ! - `template<typename Stream> void type_name(type_id type, Stream&
56- // ! stream)`: writes a description of `type` to `stream`.
78+ // ! returns the type_id of the @e dynamic type of `obj`.
5779// !
58- // ! - `template<typename Stream> void type_name(type_id type, Stream&
59- // ! stream)`: writes a description of `type` to `stream`.
80+ // ! - `template<typename Stream> void type_name(type_id type, Stream& stream)`:
81+ // ! writes a description of `type` to `stream`. `rtti::fn` provides a default
82+ // ! implementation.
6083// !
6184// ! - `/* unspecified */ type_index(type_id type)`: returns a @e unique
62- // ! identifier for `type`.
85+ // ! identifier for `type`. `rtti::fn` provides a default implementation.
86+ // !
87+ // ! The following functions is required only if casting from base to derived
88+ // ! class cannot be performed using a `static_cast` for some of the registered
89+ // ! classes:
90+ // !
91+ // ! - `template<typename D, typename B> D dynamic_cast_ref(B&& obj)`: casts
92+ // ! `obj` to reference type `D`.
6393
6494struct rtti {
6595 using category = rtti;
@@ -88,7 +118,7 @@ struct rtti {
88118 };
89119};
90120
91- // ! RTTI policy base class with defered type id collection.
121+ // ! RTTI policy base class for defered type id collection.
92122// !
93123// ! Some custom RTTI systems rely on static constructors to assign type ids.
94124// ! OpenMethod itself relies on static constructors to register classes, methods
@@ -104,9 +134,10 @@ struct deferred_static_rtti : rtti {};
104134// !
105135// ! @par Requirements
106136// !
107- // ! A subclass of `error_handler` contains a `fn<Registry>` struct that provides
108- // ! one or more `error` static functions that take an error object. `error` must
109- // ! be callable with an instance of any subclass of `openmethod_error`.
137+ // ! A subclass of `error_handler` must contain a `fn<Registry>` struct that
138+ // ! provides one or more `error` static functions that take an error object.
139+ // ! `error` must be callable with an instance of any subclass of
140+ // ! `openmethod_error`.
110141
111142struct error_handler {
112143 using category = error_handler;
@@ -118,48 +149,50 @@ struct error_handler {
118149// !
119150// ! @par Requirements
120151// !
121- // ! A subclass of `error_handler` contains a `fn<Registry>` struct that provides
152+ // ! A subclass of `type_hash` must contain a `fn<Registry>` struct that provides
122153// ! the following static member functions:
154+ // !
123155// ! - auto initialize(ForwardIterator first, ForwardIterator last) -> [min,
124156// ! max]: initialize the hash table with the values in the [iter, last) range.
125157// ! `*iter` is an object of an unspecified type that has two members,
126158// ! `type_id_begin()` and `type_id_end()`, which return iterators to a range
127159// ! of `type_id`s. `initialize` returns a pair with the minimum and maximum
128160// ! hash values.
161+ // !
129162// ! - auto hash(type_id type) -> std::size_t: returns a hash value for `type`.
130163// ! The value must be in the range returned by `initialize`.
164+ // !
131165// ! - void finalize(): releases any resources allocated by `initialize`. This
132166// ! member is optional.
133167
134168struct type_hash {
135169 using category = type_hash;
136170};
137171
138- /* *
139- Acquires a v-table pointer for an object.
140-
141- @par Requirements
142-
143- Any implementation of this policy must provide a meta-function `fn` that
144- in the form of:
145-
146- @code
147- template<class Registry>
148- struct fn {
149- template<class Class> static auto dynamic_vptr(const Class& arg) -> const vptr_type&;
150- };
151- @endcode
152-
153- @see policies::vptr_vector::fn::dynamic_vptr for an example.
154-
155- */
172+ // ! Acquires a v-table pointer for an object.
173+ // !
174+ // ! @par Requirements
175+ // !
176+ // ! A subclass of `type_hash` must contain a `fn<Registry>` struct that provides
177+ // ! the following static member functions:
178+ // !
179+ // ! - auto initialize(ForwardIterator first, ForwardIterator last) -> [min,
180+ // ! max]: initialize the hash table with the values in the [iter, last) range.
181+ // ! `*iter` is an object of an unspecified type that has two members,
182+ // ! `type_id_begin()` and `type_id_end()`, which return iterators to a range
183+ // ! of `type_id`s. `initialize` returns a pair with the minimum and maximum
184+ // ! hash values.
185+ // !
186+ // ! - auto hash(type_id type) -> std::size_t: returns a hash value for `type`.
187+ // ! The value must be in the range returned by `initialize`.
188+ // !
189+ // ! - void finalize(): releases any resources allocated by `initialize`. This
190+ // ! member is optional.
156191
157192struct vptr {
158193 using category = vptr;
159194};
160195
161- struct extern_vptr : vptr {};
162-
163196struct indirect_vptr {
164197 using category = indirect_vptr;
165198 template <class Registry >
@@ -324,6 +357,7 @@ struct registry : detail::registry_base {
324357 static constexpr auto indirect_vptr = has_policy<policies::indirect_vptr>;
325358
326359 using rtti = policy<policies::rtti>;
360+ using vptr = policy<policies::vptr>;
327361 using error_handler = policy<policies::error_handler>;
328362 using output = policy<policies::output>;
329363 using trace = policy<policies::trace>;
0 commit comments