mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 04:22:12 +00:00
registry scoped boost_openmethod_vptr
This commit is contained in:
@@ -41,7 +41,7 @@ namespace virtual_intrusive {
|
||||
class Animal {
|
||||
protected:
|
||||
boost::openmethod::vptr_type vptr;
|
||||
friend auto boost_openmethod_vptr(const Animal& a) {
|
||||
friend auto boost_openmethod_vptr(const Animal& a, void*) {
|
||||
return a.vptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -301,16 +301,18 @@ constexpr bool is_virtual_ptr = detail::is_virtual_ptr_aux<T>::value;
|
||||
|
||||
void boost_openmethod_vptr(...);
|
||||
|
||||
template<class Class>
|
||||
template<class Registry, class Class>
|
||||
constexpr bool has_vptr_fn = std::is_same_v<
|
||||
decltype(boost_openmethod_vptr(std::declval<const Class&>())), vptr_type>;
|
||||
decltype(boost_openmethod_vptr(
|
||||
std::declval<const Class&>(), std::declval<Registry*>())),
|
||||
vptr_type>;
|
||||
|
||||
template<class Registry, class ArgType>
|
||||
decltype(auto) acquire_vptr(const ArgType& arg) {
|
||||
Registry::check_initialized();
|
||||
|
||||
if constexpr (detail::has_vptr_fn<ArgType>) {
|
||||
return boost_openmethod_vptr(arg);
|
||||
if constexpr (detail::has_vptr_fn<Registry, ArgType>) {
|
||||
return boost_openmethod_vptr(arg, static_cast<Registry*>(nullptr));
|
||||
} else {
|
||||
return Registry::template policy<policies::vptr>::dynamic_vptr(arg);
|
||||
}
|
||||
|
||||
@@ -15,23 +15,23 @@
|
||||
|
||||
namespace boost::openmethod {
|
||||
|
||||
namespace policies {
|
||||
|
||||
struct release : registry<
|
||||
std_rtti, fast_perfect_hash, vptr_vector,
|
||||
default_error_handler, stderr_output> {};
|
||||
|
||||
struct debug
|
||||
struct release_registry
|
||||
: registry<
|
||||
std_rtti, fast_perfect_hash, vptr_vector, default_error_handler,
|
||||
runtime_checks, stderr_output, trace> {};
|
||||
policies::std_rtti, policies::fast_perfect_hash,
|
||||
policies::vptr_vector, policies::default_error_handler,
|
||||
policies::stderr_output> {};
|
||||
|
||||
} // namespace policies
|
||||
struct debug_registry
|
||||
: registry<
|
||||
policies::std_rtti, policies::fast_perfect_hash,
|
||||
policies::vptr_vector, policies::default_error_handler,
|
||||
policies::runtime_checks, policies::stderr_output, policies::trace> {
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
using default_registry = policies::release;
|
||||
using default_registry = release_registry;
|
||||
#else
|
||||
using default_registry = policies::debug;
|
||||
using default_registry = debug_registry;
|
||||
#endif // BOOST_OPENMETHOD_DEFAULT_REGISTRY_HPP
|
||||
|
||||
} // namespace boost::openmethod
|
||||
|
||||
@@ -76,7 +76,7 @@ class with_vptr_aux<Class, Registry, true> {
|
||||
boost_openmethod_vptr = nullptr;
|
||||
}
|
||||
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type {
|
||||
friend auto boost_openmethod_vptr(const Class& obj, void*) -> vptr_type {
|
||||
if constexpr (Registry::template has_policy<policies::indirect_vptr>) {
|
||||
return *obj.boost_openmethod_vptr;
|
||||
} else {
|
||||
@@ -149,8 +149,8 @@ class with_vptr<Class, Base1, Base2, MoreBases...> : detail::with_vptr_derived {
|
||||
-> detail::with_vptr_policy<Base1>;
|
||||
friend auto boost_openmethod_bases(Class*)
|
||||
-> mp11::mp_list<Base1, Base2, MoreBases...>;
|
||||
friend auto boost_openmethod_vptr(const Class& obj) -> vptr_type {
|
||||
return boost_openmethod_vptr(static_cast<const Base1&>(obj));
|
||||
friend auto boost_openmethod_vptr(const Class& obj, void* registry) -> vptr_type {
|
||||
return boost_openmethod_vptr(static_cast<const Base1&>(obj), registry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -307,3 +307,35 @@ using meet = method<void, void(virtual_<Animal&>, virtual_<Animal&>)>;
|
||||
static_assert(has_static_offsets<meet>::value);
|
||||
|
||||
} // namespace test_static_slots
|
||||
|
||||
namespace TEST_NS {
|
||||
|
||||
struct Animal {
|
||||
friend auto boost_openmethod_vptr(const Animal&, void*) -> vptr_type;
|
||||
};
|
||||
|
||||
static_assert(detail::has_vptr_fn<default_registry, Animal>);
|
||||
|
||||
} // namespace TEST_NS
|
||||
|
||||
namespace TEST_NS {
|
||||
|
||||
using test_registry = test_registry_<__COUNTER__>;
|
||||
|
||||
const detail::word value;
|
||||
|
||||
struct Animal {
|
||||
friend auto boost_openmethod_vptr(const Animal&, test_registry*) {
|
||||
return &value;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(detail::has_vptr_fn<test_registry, Animal>);
|
||||
static_assert(!detail::has_vptr_fn<default_registry, Animal>);
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vptr_from_function) {
|
||||
initialize<test_registry>();
|
||||
BOOST_TEST(detail::acquire_vptr<test_registry>(Animal{}) == &value);
|
||||
}
|
||||
|
||||
} // namespace TEST_NS
|
||||
|
||||
@@ -72,8 +72,8 @@ struct check_illegal_smart_ops {
|
||||
|
||||
// policies must be the same
|
||||
static_assert(!std::is_constructible_v<
|
||||
virtual_ptr<smart_ptr<Animal>, policies::debug>,
|
||||
virtual_ptr<smart_ptr<Animal>, policies::release>>);
|
||||
virtual_ptr<smart_ptr<Animal>, debug_registry>,
|
||||
virtual_ptr<smart_ptr<Animal>, release_registry>>);
|
||||
|
||||
// a smart virtual_ptr cannot be constructed from a plain reference or
|
||||
// pointer
|
||||
|
||||
Reference in New Issue
Block a user