mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 04:22:12 +00:00
fix indirect virtual_ptr::final
This commit is contained in:
committed by
Jean-Louis Leroy
parent
e80d443dbf
commit
da937900d9
@@ -357,14 +357,18 @@ inline vptr_type null_vptr = nullptr;
|
||||
|
||||
template<class Class, class Registry, typename = void>
|
||||
class virtual_ptr_impl {
|
||||
protected:
|
||||
static constexpr bool use_indirect_vptrs =
|
||||
Registry::template has_policy<policies::indirect_vptr>;
|
||||
|
||||
std::conditional_t<use_indirect_vptrs, const vptr_type*, vptr_type> vp;
|
||||
Class* obj;
|
||||
|
||||
public:
|
||||
using traits = virtual_traits<Class&, Registry>;
|
||||
using element_type = Class;
|
||||
static constexpr bool is_smart_ptr = false;
|
||||
|
||||
static constexpr bool use_indirect_vptrs =
|
||||
Registry::template has_policy<policies::indirect_vptr>;
|
||||
|
||||
virtual_ptr_impl() = default;
|
||||
|
||||
explicit virtual_ptr_impl(std::nullptr_t)
|
||||
@@ -422,8 +426,7 @@ class virtual_ptr_impl {
|
||||
template<
|
||||
class Other,
|
||||
typename = std::enable_if_t<std::is_constructible_v<Class*, Other*>>>
|
||||
virtual_ptr_impl(Other& other, const vptr_type& vp)
|
||||
: vp(box_vptr<use_indirect_vptrs>(vp)), obj(&other) {
|
||||
virtual_ptr_impl(Other& other, decltype(vp) vp) : vp(vp), obj(&other) {
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -488,15 +491,11 @@ class virtual_ptr_impl {
|
||||
std::is_base_of_v<Class, Other> || std::is_base_of_v<Other, Class>);
|
||||
|
||||
return virtual_ptr<Other, Registry>(
|
||||
traits::template cast<Other&>(*obj), unbox_vptr(vp));
|
||||
traits::template cast<Other&>(*obj), vp);
|
||||
}
|
||||
|
||||
template<class, class>
|
||||
friend struct virtual_traits;
|
||||
|
||||
protected:
|
||||
std::conditional_t<use_indirect_vptrs, const vptr_type*, vptr_type> vp;
|
||||
Class* obj;
|
||||
};
|
||||
|
||||
template<class Class, class Other, class Registry, typename = void>
|
||||
@@ -576,6 +575,12 @@ class virtual_ptr_impl<
|
||||
obj(other) {
|
||||
}
|
||||
|
||||
template<
|
||||
class Other,
|
||||
typename = std::enable_if_t<std::is_constructible_v<Class*, Other*>>>
|
||||
virtual_ptr_impl(Other& other, decltype(vp) vp) : vp(vp), obj(&other) {
|
||||
}
|
||||
|
||||
template<
|
||||
class Other,
|
||||
typename = std::enable_if_t<
|
||||
@@ -621,6 +626,11 @@ class virtual_ptr_impl<
|
||||
other.vp = box_vptr<use_indirect_vptrs>(null_vptr);
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
virtual_ptr_impl(Arg&& obj, decltype(vp) vp)
|
||||
: vp(vp), obj(std::forward<Arg>(obj)) {
|
||||
}
|
||||
|
||||
virtual_ptr_impl& operator=(std::nullptr_t) {
|
||||
obj = nullptr;
|
||||
vp = box_vptr<use_indirect_vptrs>(null_vptr);
|
||||
@@ -705,11 +715,6 @@ class virtual_ptr_impl<
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
virtual_ptr_impl(Arg&& obj, decltype(vp) other_vp)
|
||||
: vp(other_vp), obj(std::forward<Arg>(obj)) {
|
||||
}
|
||||
|
||||
template<class Other>
|
||||
auto cast() & -> decltype(auto) {
|
||||
static_assert(
|
||||
@@ -803,7 +808,7 @@ class virtual_ptr : public detail::virtual_ptr_impl<Class, Registry> {
|
||||
|
||||
return virtual_ptr(
|
||||
std::forward<Other>(obj),
|
||||
detail::box_vptr<impl::use_indirect_vptrs>(
|
||||
box_vptr<impl::use_indirect_vptrs>(
|
||||
Registry::template static_vptr<other_class>));
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,8 @@ auto fight_bear(VirtualWarriorPtr, VirtualAxePtr, VirtualBearPtr) {
|
||||
}
|
||||
|
||||
template<int N>
|
||||
struct indirect_test_registry : test_registry_<N> {};
|
||||
struct indirect_test_registry
|
||||
: test_registry_<N>::template with<policies::indirect_vptr> {};
|
||||
|
||||
template<int N>
|
||||
using policy_types =
|
||||
@@ -230,12 +231,13 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
|
||||
Player player;
|
||||
auto virtual_player = vptr_player::final(player);
|
||||
BOOST_TEST(&*virtual_player == &player);
|
||||
BOOST_TEST((virtual_player.vptr() == Registry::template static_vptr<Player>));
|
||||
BOOST_TEST(
|
||||
(virtual_player.vptr() == Registry::template static_vptr<Player>));
|
||||
|
||||
Bear bear;
|
||||
BOOST_TEST((&*vptr_bear::final(bear)) == &bear);
|
||||
BOOST_TEST(
|
||||
(vptr_bear::final(bear).vptr() == Registry::template static_vptr<Bear>));
|
||||
BOOST_TEST((
|
||||
vptr_bear::final(bear).vptr() == Registry::template static_vptr<Bear>));
|
||||
|
||||
BOOST_TEST(
|
||||
(vptr_player(bear).vptr() == Registry::template static_vptr<Bear>));
|
||||
|
||||
Reference in New Issue
Block a user