mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 04:22:12 +00:00
with_vptr -> inplace_vptr
This commit is contained in:
@@ -8,7 +8,7 @@ called to rebuild the dispatch tables.
|
||||
|
||||
This leads to a problem: any `virtual_ptr` in existence before `initialize` is
|
||||
called again becomes invalid. This also applies to vptrs that are stored inside
|
||||
objects by `with_vptr`.
|
||||
objects by `inplace_vptr`.
|
||||
|
||||
NOTE: This applies only to cases where a dynamic library adds to an _existing_
|
||||
policy. Even if the dynamic library itself uses open-methods, for example as an
|
||||
|
||||
@@ -610,7 +610,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
|
||||
<li><a href="#virtual_ptr_description_4">Description</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#virtual_ptr_with_vptr">with_vptr</a>
|
||||
<li><a href="#virtual_ptr_inplace_vptr">inplace_vptr</a>
|
||||
<ul class="sectlevel3">
|
||||
<li><a href="#virtual_ptr_synopsis_5">Synopsis</a></li>
|
||||
<li><a href="#virtual_ptr_description_5">Description</a></li>
|
||||
@@ -1961,17 +1961,17 @@ required by the library.
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>with_vptr</code> CRTP class automates the creation and management of embedded
|
||||
<p>The <code>inplace_vptr</code> CRTP class automates the creation and management of embedded
|
||||
vptrs.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="rouge highlight"><code data-lang="c++">#include <boost/openmethod/with_vptr.hpp>
|
||||
<pre class="rouge highlight"><code data-lang="c++">#include <boost/openmethod/inplace_vptr.hpp>
|
||||
|
||||
class Animal : public boost::openmethod::with_vptr<Animal> {
|
||||
class Animal : public boost::openmethod::inplace_vptr<Animal> {
|
||||
};
|
||||
|
||||
class Cat : public Animal, public boost::openmethod::with_vptr<Cat, Animal> {
|
||||
class Cat : public Animal, public boost::openmethod::inplace_vptr<Cat, Animal> {
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void);
|
||||
@@ -1989,11 +1989,11 @@ int main() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If <code>with_vptr</code> is passed only the class being defined, it adds a vptr to it, and
|
||||
<p>If <code>inplace_vptr</code> is passed only the class being defined, it adds a vptr to it, and
|
||||
defines a <code>boost_openmethod_vptr</code> friend function. If more classes are passed,
|
||||
they must be the direct bases of the class potentially involved in open-method
|
||||
calls. Its constructor and destructor set the vptr to point to the v-table for
|
||||
the class. <code>with_vptr</code> also takes care of registering the classes, so this time
|
||||
the class. <code>inplace_vptr</code> also takes care of registering the classes, so this time
|
||||
the call to <code>BOOST_OPENMETHOD_CLASSES</code> is not needed.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2787,7 +2787,7 @@ called to rebuild the dispatch tables.</p>
|
||||
<div class="paragraph">
|
||||
<p>This leads to a problem: any <code>virtual_ptr</code> in existence before <code>initialize</code> is
|
||||
called again becomes invalid. This also applies to vptrs that are stored inside
|
||||
objects by <code>with_vptr</code>.</p>
|
||||
objects by <code>inplace_vptr</code>.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
@@ -3131,7 +3131,7 @@ virtual parameters.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="ref_boostopenmethodwith_vptr_hpp"><boost/openmethod/with_vptr.hpp></h5>
|
||||
<h5 id="ref_boostopenmethodinplace_vptr_hpp"><boost/openmethod/inplace_vptr.hpp></h5>
|
||||
<div class="paragraph">
|
||||
<p>Provides support for storing v-table pointers directly in objects, in the same
|
||||
manner as native virtual functions.</p>
|
||||
@@ -4811,29 +4811,29 @@ more information.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="virtual_ptr_with_vptr">with_vptr</h3>
|
||||
<h3 id="virtual_ptr_inplace_vptr">inplace_vptr</h3>
|
||||
<div class="sect3">
|
||||
<h4 id="virtual_ptr_synopsis_5">Synopsis</h4>
|
||||
<div class="paragraph">
|
||||
<p>Defined in <boost/openmethod/with_vptr.hpp>.</p>
|
||||
<p>Defined in <boost/openmethod/inplace_vptr.hpp>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="rouge highlight"><code data-lang="c++">namespace boost::openmethod {
|
||||
|
||||
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
|
||||
class with_vptr {
|
||||
class inplace_vptr {
|
||||
protected:
|
||||
with_vptr();
|
||||
~with_vptr();
|
||||
inplace_vptr();
|
||||
~inplace_vptr();
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type;
|
||||
};
|
||||
|
||||
template<class Class, class Base, class... MoreBases>
|
||||
class with_vptr {
|
||||
class inplace_vptr {
|
||||
protected:
|
||||
with_vptr();
|
||||
~with_vptr();
|
||||
inplace_vptr();
|
||||
~inplace_vptr();
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type;
|
||||
// if sizeof(MoreBases...) > 0
|
||||
};
|
||||
@@ -4845,11 +4845,11 @@ class with_vptr {
|
||||
<div class="sect3">
|
||||
<h4 id="virtual_ptr_description_5">Description</h4>
|
||||
<div class="paragraph">
|
||||
<p><code>with_vptr</code> is a CRTP class template that embeds and manages a vptr across a
|
||||
<p><code>inplace_vptr</code> is a CRTP class template that embeds and manages a vptr across a
|
||||
class hierarchy.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If <code>Class</code> has no <code>Bases</code>, <code>with_vptr</code> adds a <code>boost_openmethod_vptr</code> private
|
||||
<p>If <code>Class</code> has no <code>Bases</code>, <code>inplace_vptr</code> adds a <code>boost_openmethod_vptr</code> private
|
||||
member to <code>Class</code>. In either case, it sets the vptr to the v-table of <code>Class</code>
|
||||
from <code>Policy</code>. It also creates a <code>boost_openmethod_vptr</code> friend function that
|
||||
takes a a <code>const Class&</code> and returns the embedded vptr.</p>
|
||||
@@ -4861,7 +4861,7 @@ matter which one, as they all have the same value). This is to resolve
|
||||
ambiguities</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>As part of its implementation, <code>with_vptr</code> may also declare one or two free
|
||||
<p>As part of its implementation, <code>inplace_vptr</code> may also declare one or two free
|
||||
functions (<code>boost_openmethod_policy</code> and <code>boost_openmethod_bases</code>) at certain
|
||||
levels of the hierarchy.</p>
|
||||
</div>
|
||||
@@ -4872,7 +4872,7 @@ levels of the hierarchy.</p>
|
||||
<h5 id="virtual_ptr_constructor_2">constructor</h5>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="rouge highlight"><code data-lang="c++">with_vptr();</code></pre>
|
||||
<pre class="rouge highlight"><code data-lang="c++">inplace_vptr();</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -4885,7 +4885,7 @@ preserving the validity of the pointer across calls to <code>initialize</code>.<
|
||||
<h5 id="virtual_ptr_destructor_2">destructor</h5>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="rouge highlight"><code data-lang="c++">~with_vptr();</code></pre>
|
||||
<pre class="rouge highlight"><code data-lang="c++">~inplace_vptr();</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -5612,7 +5612,7 @@ the same.</p>
|
||||
<div class="sect3">
|
||||
<h4 id="virtual_ptr_description_15">Description</h4>
|
||||
<div class="paragraph">
|
||||
<p><code>indirect_vptr</code> is a facet that makes <code>virtual_ptr</code>s and <code>with_vptr</code> use
|
||||
<p><code>indirect_vptr</code> is a facet that makes <code>virtual_ptr</code>s and <code>inplace_vptr</code> use
|
||||
pointers to pointers to v-tables, instead of straight pointers. As a
|
||||
consequence, they remain valid after a call to <code>initialize</code>.</p>
|
||||
</div>
|
||||
@@ -6249,7 +6249,7 @@ the library uses a lightweight implementation based on the C stream functions.</
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2025-03-08 15:24:21 -0500
|
||||
Last updated 2025-06-22 13:38:14 -0400
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
|
||||
## with_vptr
|
||||
## inplace_vptr
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/with_vptr.hpp>.
|
||||
Defined in <boost/openmethod/inplace_vptr.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod {
|
||||
|
||||
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
|
||||
class with_vptr {
|
||||
class inplace_vptr {
|
||||
protected:
|
||||
with_vptr();
|
||||
~with_vptr();
|
||||
inplace_vptr();
|
||||
~inplace_vptr();
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type;
|
||||
};
|
||||
|
||||
template<class Class, class Base, class... MoreBases>
|
||||
class with_vptr {
|
||||
class inplace_vptr {
|
||||
protected:
|
||||
with_vptr();
|
||||
~with_vptr();
|
||||
inplace_vptr();
|
||||
~inplace_vptr();
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type;
|
||||
// if sizeof(MoreBases...) > 0
|
||||
};
|
||||
@@ -30,10 +30,10 @@ class with_vptr {
|
||||
|
||||
### Description
|
||||
|
||||
`with_vptr` is a CRTP class template that embeds and manages a vptr across a
|
||||
`inplace_vptr` is a CRTP class template that embeds and manages a vptr across a
|
||||
class hierarchy.
|
||||
|
||||
If `Class` has no `Bases`, `with_vptr` adds a `boost_openmethod_vptr` private
|
||||
If `Class` has no `Bases`, `inplace_vptr` adds a `boost_openmethod_vptr` private
|
||||
member to `Class`. In either case, it sets the vptr to the v-table of `Class`
|
||||
from `Policy`. It also creates a `boost_openmethod_vptr` friend function that
|
||||
takes a a `const Class&` and returns the embedded vptr.
|
||||
@@ -43,7 +43,7 @@ function is also created. It returns one of the embedded vptrs (it doesn't
|
||||
matter which one, as they all have the same value). This is to resolve
|
||||
ambiguities
|
||||
|
||||
As part of its implementation, `with_vptr` may also declare one or two free
|
||||
As part of its implementation, `inplace_vptr` may also declare one or two free
|
||||
functions (`boost_openmethod_policy` and `boost_openmethod_bases`) at certain
|
||||
levels of the hierarchy.
|
||||
|
||||
@@ -52,7 +52,7 @@ levels of the hierarchy.
|
||||
#### constructor
|
||||
|
||||
```c++
|
||||
with_vptr();
|
||||
inplace_vptr();
|
||||
```
|
||||
|
||||
Sets the vptr to the v-table for Class, obtained from `Policy`. If `Policy`
|
||||
@@ -63,7 +63,7 @@ preserving the validity of the pointer across calls to `initialize`.
|
||||
#### destructor
|
||||
|
||||
```c++
|
||||
~with_vptr();
|
||||
~inplace_vptr();
|
||||
```
|
||||
|
||||
For each `Base`, sets the vptr to the v-table for that base.
|
||||
@@ -83,7 +83,7 @@ virtual parameters.
|
||||
Provides support for using `std::unique_ptr` in place of plain pointers in
|
||||
virtual parameters.
|
||||
|
||||
#### <boost/openmethod/with_vptr.hpp>
|
||||
#### <boost/openmethod/inplace_vptr.hpp>
|
||||
|
||||
Provides support for storing v-table pointers directly in objects, in the same
|
||||
manner as native virtual functions.
|
||||
|
||||
@@ -27,7 +27,7 @@ include::virtual_ptr.adoc[]
|
||||
include::virtual_traits.adoc[]
|
||||
include::use_classes.adoc[]
|
||||
include::virtual_.adoc[]
|
||||
include::with_vptr.adoc[]
|
||||
include::inplace_vptr.adoc[]
|
||||
include::abstract_policy.adoc[]
|
||||
include::domain.adoc[]
|
||||
include::basic_policy.adoc[]
|
||||
|
||||
@@ -53,12 +53,12 @@ NOTE: With this approach, classes need not be polymorphic. A virtual
|
||||
destructor might be needed for correct destruction of objects, but it is not
|
||||
required by the library.
|
||||
|
||||
The `with_vptr` CRTP class automates the creation and management of embedded
|
||||
The `inplace_vptr` CRTP class automates the creation and management of embedded
|
||||
vptrs.
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{exampledir}/virtual_.cpp[tag=with_vptr,indent=0]
|
||||
include::{exampledir}/virtual_.cpp[tag=inplace_vptr,indent=0]
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
@@ -68,9 +68,9 @@ int main() {
|
||||
}
|
||||
----
|
||||
|
||||
If `with_vptr` is passed only the class being defined, it adds a vptr to it, and
|
||||
If `inplace_vptr` is passed only the class being defined, it adds a vptr to it, and
|
||||
defines a `boost_openmethod_vptr` friend function. If more classes are passed,
|
||||
they must be the direct bases of the class potentially involved in open-method
|
||||
calls. Its constructor and destructor set the vptr to point to the v-table for
|
||||
the class. `with_vptr` also takes care of registering the classes, so this time
|
||||
the class. `inplace_vptr` also takes care of registering the classes, so this time
|
||||
the call to `BOOST_OPENMETHOD_CLASSES` is not needed.
|
||||
|
||||
@@ -55,7 +55,7 @@ struct indirect_vptr : facet {};
|
||||
|
||||
### Description
|
||||
|
||||
`indirect_vptr` is a facet that makes `virtual_ptr`{empty}s and `with_vptr` use
|
||||
`indirect_vptr` is a facet that makes `virtual_ptr`{empty}s and `inplace_vptr` use
|
||||
pointers to pointers to v-tables, instead of straight pointers. As a
|
||||
consequence, they remain valid after a call to `initialize`.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/with_vptr.hpp>
|
||||
#include <boost/openmethod/inplace_vptr.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
|
||||
using boost::openmethod::virtual_;
|
||||
@@ -68,16 +68,16 @@ BOOST_OPENMETHOD_CLASSES(Animal, Cat);
|
||||
// end::virtual_intrusive[]
|
||||
} // namespace virtual_intrusive
|
||||
|
||||
namespace with_vptr {
|
||||
namespace inplace_vptr {
|
||||
|
||||
// tag::with_vptr[]
|
||||
// tag::inplace_vptr[]
|
||||
|
||||
#include <boost/openmethod/with_vptr.hpp>
|
||||
#include <boost/openmethod/inplace_vptr.hpp>
|
||||
|
||||
class Animal : public boost::openmethod::with_vptr<Animal> {
|
||||
class Animal : public boost::openmethod::inplace_vptr<Animal> {
|
||||
};
|
||||
|
||||
class Cat : public Animal, public boost::openmethod::with_vptr<Cat, Animal> {
|
||||
class Cat : public Animal, public boost::openmethod::inplace_vptr<Cat, Animal> {
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void);
|
||||
@@ -85,9 +85,9 @@ BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void);
|
||||
BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& /*cat*/), void) {
|
||||
os << "hiss\n";
|
||||
}
|
||||
// end::with_vptr[]
|
||||
// end::inplace_vptr[]
|
||||
|
||||
} // namespace with_vptr
|
||||
} // namespace inplace_vptr
|
||||
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
@@ -105,7 +105,7 @@ auto main() -> int {
|
||||
}
|
||||
|
||||
{
|
||||
using namespace with_vptr;
|
||||
using namespace inplace_vptr;
|
||||
Cat cat;
|
||||
poke(std::cout, cat); // hiss
|
||||
}
|
||||
|
||||
@@ -981,8 +981,8 @@ template<typename T, class Registry>
|
||||
struct valid_method_parameter<virtual_<T>, Registry>
|
||||
: std::bool_constant<
|
||||
has_vptr_fn<virtual_type<T, Registry>, Registry> ||
|
||||
Registry::rtti::template is_polymorphic<
|
||||
virtual_type<T, Registry>>> {};
|
||||
Registry::rtti::template is_polymorphic<virtual_type<T, Registry>>> {
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef BOOST_OPENMETHOD_WITH_VPTR_HPP
|
||||
#define BOOST_OPENMETHOD_WITH_VPTR_HPP
|
||||
#ifndef BOOST_OPENMETHOD_inplace_vptr_HPP
|
||||
#define BOOST_OPENMETHOD_inplace_vptr_HPP
|
||||
|
||||
#include <boost/openmethod/core.hpp>
|
||||
|
||||
// =============================================================================
|
||||
// with_vptr
|
||||
// inplace_vptr
|
||||
|
||||
namespace boost::openmethod {
|
||||
|
||||
@@ -14,7 +14,7 @@ void boost_openmethod_registry(...);
|
||||
void boost_openmethod_bases(...);
|
||||
|
||||
template<class Class>
|
||||
using with_vptr_registry =
|
||||
using inplace_vptr_registry =
|
||||
decltype(boost_openmethod_registry(std::declval<Class*>()));
|
||||
|
||||
template<class>
|
||||
@@ -33,7 +33,7 @@ struct update_vptr_bases<mp11::mp_list<Bases...>> {
|
||||
|
||||
template<class To, class Class>
|
||||
void update_vptr(Class* obj) {
|
||||
using registry = with_vptr_registry<Class>;
|
||||
using registry = inplace_vptr_registry<Class>;
|
||||
using bases = decltype(boost_openmethod_bases(obj));
|
||||
|
||||
if constexpr (mp11::mp_size<bases>::value == 0) {
|
||||
@@ -47,32 +47,32 @@ void update_vptr(Class* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
struct with_vptr_derived {};
|
||||
struct inplace_vptr_derived {};
|
||||
|
||||
template<class, class, bool>
|
||||
class with_vptr_aux;
|
||||
class inplace_vptr_aux;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic ignored "-Wnon-template-friend"
|
||||
#endif
|
||||
|
||||
template<class... Classes>
|
||||
inline use_classes<Classes...> with_vptr_use_classes;
|
||||
inline use_classes<Classes...> inplace_vptr_use_classes;
|
||||
|
||||
template<class Class, class Registry>
|
||||
class with_vptr_aux<Class, Registry, true> {
|
||||
class inplace_vptr_aux<Class, Registry, true> {
|
||||
protected:
|
||||
template<class To, class Other>
|
||||
friend void update_vptr(Other*);
|
||||
friend auto boost_openmethod_registry(Class*) -> Registry;
|
||||
friend auto boost_openmethod_bases(Class*) -> mp11::mp_list<>;
|
||||
|
||||
with_vptr_aux() {
|
||||
(void)&with_vptr_use_classes<Class, Registry>;
|
||||
inplace_vptr_aux() {
|
||||
(void)&inplace_vptr_use_classes<Class, Registry>;
|
||||
detail::update_vptr<Class>(static_cast<Class*>(this));
|
||||
}
|
||||
|
||||
~with_vptr_aux() {
|
||||
~inplace_vptr_aux() {
|
||||
boost_openmethod_vptr = nullptr;
|
||||
}
|
||||
|
||||
@@ -92,16 +92,17 @@ class with_vptr_aux<Class, Registry, true> {
|
||||
};
|
||||
|
||||
template<class Class, class Base>
|
||||
class with_vptr_aux<Class, Base, false> : with_vptr_derived {
|
||||
class inplace_vptr_aux<Class, Base, false> : inplace_vptr_derived {
|
||||
protected:
|
||||
friend void update_vptr(Class*);
|
||||
|
||||
with_vptr_aux() {
|
||||
(void)&with_vptr_use_classes<Class, Base, with_vptr_registry<Class>>;
|
||||
inplace_vptr_aux() {
|
||||
(void)&inplace_vptr_use_classes<
|
||||
Class, Base, inplace_vptr_registry<Class>>;
|
||||
detail::update_vptr<Class>(static_cast<Class*>(this));
|
||||
}
|
||||
|
||||
~with_vptr_aux() {
|
||||
~inplace_vptr_aux() {
|
||||
detail::update_vptr<Base>(
|
||||
static_cast<Base*>(static_cast<Class*>(this)));
|
||||
}
|
||||
@@ -112,18 +113,21 @@ class with_vptr_aux<Class, Base, false> : with_vptr_derived {
|
||||
} // namespace detail
|
||||
|
||||
template<typename...>
|
||||
class with_vptr;
|
||||
class inplace_vptr;
|
||||
|
||||
template<class Class>
|
||||
class with_vptr<Class> : public detail::with_vptr_aux<
|
||||
Class, BOOST_OPENMETHOD_DEFAULT_REGISTRY, true> {};
|
||||
class inplace_vptr<Class>
|
||||
: public detail::inplace_vptr_aux<
|
||||
Class, BOOST_OPENMETHOD_DEFAULT_REGISTRY, true> {};
|
||||
|
||||
template<class Class, class Other>
|
||||
class with_vptr<Class, Other>
|
||||
: public detail::with_vptr_aux<Class, Other, detail::is_registry<Other>> {};
|
||||
class inplace_vptr<Class, Other>
|
||||
: public detail::inplace_vptr_aux<
|
||||
Class, Other, detail::is_registry<Other>> {};
|
||||
|
||||
template<class Class, class Base1, class Base2, class... MoreBases>
|
||||
class with_vptr<Class, Base1, Base2, MoreBases...> : detail::with_vptr_derived {
|
||||
class inplace_vptr<Class, Base1, Base2, MoreBases...>
|
||||
: detail::inplace_vptr_derived {
|
||||
|
||||
static_assert(
|
||||
!detail::is_registry<Base1> && !detail::is_registry<Base2> &&
|
||||
@@ -131,14 +135,14 @@ class with_vptr<Class, Base1, Base2, MoreBases...> : detail::with_vptr_derived {
|
||||
"registry can be specified only for root classes");
|
||||
|
||||
protected:
|
||||
with_vptr() {
|
||||
(void)&detail::with_vptr_use_classes<
|
||||
inplace_vptr() {
|
||||
(void)&detail::inplace_vptr_use_classes<
|
||||
Class, Base1, Base2, MoreBases...,
|
||||
detail::with_vptr_registry<Base1>>;
|
||||
detail::inplace_vptr_registry<Base1>>;
|
||||
detail::update_vptr<Class>(static_cast<Class*>(this));
|
||||
}
|
||||
|
||||
~with_vptr() {
|
||||
~inplace_vptr() {
|
||||
auto obj = static_cast<Class*>(this);
|
||||
detail::update_vptr<Base1>(static_cast<Base1*>(obj));
|
||||
detail::update_vptr<Base2>(static_cast<Base2*>(obj));
|
||||
@@ -146,11 +150,11 @@ class with_vptr<Class, Base1, Base2, MoreBases...> : detail::with_vptr_derived {
|
||||
}
|
||||
|
||||
friend auto boost_openmethod_registry(Class*)
|
||||
-> detail::with_vptr_registry<Base1>;
|
||||
-> detail::inplace_vptr_registry<Base1>;
|
||||
friend auto boost_openmethod_bases(Class*)
|
||||
-> mp11::mp_list<Base1, Base2, MoreBases...>;
|
||||
friend auto boost_openmethod_vptr(
|
||||
const Class& obj, detail::with_vptr_registry<Base1>* registry)
|
||||
const Class& obj, detail::inplace_vptr_registry<Base1>* registry)
|
||||
-> vptr_type {
|
||||
return boost_openmethod_vptr(static_cast<const Base1&>(obj), registry);
|
||||
}
|
||||
@@ -158,4 +162,4 @@ class with_vptr<Class, Base1, Base2, MoreBases...> : detail::with_vptr_derived {
|
||||
|
||||
} // namespace boost::openmethod
|
||||
|
||||
#endif // BOOST_OPENMETHOD_WITH_VPTR_HPP
|
||||
#endif // BOOST_OPENMETHOD_inplace_vptr_HPP
|
||||
@@ -9,4 +9,5 @@ using namespace boost::openmethod;
|
||||
|
||||
struct Cat {};
|
||||
|
||||
BOOST_OPENMETHOD(poke, (virtual_ptr<Cat, release_registry>), void, debug_registry);
|
||||
BOOST_OPENMETHOD(
|
||||
poke, (virtual_ptr<Cat, release_registry>), void, debug_registry);
|
||||
|
||||
@@ -16,7 +16,7 @@ using namespace boost::openmethod::detail;
|
||||
namespace mp11 = boost::mp11;
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/with_vptr.hpp>
|
||||
#include <boost/openmethod/inplace_vptr.hpp>
|
||||
#include <boost/openmethod/shared_ptr.hpp>
|
||||
|
||||
#include "test_util.hpp"
|
||||
@@ -149,17 +149,18 @@ struct non_polymorphic {};
|
||||
static_assert(!valid_method_parameter<
|
||||
virtual_<non_polymorphic&>, default_registry>::value);
|
||||
|
||||
struct non_polymorphic_with_vptr {};
|
||||
struct non_polymorphic_inplace_vptr {};
|
||||
|
||||
auto boost_openmethod_vptr(const non_polymorphic_with_vptr&, void*)
|
||||
auto boost_openmethod_vptr(const non_polymorphic_inplace_vptr&, void*)
|
||||
-> vptr_type;
|
||||
|
||||
static_assert(valid_method_parameter<
|
||||
virtual_<non_polymorphic_with_vptr&>, default_registry>::value);
|
||||
|
||||
static_assert(
|
||||
valid_method_parameter<
|
||||
virtual_<const non_polymorphic_with_vptr&>, default_registry>::value);
|
||||
virtual_<non_polymorphic_inplace_vptr&>, default_registry>::value);
|
||||
|
||||
static_assert(valid_method_parameter<
|
||||
virtual_<const non_polymorphic_inplace_vptr&>,
|
||||
default_registry>::value);
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ struct test_registry
|
||||
#define BOOST_OPENMETHOD_DEFAULT_REGISTRY test_registry
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/with_vptr.hpp>
|
||||
#include <boost/openmethod/inplace_vptr.hpp>
|
||||
#include <boost/openmethod/shared_ptr.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
|
||||
@@ -26,25 +26,25 @@ struct test_registry
|
||||
namespace bom = boost::openmethod;
|
||||
using bom::virtual_;
|
||||
|
||||
struct Animal : bom::with_vptr<Animal> {
|
||||
struct Animal : bom::inplace_vptr<Animal> {
|
||||
explicit Animal(std::ostream& os);
|
||||
~Animal();
|
||||
std::ostream& os;
|
||||
};
|
||||
|
||||
struct Cat : Animal, bom::with_vptr<Cat, Animal> {
|
||||
struct Cat : Animal, bom::inplace_vptr<Cat, Animal> {
|
||||
explicit Cat(std::ostream& os);
|
||||
~Cat();
|
||||
};
|
||||
|
||||
struct Pet : bom::with_vptr<Pet> {
|
||||
struct Pet : bom::inplace_vptr<Pet> {
|
||||
explicit Pet(std::ostream& os);
|
||||
~Pet();
|
||||
std::string name;
|
||||
std::ostream& os;
|
||||
};
|
||||
|
||||
struct DomesticCat : Cat, Pet, bom::with_vptr<DomesticCat, Cat, Pet> {
|
||||
struct DomesticCat : Cat, Pet, bom::inplace_vptr<DomesticCat, Cat, Pet> {
|
||||
explicit DomesticCat(std::ostream& os);
|
||||
~DomesticCat();
|
||||
};
|
||||
@@ -182,8 +182,8 @@ BOOST_AUTO_TEST_CASE(intrusive_mode) {
|
||||
|
||||
struct indirect_policy : test_registry::with<bom::policies::indirect_vptr> {};
|
||||
|
||||
struct Indirect : bom::with_vptr<Indirect, indirect_policy> {
|
||||
using bom::with_vptr<Indirect, indirect_policy>::boost_openmethod_vptr;
|
||||
struct Indirect : bom::inplace_vptr<Indirect, indirect_policy> {
|
||||
using bom::inplace_vptr<Indirect, indirect_policy>::boost_openmethod_vptr;
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(whatever, (virtual_<Indirect&>), void, indirect_policy);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#define BOOST_TEST_MODULE static_list
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user