Skip to content

Commit 8c91adc

Browse files
committed
wip
1 parent 26e1b55 commit 8c91adc

File tree

1 file changed

+54
-41
lines changed

1 file changed

+54
-41
lines changed

include/boost/openmethod/core.hpp

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
869866
class 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

Comments
 (0)