Skip to content

Commit f970a16

Browse files
committed
wip
1 parent 799f52a commit f970a16

File tree

4 files changed

+108
-21
lines changed

4 files changed

+108
-21
lines changed

doc/modules/ROOT/pages/reference.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
|===
135135
| Name
136136
| Description
137-
| xref:reference:boost/openmethod/boost_openmethod_vptr.adoc[`boost_openmethod_vptr`]
137+
| xref:reference:boost/openmethod/boost_openmethod_vptr-02.adoc[`boost_openmethod_vptr`]
138138
|
139139
| xref:reference:boost/openmethod/final_virtual_ptr-04.adoc[`final_virtual_ptr`]
140140
|

doc/tagfiles/boost-openmethod-doxygen.tag.xml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<class kind="class">boost::openmethod::virtual_traits</class>
4343
<class kind="class">boost::openmethod::virtual_traits</class>
4444
<class kind="class">boost::openmethod::virtual_traits</class>
45+
<class kind="class">boost::openmethod::boost_openmethod_vptr</class>
4546
<class kind="class">boost::openmethod::final_virtual_ptr</class>
4647
<class kind="class">boost::openmethod::is_method</class>
4748
<class kind="class">boost::openmethod::is_polymorphic</class>
@@ -63,13 +64,6 @@
6364
<anchor/>
6465
<arglist>(Class* )</arglist>
6566
</member>
66-
<member kind="function">
67-
<type>vptr_type</type>
68-
<name>boost_openmethod_vptr</name>
69-
<anchorfile>boost/openmethod/boost_openmethod_vptr.adoc</anchorfile>
70-
<anchor/>
71-
<arglist>(const Class&amp; obj, detail::inplace_vptr_registry&lt;Base1&gt;* registry)</arglist>
72-
</member>
7367
<member kind="function">
7468
<type>void</type>
7569
<name>finalize</name>
@@ -416,7 +410,7 @@
416410
<name>operator[]</name>
417411
<anchorfile>boost/openmethod/compiler/operator_subs.adoc</anchorfile>
418412
<anchor/>
419-
<arglist>(const openmethod::method&lt;Id, Signature, Registry&gt;&amp; fn)</arglist>
413+
<arglist>(const openmethod::method&lt;Id, Signature, Registry&gt;&amp; )</arglist>
420414
</member>
421415
<member kind="function">
422416
<type>void</type>
@@ -914,6 +908,10 @@
914908
<arglist>(T* arg)</arglist>
915909
</member>
916910
</compound>
911+
<compound kind="class">
912+
<name>boost::openmethod::boost_openmethod_vptr</name>
913+
<filename>boost/openmethod/boost_openmethod_vptr-02.adoc</filename>
914+
</compound>
917915
<compound kind="class">
918916
<name>boost::openmethod::final_virtual_ptr</name>
919917
<filename>boost/openmethod/final_virtual_ptr-04.adoc</filename>

include/boost/openmethod/core.hpp

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ constexpr bool is_polymorphic = Registry::rtti::template is_polymorphic<Class>;
3939

4040
template<
4141
class Class, class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY,
42-
typename Void = void>
42+
typename = void>
4343
class virtual_ptr;
4444

4545
// =============================================================================
@@ -280,6 +280,8 @@ struct use_classes {
280280
tuple_type tuple;
281281
};
282282

283+
void boost_openmethod_vptr(...);
284+
283285
// =============================================================================
284286
// virtual_ptr
285287

@@ -309,8 +311,6 @@ struct is_virtual_ptr_aux<const virtual_ptr<Class, Registry, void>&>
309311
template<typename T>
310312
constexpr bool is_virtual_ptr = detail::is_virtual_ptr_aux<T>::value;
311313

312-
void boost_openmethod_vptr(...);
313-
314314
template<class Class, class Registry>
315315
constexpr bool has_vptr_fn = std::is_same_v<
316316
decltype(boost_openmethod_vptr(
@@ -390,18 +390,15 @@ inline auto final_virtual_ptr(Arg&& obj) {
390390
391391
A wide pointer combining a pointer to an object and a pointer to its v-table.
392392
393-
@par Template parameters
394-
- `Class`
395-
The class of the object.
393+
@tparam Class The class of the object.
394+
395+
@tparam Registry The registry in which `Class` is registered.
396396
397-
- `Registry`
398-
The registry in which `Class` is registered.
397+
@tparam unnamed Always `void` (used for SFINAE).
399398
400-
- `Void`
401-
Used for SFINAE in C++17. Not used in C++20 and later.
402399
*/
403400

404-
template<class Class, class Registry, typename Void>
401+
template<class Class, class Registry, typename>
405402
class virtual_ptr {
406403

407404
using traits = virtual_traits<Class&, Registry>;
@@ -424,18 +421,52 @@ class virtual_ptr {
424421
public:
425422
using element_type = Class;
426423

424+
/**
425+
Constructs a `virtual_ptr` with both object and v-table pointers
426+
initialized to `nullptr`.
427+
*/
428+
427429
virtual_ptr() = default;
428430

431+
/**
432+
Constructs a `virtual_ptr` with both object and v-table pointers
433+
initialized to `nullptr`.
434+
435+
@param value A `nullptr`.
436+
*/
437+
429438
explicit virtual_ptr(std::nullptr_t)
430439
: vp(detail::box_vptr<use_indirect_vptrs>(detail::null_vptr)),
431440
obj(nullptr) {
432441
}
433442

443+
/**
444+
Constructs a `virtual_ptr` pointing to an object of type `Other`.
445+
446+
The pointer to the v-table is obtained by calling
447+
@ref boost_openmethod_vptr if a suitable overload exists, or the
448+
@ref policies::vptr::fn::dynamic_vptr of the registry's @ref
449+
policies::vptr otherwise.
450+
451+
@ref dynamic_vptr foo
452+
453+
@param other A `nullptr`.
454+
455+
@par Requirements
456+
457+
`Other` must be a polymorphic class, according to the `Registry`'s
458+
`rtti` policy.
459+
460+
`Other*` must be convertible to `Class*`.
461+
462+
@par Errors
463+
*/
464+
434465
template<
435466
class Other,
436467
typename = std::enable_if_t<
437468
std::is_constructible_v<Class*, Other*> &&
438-
is_polymorphic<Class, Registry>>>
469+
is_polymorphic<Other, Registry>>>
439470
virtual_ptr(Other& other)
440471
: vp(detail::box_vptr<use_indirect_vptrs>(
441472
detail::acquire_vptr<Registry>(other))),

include/boost/openmethod/registry.hpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,45 @@ namespace boost::openmethod {
1313

1414
namespace policies {
1515

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:
34+
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+
1655
struct policy {};
1756

1857
struct rtti : policy {
@@ -41,6 +80,25 @@ struct type_hash : policy {
4180
using category = type_hash;
4281
};
4382

83+
/**
84+
Acquires a v-table pointer for an object.
85+
86+
@par Requirements
87+
88+
Any implementation of this policy must provide a meta-function `fn` that
89+
in the form of:
90+
91+
@code
92+
template<class Registry>
93+
struct fn {
94+
template<class Class> static auto dynamic_vptr(const Class& arg) -> const vptr_type&;
95+
};
96+
@endcode
97+
98+
@see policies::vptr_vector::fn::dynamic_vptr for an example.
99+
100+
*/
101+
44102
struct vptr : policy {
45103
using category = vptr;
46104
};

0 commit comments

Comments
 (0)