From Jason Turner

[util.smartptr.shared.create]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5mbnvkuz/{from.md → to.md} +256 -26
tmp/tmp5mbnvkuz/{from.md → to.md} RENAMED
@@ -1,41 +1,271 @@
1
- ##### `shared_ptr` creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
 
 
 
 
 
2
 
3
  ``` cpp
4
- template<class T, class... Args>
5
- shared_ptr<T> make_shared(Args&&... args);
6
- template<class T, class A, class... Args>
7
- shared_ptr<T> allocate_shared(const A& a, Args&&... args);
 
 
 
 
8
  ```
9
 
10
- *Requires:* The expression `::new (pv) T(std::forward<Args>(args)...)`,
11
- where `pv` has type `void*` and points to storage suitable to hold an
12
- object of type `T`, shall be well formed. `A` shall be an
13
- allocator ([[allocator.requirements]]). The copy constructor and
14
- destructor of `A` shall not throw exceptions.
15
 
16
- *Effects:* Allocates memory suitable for an object of type `T` and
17
- constructs an object in that memory via the placement *new-expression*
18
- `::new (pv) T(std::forward<Args>(args)...)`. The template
19
- `allocate_shared` uses a copy of `a` to allocate memory. If an exception
20
- is thrown, the functions have no effect.
 
 
21
 
22
  *Returns:* A `shared_ptr` instance that stores and owns the address of
23
- the newly constructed object of type `T`.
24
 
25
- *Postconditions:* `get() != 0 && use_count() == 1`.
 
26
 
27
- *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
28
- the constructor of `T`.
29
 
30
- *Remarks:* The `shared_ptr` constructor called by this function enables
31
- `shared_from_this` with the address of the newly constructed object of
32
- type `T`. Implementations should perform no more than one memory
33
- allocation.
34
 
