Files
openmethod/doc/virtual_ptr.adoc
Jean-Louis Leroy 5e0fa8ee4b inception
2025-03-08 15:31:25 -05:00

290 lines
7.4 KiB
Plaintext

[#virtual_ptr]
:idprefix: virtual_ptr_
## virtual_ptr
### Synopsis
`virtual_ptr` is defined in `<boost/openmethod/core.hpp>`.
```c++
namespace boost::openmethod {
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
class virtual_ptr {
public:
static constexpr bool is_smart_ptr = /* see below */;
using element_type = /* see below */;
template<class Other> virtual_ptr(Other& other);
template<class Other> virtual_ptr(const Other& other);
template<class Other> virtual_ptr(Other&& other);
template<class Other>
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<typename Other>
auto cast() const -> virtual_ptr<Other, Policy>;
};
template<class Class>
virtual_ptr(Class&) -> virtual_ptr<Class, BOOST_OPENMETHOD_DEFAULT_POLICY>;
template<class Class>
inline auto final_virtual_ptr(Class& obj) -> virtual_ptr<
Class, BOOST_OPENMETHOD_DEFAULT_POLICY>;
template<class Policy, class Class>
inline auto final_virtual_ptr(Class& obj) -> virtual_ptr<Class, Policy>;
template<class Left, class Right, class Policy>
bool operator==(
const virtual_ptr<Left, Policy>& left,
const virtual_ptr<Right, Policy>& right);
template<class Left, class Right, class Policy>
bool operator!=(
const virtual_ptr<Left, Policy>& left,
const virtual_ptr<Right, Policy>& right);
} // namespace boost::openmethod
```
Defined in `<boost/openmethod/shared_ptr.hpp>`:
```c++
namespace boost::openmethod {
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
using shared_virtual_ptr = virtual_ptr<std::shared_ptr<Class>, Policy>;
template<
class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY, typename... T>
inline auto make_shared_virtual(T&&... args);
}
```
Defined in `<boost/openmethod/unique_ptr.hpp>`:
```c++
namespace boost::openmethod {
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
using unique_virtual_ptr = virtual_ptr<std::unique_ptr<Class>, 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<Class, Policy>`: 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<class Other> virtual_ptr(Other& other); // 1
template<class Other> virtual_ptr(const Other& other); // 2
template<class Other> 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<class Other>
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<typename Other>
auto cast() const -> virtual_ptr<Other, Policy>;
```
Returns a `virtual_ptr` to the same object, cast to `Other`.
### Deduction guide
```c++
template<class Class>
virtual_ptr(Class&) -> virtual_ptr<Class, BOOST_OPENMETHOD_DEFAULT_POLICY>;
```
---
### Non-members
#### virtual_shared_ptr
```c++
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
using virtual_shared_ptr = virtual_ptr<std::shared_ptr<Class>, Policy>;
```
Convenience alias for `virtual_ptr<std::shared_ptr<Class>, Policy>`.
#### virtual_unique_ptr
```c++
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
using virtual_unique_ptr = virtual_ptr<std::unique_ptr<Class>, Policy>;
```
Convenience alias for `virtual_ptr<std::unique_ptr<Class>, Policy>`.
#### final_virtual_ptr
```c++
template<class Policy, class Class>
inline auto final_virtual_ptr(Class&& obj);
template<class Class>
inline auto final_virtual_ptr(Class&& obj);
```
Utility functions, forwarding to `virtual_ptr<Class, Policy>::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<class Left, class Right, class Policy>
bool operator==(
const virtual_ptr<Left, Policy>& left,
const virtual_ptr<Right, Policy>& right);
```
Compares two `virtual_ptr` objects for equality.
#### operator!=
```c++
template<class Left, class Right, class Policy>
bool operator!=(
const virtual_ptr<Left, Policy>& left,
const virtual_ptr<Right, Policy>& right);
```
Compares two `virtual_ptr` objects for inequality.