1111
1212namespace boost ::openmethod {
1313
14- namespace policies {
15-
16- /* *
17- Base class for all policies.
18-
19- A @e policy is a direct subclass of `policy`. Each such subclass
20-
21- A @ref
22-
23- @par Requirements
24-
25- A policy must provide a typedef that identifies its category, which must be
26- a direct derived class of `policy`. The category identifies the policy in
27- the registry.
28-
29- @code
30- using category = <policy direct derived class>;
31- @endcode
32-
33- <policy_category> must be one of the following:
14+ // ! Namespace containing the policy framework.
15+ // !
16+ // ! A @e policy is a class that controls how some fundamental operations are
17+ // ! performed by the library: type information acquisition (`rtti`), v-table
18+ // ! pointer acquisition (`vptr`), error handling (`error_handler`), etc.
19+ // !
20+ // ! Some policies can be used directly in a registry's policy list. They
21+ // ! function like flags, enabling blocks of code in the dispatch mechanism. For
22+ // ! example, `runtime_checks` enables code that detects missing class
23+ // ! registrations.
24+ // !
25+ // ! Others policy classes need to be derived from. The subclass is required to
26+ // ! contain a `template<class Registry> struct fn`, which contains a set static
27+ // ! members that follow the requirements of the policy. For example, subclasses
28+ // ! of `vptr` must provide a `fn` that contains a `static vptr_type
29+ // ! dynamic_vptr(const Class& arg)` that returns a v-table pointer for an object
30+ // ! of type `Class`.
3431
35- - `rtti` obtain static type information for a class, and dynamic type
36- information for an object.
37-
38- - `error_handler`
39-
40- - `type_hash`
41-
42- - `vptr`
43-
44- - `indirect_vptr`
45-
46- - `output`
47-
48- - `trace`
49-
50- - `runtime_checks`
51-
52- - `n2216`
53- */
54-
55- struct policy {};
32+ namespace policies {
5633
57- struct rtti : policy {
34+ // ! RTTI policy base class.
35+ // !
36+ // ! A @e rtti policy is responsible for acquiring and manipulating type
37+ // ! information, dynamic casting, and identifying polymorphic classes.
38+ // !
39+ // ! Class `rtti` provides a default implementation for some of these operations.
40+ // !
41+ // ! @par Requirements
42+ // !
43+ // ! A @e rtti policy must derive from class `rtti`, and contain a `fn<Registry>`
44+ // ! class template with the following public static members:
45+ // !
46+ // ! - `template<class Class> constexpr bool is_polymorphic`: evaluates to `true`
47+ // ! if `Class` is polymorphic.
48+ // !
49+ // ! - `template<class Class> type_id static_type()`: returns a `type_id`
50+ // ! for `Class`.
51+ // !
52+ // ! - `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`.
57+ // !
58+ // ! - `template<typename Stream> void type_name(type_id type, Stream&
59+ // ! stream)`: writes a description of `type` to `stream`.
60+ // !
61+ // ! - `/* unspecified */ type_index(type_id type)`: returns a @e unique
62+ // ! identifier for `type`.
63+
64+ struct rtti {
5865 using category = rtti;
5966
6067 template <class Register >
6168 struct fn {
69+ // ! Default implementation of `type_index`.
70+ // !
71+ // ! Returns `type`.
72+ // !
73+ // ! @param type A `type_id`.
6274 static auto type_index (type_id type) -> type_id {
6375 return type;
6476 }
6577
78+ // ! Default implementation of `type_name`.
79+ // !
80+ // ! Executes `stream << "type_id(" << type << ")"`.
81+ // !
82+ // ! @param type A `type_id`.
83+ // ! @param stream A stream to write to.
6684 template <typename Stream>
6785 static void type_name (type_id type, Stream& stream) {
6886 stream << " type_id(" << type << " )" ;
6987 }
7088 };
7189};
7290
91+ // ! RTTI policy base class with defered type id collection.
92+ // !
93+ // ! Some custom RTTI systems rely on static constructors to assign type ids.
94+ // ! OpenMethod itself relies on static constructors to register classes, methods
95+ // ! and overriders. This creates order-of-initialization issues. Deriving a @e
96+ // ! rtti policy from this class - instead of just `rtti` - causes the collection
97+ // ! of type ids to be deferred until the first call to @ref update.
7398struct deferred_static_rtti : rtti {};
7499
75- struct error_handler : policy {
100+ // ! Error handling policy base class.
101+ // !
102+ // ! A @e error_handler policy runs code before terminating the program due to an
103+ // ! error. This can be useful for throwing, logging, cleanup, or other actions.
104+ // !
105+ // ! @par Requirements
106+ // !
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`.
110+
111+ struct error_handler {
76112 using category = error_handler;
77113};
78114
79- struct type_hash : policy {
115+ // ! Hashing policy base class.
116+ // !
117+ // ! A @e type_hash policy calculates an integer hash for a `type_id`.
118+ // !
119+ // ! @par Requirements
120+ // !
121+ // ! A subclass of `error_handler` contains a `fn<Registry>` struct that provides
122+ // ! the following static member functions:
123+ // ! - auto initialize(ForwardIterator first, ForwardIterator last) -> [min,
124+ // ! max]: initialize the hash table with the values in the [iter, last) range.
125+ // ! `*iter` is an object of an unspecified type that has two members,
126+ // ! `type_id_begin()` and `type_id_end()`, which return iterators to a range
127+ // ! of `type_id`s. `initialize` returns a pair with the minimum and maximum
128+ // ! hash values.
129+ // ! - auto hash(type_id type) -> std::size_t: returns a hash value for `type`.
130+ // ! The value must be in the range returned by `initialize`.
131+ // ! - void finalize(): releases any resources allocated by `initialize`. This
132+ // ! member is optional.
133+
134+ struct type_hash {
80135 using category = type_hash;
81136};
82137
@@ -99,23 +154,23 @@ struct type_hash : policy {
99154
100155*/
101156
102- struct vptr : policy {
157+ struct vptr {
103158 using category = vptr;
104159};
105160
106161struct extern_vptr : vptr {};
107162
108- struct indirect_vptr : policy {
163+ struct indirect_vptr {
109164 using category = indirect_vptr;
110165 template <class Registry >
111166 struct fn {};
112167};
113168
114- struct output : policy {
169+ struct output {
115170 using category = output;
116171};
117172
118- struct trace : policy {
173+ struct trace {
119174 using category = trace;
120175 template <class Registry >
121176 struct fn {
@@ -136,20 +191,20 @@ struct trace : policy {
136191 };
137192};
138193
139- struct runtime_checks : policy {
194+ struct runtime_checks {
140195 using category = runtime_checks;
141196 template <class Registry >
142197 struct fn {};
143198};
144199
145- struct n2216 : policy {
200+ struct n2216 {
146201 using category = n2216;
147202 template <class Registry >
148203 struct fn {};
149204};
150205
151206template <typename Key>
152- struct unique : policy {
207+ struct unique {
153208 using category = unique;
154209 template <class Registry >
155210 struct fn {};
0 commit comments