@@ -529,11 +529,12 @@ inline auto final_virtual_ptr(Arg&& obj) {
529529// !
530530// ! `virtual_ptr` is a wide pointer that combines a pointer to an object and a
531531// ! pointer to its v-table. It can be constructed from a reference, a pointer,
532- // ! or another `virtual_ptr`.
532+ // ! or another (possibly smart) `virtual_ptr`.
533533// !
534534// ! Calls to methods via `virtual_ptr` are as fast as ordinary virtual function
535535// ! calls (typically two instructions).
536536// !
537+ // ! TODO: link out from mrdocs to macro documentation
537538// ! The default value for `Registry` can be customized by defining the <a
538539// ! href="openmethod/BOOST_OPENMETHOD_DEFAULT_REGISTRY.html">BOOST_OPENMETHOD_DEFAULT_REGISTRY</a>
539540// ! preprocessor symbol.
@@ -856,20 +857,16 @@ class virtual_ptr {
856857
857858// ! Wide pointer combining a smart pointer to an object and its v-table
858859// !
859- // ! This specialization of `virtual_ptr` uses a smart pointer to the object,
860- // ! instead of a plain pointer.
860+ // ! This specialization of `virtual_ptr` uses a smart pointer to track the
861+ // ! object, instead of a plain pointer.
861862// !
862- // ! Calls to methods via `virtual_ptr` are as fast as ordinary virtual function
863- // ! calls (typically two instructions).
864- // !
865- // ! @tparam Class The class of the object, possibly cv-qualified
866- // ! @tparam Registry The registry in which `Class` is registered
867- // ! @tparam unnamed Implementation defined, do not provide.
868- template <class Class , class Registry >
863+ // ! @tparam SmartPtr A smart pointer type
864+ // ! @tparam Registry The registry in which the underlying class is registered
865+ template <class SmartPtr , class Registry >
869866class virtual_ptr <
870- Class , Registry,
867+ SmartPtr , Registry,
871868 std::enable_if_t <BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS(detail::)
872- IsSmartPtr<Class , Registry>>> {
869+ IsSmartPtr<SmartPtr , Registry>>> {
873870
874871#ifndef __MRDOCS__
875872 template <class , class , typename >
@@ -881,40 +878,56 @@ class virtual_ptr<
881878 static constexpr bool is_smart_ptr = true ;
882879 static constexpr bool use_indirect_vptrs = Registry::has_indirect_vptr;
883880
884- using traits = virtual_traits<Class , Registry>;
881+ using traits = virtual_traits<SmartPtr , Registry>;
885882
886883 std::conditional_t <use_indirect_vptrs, const vptr_type*, vptr_type> vp;
887- Class obj;
884+ SmartPtr obj;
888885
889886 template <
890887 class Other ,
891- typename = std::enable_if_t <std::is_constructible_v<Class *, Other*>>>
888+ typename = std::enable_if_t <std::is_constructible_v<SmartPtr *, Other*>>>
892889 virtual_ptr (Other& other, decltype (vp) vp) : vp(vp), obj(&other) {
893890 }
894891
895892 public:
896- using element_type = typename Class::element_type;
893+ // ! Class pointed to by SmartPtr
894+ using element_type = typename SmartPtr::element_type;
897895
898- public:
896+ // ! Default constructor
897+ // !
898+ // ! Construct the smart pointer with its default constructor. Set the
899+ // ! v-table pointer to `nullptr`.
899900 virtual_ptr ()
900901 : vp(detail::box_vptr<use_indirect_vptrs>(detail::null_vptr)) {
901902 }
902903
904+ // ! Construct from `nullptr`
905+ // !
906+ // ! @param value A `nullptr`.
903907 explicit virtual_ptr (std::nullptr_t )
904908 : vp(detail::box_vptr<use_indirect_vptrs>(detail::null_vptr)),
905909 obj(nullptr ) {
906910 }
907911
912+ // ! Copy constructor
913+ // !
914+ // ! This constructor can be used only if `SmartPtr` is copy-constructible.
908915 virtual_ptr (const virtual_ptr& other) = default ;
909916
917+ // ! Copy from SmartPtr to a derived class
918+ // !
919+ // ! @para Requirements
920+ // ! @li `Other` must be a smart pointer to a class derived from
921+ // ! `element_type`.
922+ // ! @li `SmartPtr` must be constructible from `const Other&`.
910923 template <
911924 class Other ,
912925 typename = std::enable_if_t <
913926 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
914- SameSmartPtr<Class , Other, Registry> &&
927+ SameSmartPtr<SmartPtr , Other, Registry> &&
915928 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
916- IsPolymorphic<element_type, Registry> &&
917- std::is_constructible_v<Class , const Other&>>>
929+ IsPolymorphic<typename Other:: element_type, Registry> &&
930+ std::is_constructible_v<SmartPtr , const Other&>>>
918931 virtual_ptr (const Other& other)
919932 : vp(detail::box_vptr<use_indirect_vptrs>(
920933 other ? detail::acquire_vptr<Registry>(*other)
@@ -926,10 +939,10 @@ class virtual_ptr<
926939 class Other ,
927940 typename = std::enable_if_t <
928941 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
929- SameSmartPtr<Class , Other, Registry> &&
942+ SameSmartPtr<SmartPtr , Other, Registry> &&
930943 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS(detail::)
931944 IsPolymorphic<element_type, Registry> &&
932- std::is_constructible_v<Class , Other&>>>
945+ std::is_constructible_v<SmartPtr , Other&>>>
933946 virtual_ptr(Other& other)
934947 : vp(detail::box_vptr<use_indirect_vptrs>(
935948 other ? detail::acquire_vptr<Registry>(*other)
@@ -941,10 +954,10 @@ class virtual_ptr<
941954 class Other ,
942955 typename = std::enable_if_t <
943956 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
944- SameSmartPtr<Class , Other, Registry> &&
957+ SameSmartPtr<SmartPtr , Other, Registry> &&
945958 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS(detail::)
946959 IsPolymorphic<element_type, Registry> &&
947- std::is_constructible_v<Class , Other&&>>>
960+ std::is_constructible_v<SmartPtr , Other&&>>>
948961 virtual_ptr(Other&& other)
949962 : vp(detail::box_vptr<use_indirect_vptrs>(
950963 other ? detail::acquire_vptr<Registry>(*other)
@@ -956,8 +969,8 @@ class virtual_ptr<
956969 class Other ,
957970 typename = std::enable_if_t <
958971 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
959- SameSmartPtr<Class , Other, Registry> &&
960- std::is_constructible_v<Class , const Other&>>>
972+ SameSmartPtr<SmartPtr , Other, Registry> &&
973+ std::is_constructible_v<SmartPtr , const Other&>>>
961974 virtual_ptr(const virtual_ptr<Other, Registry>& other)
962975 : vp(other.vp), obj(other.obj) {
963976 }
@@ -966,8 +979,8 @@ class virtual_ptr<
966979 class Other ,
967980 typename = std::enable_if_t <
968981 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
969- SameSmartPtr<Class , Other, Registry> &&
970- std::is_constructible_v<Class , Other&>>>
982+ SameSmartPtr<SmartPtr , Other, Registry> &&
983+ std::is_constructible_v<SmartPtr , Other&>>>
971984 virtual_ptr(virtual_ptr<Other, Registry>& other)
972985 : vp(other.vp), obj(other.obj) {
973986 }
@@ -980,8 +993,8 @@ class virtual_ptr<
980993 class Other ,
981994 typename = std::enable_if_t <
982995 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
983- SameSmartPtr<Class , Other, Registry> &&
984- std::is_constructible_v<Class , Other&&>>>
996+ SameSmartPtr<SmartPtr , Other, Registry> &&
997+ std::is_constructible_v<SmartPtr , Other&&>>>
985998 virtual_ptr(virtual_ptr<Other, Registry>&& other)
986999 : vp(other.vp), obj(std::move(other.obj)) {
9871000 other.vp = detail::box_vptr<use_indirect_vptrs>(detail::null_vptr);
@@ -1002,8 +1015,8 @@ class virtual_ptr<
10021015 class Other ,
10031016 typename = std::enable_if_t <
10041017 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
1005- SameSmartPtr<Class , Other, Registry> &&
1006- std::is_assignable_v<Class , const Other&> &&
1018+ SameSmartPtr<SmartPtr , Other, Registry> &&
1019+ std::is_assignable_v<SmartPtr , const Other&> &&
10071020 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
10081021 IsPolymorphic<element_type, Registry>>>
10091022 virtual_ptr& operator =(const Other& other) {
@@ -1017,8 +1030,8 @@ class virtual_ptr<
10171030 class Other ,
10181031 typename = std::enable_if_t <
10191032 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
1020- SameSmartPtr<Class , Other, Registry> &&
1021- std::is_assignable_v<Class , Other&&> &&
1033+ SameSmartPtr<SmartPtr , Other, Registry> &&
1034+ std::is_assignable_v<SmartPtr , Other&&> &&
10221035 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
10231036 IsPolymorphic<element_type, Registry>>>
10241037 virtual_ptr& operator =(Other&& other) {
@@ -1032,8 +1045,8 @@ class virtual_ptr<
10321045 class Other ,
10331046 typename = std::enable_if_t <
10341047 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
1035- SameSmartPtr<Class , Other, Registry> &&
1036- std::is_assignable_v<Class , Other&>>>
1048+ SameSmartPtr<SmartPtr , Other, Registry> &&
1049+ std::is_assignable_v<SmartPtr , Other&>>>
10371050 virtual_ptr& operator =(virtual_ptr<Other, Registry>& other) {
10381051 obj = other.obj ;
10391052 vp = other.vp ;
@@ -1046,8 +1059,8 @@ class virtual_ptr<
10461059 class Other ,
10471060 typename = std::enable_if_t <
10481061 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
1049- SameSmartPtr<Class , Other, Registry> &&
1050- std::is_assignable_v<Class , const Other&>>>
1062+ SameSmartPtr<SmartPtr , Other, Registry> &&
1063+ std::is_assignable_v<SmartPtr , const Other&>>>
10511064 virtual_ptr& operator =(const virtual_ptr<Other, Registry>& other) {
10521065 obj = other.obj ;
10531066 vp = other.vp ;
@@ -1058,8 +1071,8 @@ class virtual_ptr<
10581071 class Other ,
10591072 typename = std::enable_if_t <
10601073 BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS (detail::)
1061- SameSmartPtr<Class , Other, Registry> &&
1062- std::is_assignable_v<Class , Other&&>>>
1074+ SameSmartPtr<SmartPtr , Other, Registry> &&
1075+ std::is_assignable_v<SmartPtr , Other&&>>>
10631076 virtual_ptr& operator =(virtual_ptr<Other, Registry>&& other) {
10641077 obj = std::move (other.obj );
10651078 vp = other.vp ;
@@ -1079,7 +1092,7 @@ class virtual_ptr<
10791092 return *get ();
10801093 }
10811094
1082- auto pointer () const -> const Class & {
1095+ auto pointer () const -> const SmartPtr & {
10831096 return obj;
10841097 }
10851098
0 commit comments