[#virtual_ptr] :idprefix: virtual_ptr_ ## virtual_ptr ### Synopsis `virtual_ptr` is defined in ``. ```c++ namespace boost::openmethod { template class virtual_ptr { public: static constexpr bool is_smart_ptr = /* see below */; using element_type = /* see below */; template virtual_ptr(Other& other); template virtual_ptr(const Other& other); template virtual_ptr(Other&& other); template static auto final(Other&& obj); auto get() const -> element_type*; auto operator->() const -> element_type*; auto operator*() const -> element_type&; auto pointer() const -> const Class*&; template auto cast() const -> virtual_ptr; }; template virtual_ptr(Class&) -> virtual_ptr; template inline auto final_virtual_ptr(Class& obj) -> virtual_ptr< Class, BOOST_OPENMETHOD_DEFAULT_POLICY>; template inline auto final_virtual_ptr(Class& obj) -> virtual_ptr; template bool operator==( const virtual_ptr& left, const virtual_ptr& right); template bool operator!=( const virtual_ptr& left, const virtual_ptr& right); } // namespace boost::openmethod ``` Defined in ``: ```c++ namespace boost::openmethod { template using shared_virtual_ptr = virtual_ptr, Policy>; template< class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY, typename... T> inline auto make_shared_virtual(T&&... args); } ``` Defined in ``: ```c++ namespace boost::openmethod { template using unique_virtual_ptr = virtual_ptr, Policy>; template< class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY, typename... T> inline auto make_unique_virtual(T&&... args); } ``` ### Description `virtual_ptr` is a wide pointer that combines a pointer to an object and a pointer to its v-table. The object pointer can be a plain pointer or a smart pointer. Specializations of `virtual_traits` are required for smart pointers. They are provided for `std::unique_ptr` and `std::shared_ptr`. A plain `virtual_ptr` can be constructed from a reference, a smart pointer, or another `virtual_ptr`. A smart `virtual_ptr` can be constructed from a smart pointer or from a smart `virtual_ptr`. Usual conversions - from derived to base, and from non-const to const - are allowed. `virtual_ptr` does not have a default constructor, nor a "null" state. In that respect, it behaves more like a reference than a pointer. The only reason why it is not called `virtual_ref` is to save the name for the day C++ will support smart references. ### Members #### is_smart_ptr ```c++ static constexpr bool is_smart_ptr; ``` `true` if `Class` is a smart pointer, `false` otherwise. The value is derived from `virtual_traits`: if it has a member template called `rebind`, `Class` is considered a smart pointer. #### element_type ```c++ using element_type = std::conditional_t< is_smart_ptr, typename Class::element_type, Class>; ``` The class of the object pointed to. #### constructors [source,c++] ---- template virtual_ptr(Other& other); // 1 template virtual_ptr(const Other& other); // 2 template virtual_ptr(Other&& other); // 3 ---- (1), (2) If `virtual_ptr` uses a plain pointer, `other` must be a lvalue reference to an object of a registered class, or to a `virtual_ptr` (plain or smart). If `virtual_ptr` uses a smart pointer, `other` must be a reference to a smart pointer, or a smart `virtual_ptr`. (3) Smart `virtual_ptr` only. Constructs a `virtual_ptr` from a smart pointer or a smart `virtual_ptr`. The (smart) object pointer is moved from `other`. If `other` is also a `virtual_ptr`, the v-table pointer is copied from it. Otherwise, it is deduced from the object. The `Policy` must be the same for both `virtual_ptr`{empty}s. #### final ```c++ template static auto final(Other&& obj); ``` Constructs a `virtual_ptr` from a reference to an object, or from a smart pointer. It is assumed that the static and dynamic types are the same. The v-table pointer is initialized from the `Policy::static_vptr` for the class, which needs not be polymorphic. #### get ```c++ auto get() const -> element_type*; ``` Returns a pointer to the object. #### operator-> ```c++ auto operator->() const -> element_type*; ``` Returns a pointer to the object. #### operator* ```c++ auto operator*() const -> element_type&; ``` Returns a reference to the object. #### pointer ```c++ auto pointer() const; ``` Returns a reference to the object pointer, which can be either a plain pointer or a smart pointer. #### cast ```c++ template auto cast() const -> virtual_ptr; ``` Returns a `virtual_ptr` to the same object, cast to `Other`. ### Deduction guide ```c++ template virtual_ptr(Class&) -> virtual_ptr; ``` --- ### Non-members #### virtual_shared_ptr ```c++ template using virtual_shared_ptr = virtual_ptr, Policy>; ``` Convenience alias for `virtual_ptr, Policy>`. #### virtual_unique_ptr ```c++ template using virtual_unique_ptr = virtual_ptr, Policy>; ``` Convenience alias for `virtual_ptr, Policy>`. #### final_virtual_ptr ```c++ template inline auto final_virtual_ptr(Class&& obj); template inline auto final_virtual_ptr(Class&& obj); ``` Utility functions, forwarding to `virtual_ptr::final`. If `Policy` is not specified, `BOOST_OPENMETHOD_DEFAULT_POLICY` is used. #### make_virtual_shared ```c++ template< class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY, typename... T> inline auto make_virtual_shared(T&&... args); ``` Creates an object using `std::make_shared` and returns a `virtual_shared_ptr` to it. The v-table pointer is initialized from the the `Policy::static_vptr` for the class, which needs not be polymorphic. #### make_virtual_unique ```c++ template< class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY, typename... T> inline auto make_virtual_unique(T&&... args); ``` Creates an object using `std::make_unique` and returns a `virtual_unique_ptr` to it. The v-table pointer is initialized from the the `Policy::static_vptr` for the class, which needs not be polymorphic. #### operator== ```c++ template bool operator==( const virtual_ptr& left, const virtual_ptr& right); ``` Compares two `virtual_ptr` objects for equality. #### operator!= ```c++ template bool operator!=( const virtual_ptr& left, const virtual_ptr& right); ``` Compares two `virtual_ptr` objects for inequality.