registry scoped boost_openmethod_vptr

This commit is contained in:
Jean-Louis Leroy
2025-06-20 19:04:46 -04:00
parent e1658db6d1
commit a0720ca8b6
6 changed files with 56 additions and 22 deletions

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}
};

View File

@@ -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

View File

@@ -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