@@ -37,18 +37,6 @@ namespace boost::openmethod {
3737template <class Registry , class Class >
3838constexpr bool is_polymorphic = Registry::rtti::template is_polymorphic<Class>;
3939
40-
41- // ! The `virtual_ptr` template represents a set of bits.
42- // !
43- // ! \par Template parameters
44- // ! - `Class`
45- // ! A class registered in `Registry
46- // !
47- // ! - `Registry`
48- // !
49- // ! - `Void`
50- // !
51-
5240template <
5341 class Class , class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY,
5442 typename Void = void >
@@ -416,6 +404,21 @@ inline auto final_virtual_ptr(Arg&& obj) {
416404 std::forward<Arg>(obj));
417405}
418406
407+ /* *
408+
409+ A wide pointer combining a pointer to an object and a pointer to its v-table.
410+
411+ @par Template parameters
412+ - `Class`
413+ The class of the object.
414+
415+ - `Registry`
416+ The registry in which `Class` is registered.
417+
418+ - `Void`
419+ Used for SFINAE in C++17. Not used in C++20 and later.
420+ */
421+
419422template <class Class , class Registry , typename Void>
420423class virtual_ptr {
421424 template <class , class , typename >
@@ -457,7 +460,7 @@ class virtual_ptr {
457460 typename = std::enable_if_t <
458461 std::is_constructible_v<
459462 Class*,
460- decltype (std::declval< virtual_ptr<Other, Registry>>().get()) > &&
463+ typename virtual_ptr<Other, Registry>::element_type* > &&
461464 is_polymorphic<Registry, Class>>>
462465 virtual_ptr (Other* other)
463466 : vp(detail::box_vptr<use_indirect_vptrs>(
@@ -469,7 +472,7 @@ class virtual_ptr {
469472 class Other ,
470473 typename = std::enable_if_t <std::is_constructible_v<
471474 Class*,
472- decltype (std::declval< virtual_ptr<Other, Registry>>().get()) >>>
475+ typename virtual_ptr<Other, Registry>::element_type* >>>
473476 virtual_ptr (const virtual_ptr<Other, Registry>& other)
474477 : vp(other.vp), obj(other.get()) {
475478 }
@@ -478,7 +481,7 @@ class virtual_ptr {
478481 class Other ,
479482 typename = std::enable_if_t <std::is_constructible_v<
480483 Class*,
481- decltype (std::declval< virtual_ptr<Other, Registry>>().get()) >>>
484+ typename virtual_ptr<Other, Registry>::element_type* >>>
482485 virtual_ptr (virtual_ptr<Other, Registry>& other)
483486 : vp(other.vp), obj(other.get()) {
484487 // Why is this needed? Consider this conversion conversion from
@@ -525,7 +528,7 @@ class virtual_ptr {
525528 class Other ,
526529 typename = std::enable_if_t <std::is_assignable_v<
527530 Class*,
528- decltype (std::declval< virtual_ptr<Other, Registry>>().get()) >>>
531+ typename virtual_ptr<Other, Registry>::element_type* >>>
529532 virtual_ptr& operator =(const virtual_ptr<Other, Registry>& other) {
530533 obj = other.get ();
531534 vp = other.vp ;
@@ -563,9 +566,6 @@ class virtual_ptr {
563566 traits::template cast<Other&>(*obj), vp);
564567 }
565568
566- template <class , class >
567- friend struct virtual_traits ;
568-
569569 template <class Other >
570570 static auto final (Other&& obj) {
571571 return final_virtual_ptr<Registry>(std::forward<Other>(obj));
0 commit comments