File: virtual_ptr.adoc

package info (click to toggle)
boost1.90 1.90.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 593,156 kB
  • sloc: cpp: 4,190,642; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,776; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (333 lines) | stat: -rw-r--r-- 9,479 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

[#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_REGISTRY>
class virtual_ptr {
  public:
    static constexpr bool is_smart_ptr = /* see below */;
    using element_type = /* see below */;

    virtual_ptr();
    virtual_ptr(nullptr_t);
    template<class Other> virtual_ptr(Other& other);
    template<class Other> virtual_ptr(const Other& other);
    template<class Other> virtual_ptr(Other&& other);

    virtual_ptr& operator =(nullptr_t);
    template<class Other> virtual_ptr& operator =(Other& other);
    template<class Other> virtual_ptr& operator =(const Other& other);
    template<class Other> virtual_ptr& operator =(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_REGISTRY>;

template<class Class>
inline auto final_virtual_ptr(Class& obj) -> virtual_ptr<
    Class, BOOST_OPENMETHOD_DEFAULT_REGISTRY>;

template<class Policy, class Class>
inline auto final_virtual_ptr(Class& obj) -> virtual_ptr<Class, Policy>;

template<class Left, class Right, class Policy>
auto operator==(
    const virtual_ptr<Left, Policy>& left,
    const virtual_ptr<Right, Policy>& right) -> bool;

template<class Left, class Right, class Policy>
auto operator!=(
    const virtual_ptr<Left, Policy>& left,
    const virtual_ptr<Right, Policy>& right) -> bool;

} // namespace boost::openmethod
```

Defined in `<boost/openmethod/interop/std_shared_ptr.hpp>`:

```c++
namespace boost::openmethod {

template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
using shared_virtual_ptr = virtual_ptr<std::shared_ptr<Class>, Policy>;

template<
    class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY, typename... T>
inline auto make_shared_virtual(T&&... args)
    -> shared_virtual_ptr<Class, Policy>;

}
```
Defined in `<boost/openmethod/interop/std_unique_ptr.hpp>`:

```c++
namespace boost::openmethod {

template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
using unique_virtual_ptr = virtual_ptr<std::unique_ptr<Class>, Policy>;

template<
    class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY, typename... T>
inline auto make_unique_virtual(T&&... args)
    -> unique_virtual_ptr<Class, Policy>;
}
```

### 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 supported.

### 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++]
----
virtual_ptr();                                          // 1
virtual_ptr(nullptr_t);                                 // 2
template<class Other> virtual_ptr(Other& other);        // 3
template<class Other> virtual_ptr(const Other& other);  // 4
template<class Other> virtual_ptr(Other&& other);       // 5
template<class Other> virtual_ptr(Other* other);        // 6
----

(1) Default constructor. Sets the v-table pointer to `nullptr`. If `Class` is
_not_ a smart pointer, the value of object pointer is is undefined.

(2) Sets both the object and v-table pointers to `nullptr`.

(3), (4) For plain `virtual_ptr`{empty}s, `other` must be either a lvalue
reference to an object of a registered class, or a `virtual_ptr` (plain or
smart). For smart `virtual_ptr`{empty}s, `other` must be a reference to a smart
pointer, or a reference to a smart `virtual_ptr`.

(5) Constructs a `virtual_ptr` from a smart pointer or a smart `virtual_ptr`.
The object pointer is moved from `other`.

(6) Constructs a `virtual_ptr` from a plain pointer. Available only for plain
`virtual_ptr`{empty}s.

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.


#### assignment operators

[source,c++]
----
virtual_ptr& operator =(nullptr_t);                                 // 1
template<class Other> virtual_ptr& operator =(Other& other);        // 2
template<class Other> virtual_ptr& operator =(const Other& other);  // 3
template<class Other> virtual_ptr& operator =(Other&& other);       // 4
template<class Other> virtual_ptr& operator =(Other* other);        // 5
----

(1) Sets both the object and v-table pointers to `nullptr`.

(2), (3) For plain `virtual_ptr`{empty}s, `other` must be either a lvalue
reference to an object of a registered class, or a `virtual_ptr` (plain or
smart). For smart `virtual_ptr`{empty}s, `other` must be a reference to a smart
pointer, or a reference to a smart `virtual_ptr`.

(4) Moves `other` to this `virtual_ptr`. If `other` is a smart pointer or a
smart virtual pointer, the object pointer is moved from `other`.

(5) Sets the object pointer to `other`. Available only for plain
`virtual_ptr`{empty}s.

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_REGISTRY>;
```

---

### Non-members

#### virtual_shared_ptr

```c++
template<class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
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_REGISTRY>
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_REGISTRY` is used.

#### make_shared_virtual

```c++
template<
    class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY, typename... T>
inline auto make_shared_virtual(T&&... args)
    -> shared_virtual_ptr<Class, Policy>;
```

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_unique_virtual

```c++
template<
    class Class, class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY, typename... T>
inline auto make_unique_virtual(T&&... args)
    -> unique_virtual_ptr<Class, Policy>;
```

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>
auto operator==(
    const virtual_ptr<Left, Policy>& left,
    const virtual_ptr<Right, Policy>& right) -> bool;
```

Compares two `virtual_ptr` objects for equality.

#### operator!=

```c++
template<class Left, class Right, class Policy>
auto operator!=(
    const virtual_ptr<Left, Policy>& left,
    const virtual_ptr<Right, Policy>& right) -> bool;
```

Compares two `virtual_ptr` objects for inequality.