35
- [*Note 7*: This provides efficiency equivalent to an intrusive smart
 
36
  pointer. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
- [*Note 8*: These functions will typically allocate more memory than
39
- `sizeof(T)` to allow for internal bookkeeping structures such as the
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  reference counts. — *end note*]
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
2
+
3
+ The common requirements that apply to all `make_shared`,
4
+ `allocate_shared`, `make_shared_for_overwrite`, and
5
+ `allocate_shared_for_overwrite` overloads, unless specified otherwise,
6
+ are described below.
7
 
8
  ``` cpp
9
+ template<class T, ...>
10
+ shared_ptr<T> make_shared(args);
11
+ template<class T, class A, ...>
12
+ shared_ptr<T> allocate_shared(const A& a, args);
13
+ template<class T, ...>
14
+ shared_ptr<T> make_shared_for_overwrite(args);
15
+ template<class T, class A, ...>
16
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
17
  ```
18
 
19
+ *Preconditions:* `A` meets the *Cpp17Allocator* requirements
20
+ ([[cpp17.allocator]]).
 
 
 
21
 
22
+ *Effects:* Allocates memory for an object of type `T` (or `U[N]` when
23
+ `T` is `U[]`, where `N` is determined from *args* as specified by the
24
+ concrete overload). The object is initialized from *args* as specified
25
+ by the concrete overload. The `allocate_shared` and
26
+ `allocate_shared_for_overwrite` templates use a copy of `a` (rebound for
27
+ an unspecified `value_type`) to allocate memory. If an exception is
28
+ thrown, the functions have no effect.
29
 
30
  *Returns:* A `shared_ptr` instance that stores and owns the address of
31
+ the newly constructed object.
32
 
33
+ *Ensures:* `r.get() != 0 && r.use_count() == 1`, where `r` is the return
34
+ value.
35
 
36
+ *Throws:* `bad_alloc`, or an exception thrown from `allocate` or from
37
+ the initialization of the object.
38
 
39
+ *Remarks:*
 
 
 
40
 
41
+ - Implementations should perform no more than one memory allocation.
42
+ \[*Note 1*: This provides efficiency equivalent to an intrusive smart
43
  pointer. — *end note*]
44
+ - When an object of an array type `U` is specified to have an initial
45
+ value of `u` (of the same type), this shall be interpreted to mean
46
+ that each array element of the object has as its initial value the
47
+ corresponding element from `u`.
48
+ - When an object of an array type is specified to have a default initial
49
+ value, this shall be interpreted to mean that each array element of
50
+ the object has a default initial value.
51
+ - When a (sub)object of a non-array type `U` is specified to have an
52
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
53
+ constructor arguments, `make_shared` shall initialize this (sub)object
54
+ via the expression `::new(pv) U(v)` or `::new(pv) U(l...)`
55
+ respectively, where `pv` has type `void*` and points to storage
56
+ suitable to hold an object of type `U`.
57
+ - When a (sub)object of a non-array type `U` is specified to have an
58
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
59
+ constructor arguments, `allocate_shared` shall initialize this
60
+ (sub)object via the expression
61
+ - `allocator_traits<A2>::construct(a2, pv, v)` or
62
+ - `allocator_traits<A2>::construct(a2, pv, l...)`
63
 
64
+ respectively, where `pv` points to storage suitable to hold an object
65
+ of type `U` and `a2` of type `A2` is a rebound copy of the allocator
66
+ `a` passed to `allocate_shared` such that its `value_type` is
67
+ `remove_cv_t<U>`.
68
+ - When a (sub)object of non-array type `U` is specified to have a
69
+ default initial value, `make_shared` shall initialize this (sub)object
70
+ via the expression `::new(pv) U()`, where `pv` has type `void*` and
71
+ points to storage suitable to hold an object of type `U`.
72
+ - When a (sub)object of non-array type `U` is specified to have a
73
+ default initial value, `allocate_shared` shall initialize this
74
+ (sub)object via the expression
75
+ `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
76
+ storage suitable to hold an object of type `U` and `a2` of type `A2`
77
+ is a rebound copy of the allocator `a` passed to `allocate_shared`
78
+ such that its `value_type` is `remove_cv_t<U>`.
79
+ - When a (sub)object of non-array type `U` is initialized by
80
+ `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
81
+ initialized via the expression `::new(pv) U`, where `pv` has type
82
+ `void*` and points to storage suitable to hold an object of type `U`.
83
+ - Array elements are initialized in ascending order of their addresses.
84
+ - When the lifetime of the object managed by the return value ends, or
85
+ when the initialization of an array element throws an exception, the
86
+ initialized elements are destroyed in the reverse order of their
87
+ original construction.
88
+ - When a (sub)object of non-array type `U` that was initialized by
89
+ `make_shared` is to be destroyed, it is destroyed via the expression
90
+ `pv->~U()` where `pv` points to that object of type `U`.
91
+ - When a (sub)object of non-array type `U` that was initialized by
92
+ `allocate_shared` is to be destroyed, it is destroyed via the
93
+ expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
94
+ to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
95
+ rebound copy of the allocator `a` passed to `allocate_shared` such
96
+ that its `value_type` is `remove_cv_t<U>`.
97
+
98
+ [*Note 1*: These functions will typically allocate more memory than
99
+ `sizeof(T)` to allow for internal bookkeeping structures such as
100
  reference counts. — *end note*]
101
 
102
+ ``` cpp
103
+ template<class T, class... Args>
104
+ shared_ptr<T> make_shared(Args&&... args); // T is not array
105
+ template<class T, class A, class... Args>
106
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
107
+ ```
108
+
109
+ *Constraints:* `T` is not an array type.
110
+
111
+ *Returns:* A `shared_ptr` to an object of type `T` with an initial value
112
+ `T(forward<Args>(args)...)`.
113
+
114
+ *Remarks:* The `shared_ptr` constructors called by these functions
115
+ enable `shared_from_this` with the address of the newly constructed
116
+ object of type `T`.
117
+
118
+ [*Example 1*:
119
+
120
+ ``` cpp
121
+ shared_ptr<int> p = make_shared<int>(); // shared_ptr to int()
122
+ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
123
+ // shared_ptr to vector of 16 elements with value 1
124
+ ```
125
+
126
+ — *end example*]
127
+
128
+ ``` cpp
129
+ template<class T> shared_ptr<T>
130
+ make_shared(size_t N); // T is U[]
131
+ template<class T, class A>
132
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
133
+ ```
134
+
135
+ *Constraints:* `T` is of the form `U[]`.
136
+
137
+ *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
138
+ initial value, where `U` is `remove_extent_t<T>`.
139
+
140
+ [*Example 2*:
141
+
142
+ ``` cpp
143
+ shared_ptr<double[]> p = make_shared<double[]>(1024);
144
+ // shared_ptr to a value-initialized double[1024]
145
+ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
146
+ // shared_ptr to a value-initialized double[6][2][2]
147
+ ```
148
+
149
+ — *end example*]
150
+
151
+ ``` cpp
152
+ template<class T>
153
+ shared_ptr<T> make_shared(); // T is U[N]
154
+ template<class T, class A>
155
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N]
156
+ ```
157
+
158
+ *Constraints:* `T` is of the form `U[N]`.
159
+
160
+ *Returns:* A `shared_ptr` to an object of type `T` with a default
161
+ initial value.
162
+
163
+ [*Example 3*:
164
+
165
+ ``` cpp
166
+ shared_ptr<double[1024]> p = make_shared<double[1024]>();
167
+ // shared_ptr to a value-initialized double[1024]
168
+ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
169
+ // shared_ptr to a value-initialized double[6][2][2]
170
+ ```
171
+
172
+ — *end example*]
173
+
174
+ ``` cpp
175
+ template<class T>
176
+ shared_ptr<T> make_shared(size_t N,
177
+ const remove_extent_t<T>& u); // T is U[]
178
+ template<class T, class A>
179
+ shared_ptr<T> allocate_shared(const A& a, size_t N,
180
+ const remove_extent_t<T>& u); // T is U[]
181
+ ```
182
+
183
+ *Constraints:* `T` is of the form `U[]`.
184
+
185
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
186
+ `remove_extent_t<T>` and each array element has an initial value of `u`.
187
+
188
+ [*Example 4*:
189
+
190
+ ``` cpp
191
+ shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0);
192
+ // shared_ptr to a double[1024], where each element is 1.0
193
+ shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0});
194
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
195
+ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
196
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
197
+ ```
198
+
199
+ — *end example*]
200
+
201
+ ``` cpp
202
+ template<class T>
203
+ shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
204
+ template<class T, class A>
205
+ shared_ptr<T> allocate_shared(const A& a,
206
+ const remove_extent_t<T>& u); // T is U[N]
207
+ ```
208
+
209
+ *Constraints:* `T` is of the form `U[N]`.
210
+
211
+ *Returns:* A `shared_ptr` to an object of type `T`, where each array
212
+ element of type `remove_extent_t<T>` has an initial value of `u`.
213
+
214
+ [*Example 5*:
215
+
216
+ ``` cpp
217
+ shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0);
218
+ // shared_ptr to a double[1024], where each element is 1.0
219
+ shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0});
220
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
221
+ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
222
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
223
+ ```
224
+
225
+ — *end example*]
226
+
227
+ ``` cpp
228
+ template<class T>
229
+ shared_ptr<T> make_shared_for_overwrite();
230
+ template<class T, class A>
231
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a);
232
+ ```
233
+
234
+ *Constraints:* `T` is not an array of unknown bound.
235
+
236
+ *Returns:* A `shared_ptr` to an object of type `T`.
237
+
238
+ [*Example 6*:
239
+
240
+ ``` cpp
241
+ struct X { double data[1024]; };
242
+ shared_ptr<X> p = make_shared_for_overwrite<X>();
243
+ // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value
244
+
245
+ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
246
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
247
+ ```
248
+
249
+ — *end example*]
250
+
251
+ ``` cpp
252
+ template<class T>
253
+ shared_ptr<T> make_shared_for_overwrite(size_t N);
254
+ template<class T, class A>
255
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
256
+ ```
257
+
258
+ *Constraints:* `T` is an array of unknown bound.
259
+
260
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
261
+ `remove_extent_t<T>`.
262
+
263
+ [*Example 7*:
264
+
265
+ ``` cpp
266
+ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
267
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
268
+ ```
269
+
270
+ — *end example*]
271
+