Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / smart_ptr / doc / smart_ptr / make_shared.adoc
1 ////
2 Copyright 2017 Peter Dimov
3 Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
4
5 Distributed under the Boost Software License, Version 1.0.
6
7 See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt
9 ////
10
11 [#make_shared]
12 # make_shared: Creating shared_ptr
13 :toc:
14 :toc-title:
15 :idprefix: make_shared_
16
17 ## Description
18
19 The function templates `make_shared` and `allocate_shared` provide convenient,
20 safe and efficient ways to create `shared_ptr` objects.
21
22 ## Rationale
23
24 Consistent use of `shared_ptr` can eliminate the need to use an explicit
25 `delete`, but alone it provides no support in avoiding explicit `new`. There
26 were repeated requests from users for a factory function that creates an
27 object of a given type and returns a `shared_ptr` to it. Besides convenience
28 and style, such a function is also exception safe and considerably faster
29 because it can use a single allocation for both the object and its
30 corresponding control block, eliminating a significant portion of
31 `shared_ptr` construction overhead. This eliminates one of the major
32 efficiency complaints about `shared_ptr`.
33
34 The family of overloaded function templates, `make_shared` and
35 `allocate_shared`, were provided to address this need. `make_shared` uses the
36 global `operator new` to allocate memory, whereas `allocate_shared` uses an
37 user-supplied allocator, allowing finer control.
38
39 The rationale for choosing the name `make_shared` is that the expression
40 `make_shared<Widget>()` can be read aloud and conveys the intended meaning.
41
42 Originally the Boost function templates `allocate_shared` and `make_shared`
43 were provided for scalar objects only. There was a need to have efficient
44 allocation of array objects. One criticism of class template `shared_array`
45 was always the lack of a utility like `make_shared` that uses only a single
46 allocation. When `shared_ptr` was enhanced to support array types, additional
47 overloads of `allocate_shared` and `make_shared` were provided for array
48 types.
49
50 ## Synopsis
51
52 `make_shared` and `allocate_shared` are defined in
53 `<boost/smart_ptr/make_shared.hpp>`.
54
55 [subs=+quotes]
56 ```
57 namespace boost {
58   `// T is not an array`
59   template<class T, class... Args>
60     shared_ptr<T> make_shared(Args&&... args);
61   template<class T, class A, class... Args>
62     shared_ptr<T> allocate_shared(const A& a, Args&&... args);
63
64   `// T is an array of unknown bounds`
65   template<class T>
66     shared_ptr<T> make_shared(std::size_t n);
67   template<class T, class A>
68     shared_ptr<T> allocate_shared(const A& a, std::size_t n);
69
70   `// T is an array of known bounds`
71   template<class T>
72     shared_ptr<T> make_shared();
73   template<class T, class A>
74     shared_ptr<T> allocate_shared(const A& a);
75
76   `// T is an array of unknown bounds`
77   template<class T> shared_ptr<T>
78     make_shared(std::size_t n, const remove_extent_t<T>& v);
79   template<class T, class A> shared_ptr<T>
80     allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
81
82   `// T is an array of known bounds`
83   template<class T>
84     shared_ptr<T> make_shared(const remove_extent_t<T>& v);
85   template<class T, class A>
86     shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
87
88   `// T is not an array of unknown bounds`
89   template<class T>
90     shared_ptr<T> make_shared_noinit();
91   template<class T, class A>
92     shared_ptr<T> allocate_shared_noinit(const A& a);
93
94   `// T is an array of unknown bounds`
95   template<class T>
96     shared_ptr<T> make_shared_noinit(std::size_t n);
97   template<class T, class A>
98     shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
99 }
100 ```
101
102 ## Common Requirements
103
104 The common requirements that apply to all `make_shared` and `allocate_shared`
105 overloads, unless specified otherwise, are described below.
106
107 Requires:: `A` shall be an _allocator_. The copy constructor and destructor
108 of `A` shall not throw exceptions.
109
110 Effects:: Allocates memory for an object of type `T`  or `n` objects of `U`
111 (if `T` is an array type of the form `U[]` and  `n` is determined by
112 arguments, as specified by the concrete overload). The object is initialized
113 from arguments as specified by the concrete overload. Uses a rebound copy of
114 `a` (for an unspecified `value_type`) to allocate memory. If an exception is
115 thrown, the functions have no effect.
116
117 Returns:: A `shared_ptr` instance that stores and owns the address of the
118 newly constructed object.
119
120 Postconditions:: `r.get() != 0` and `r.use_count() == 1`, where `r`
121 is the return value.
122
123 Throws:: `std::bad_alloc`, an exception thrown from `A::allocate`, or from the
124 initialization of the object.
125
126 Remarks::
127 * Performs no more than one memory allocation. This provides efficiency
128 equivalent to an intrusive smart pointer.
129 * When an object of an array type is specified to be initialized to a value of
130 the same type `v`, this shall be interpreted to mean that each array element
131 of the object is initialized to the corresponding element from `v`.
132 * When an object of an array type is specified to be value-initialized, this
133 shall be interpreted to mean that each array element of the object is
134 value-initialized.
135 * When a (sub)object of non-array type `U` is specified to be initialized to
136 a value `v`, or constructed from `args\...`, `make_shared` shall perform
137 this initialization via the expression `::new(p) U(expr)` (where
138 `_expr_` is `v` or `std::forward<Args>(args)\...)` respectively) and `p`
139 has type `void*` and points to storage suitable to hold an object of type
140 `U`.
141 * When a (sub)object of non-array type `U` is specified to be initialized to
142 a value `v`, or constructed from `args\...`, `allocate_shared` shall
143 perform this initialization via the expression
144 `std::allocator_traits<A2>::construct(a2, p, expr)` (where
145 `_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p`
146 points to storage suitable to hold an object of type `U`, and `a2` of
147 type `A2` is a potentially rebound copy of `a`.
148 * When a (sub)object of non-array type `U` is specified to be
149 default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall
150 perform this initialization via the expression `::new(p) U`, where
151 `p` has type `void*` and points to storage suitable to hold an object of
152 type `U`.
153 * When a (sub)object of non-array type `U` is specified to be
154 value-initialized, `make_shared` shall perform this initialization via the
155 expression `::new(p) U()`, where `p` has type `void*` and points to
156 storage suitable to hold an object of type `U`.
157 * When a (sub)object of non-array type `U` is specified to be
158 value-initialized, `allocate_shared` shall perform this initialization via the
159 expression `std::allocator_traits<A2>::construct(a2, p)`, where
160 `p` points to storage suitable to hold an object of type `U` and `a2` of
161 type `A2` is a potentially rebound copy of `a`.
162 * Array elements are initialized in ascending order of their addresses.
163 * When the lifetime of the object managed by the return value ends, or when
164 the initialization of an array element throws an exception, the initialized
165 elements should be destroyed in the reverse order of their construction.
166
167 NOTE: These functions will typically allocate more memory than the total size
168 of the element objects to allow for internal bookkeeping structures such as
169 the reference counts.
170
171 ## Free Functions
172
173 ```
174 template<class T, class... Args>
175   shared_ptr<T> make_shared(Args&&... args);
176 ```
177 ```
178 template<class T, class A, class... Args>
179   shared_ptr<T> allocate_shared(const A& a, Args&&... args);
180 ```
181 [none]
182 * {blank}
183 +
184 Constraints:: `T` is not an array.
185 Returns:: A `shared_ptr` to an object of type `T`, constructed from
186 `args\...`.
187 Examples::
188 * `auto p = make_shared<int>();`
189 * `auto p = make_shared<std::vector<int> >(16, 1);`
190
191 ```
192 template<class T>
193   shared_ptr<T> make_shared(std::size_t n);
194 ```
195 ```
196 template<class T, class A>
197   shared_ptr<T> allocate_shared(const A& a, std::size_t n);
198 ```
199 [none]
200 * {blank}
201 +
202 Constraints:: `T` is an array of unknown bounds.
203 Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of
204 type `remove_extent_t<T>`.
205 Examples::
206 * `auto p = make_shared<double[]>(1024);`
207 * `auto p = make_shared<double[][2][2]>(6);`
208
209 ```
210 template<class T>
211   shared_ptr<T> make_shared();
212 ```
213 ```
214 template<class T, class A>
215   shared_ptr<T> allocate_shared(const A& a);
216 ```
217 [none]
218 * {blank}
219 +
220 Constraints:: `T` is an array of known bounds.
221 Returns:: A `shared_ptr` to a sequence of `extent_v<T>` value-initialized
222 objects of type `remove_extent_t<T>`.
223 Examples::
224 * `auto p = make_shared<double[1024]>();`
225 * `auto p = make_shared<double[6][2][2]>();`
226
227 ```
228 template<class T> shared_ptr<T>
229   make_shared(std::size_t n, const remove_extent_t<T>& v);
230 ```
231 ```
232 template<class T, class A> shared_ptr<T>
233   allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
234 ```
235 [none]
236 * {blank}
237 +
238 Constraints:: `T` is an array of unknown bounds.
239 Returns:: A `shared_ptr` to a sequence of `n` objects of type
240 `remove_extent_t<T>`, each initialized to `v`.
241 Examples::
242 * `auto p = make_shared<double[]>(1024, 1.0);`
243 * `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`
244 * `auto p = make_shared<std::vector<int>[]>(4, {1, 2});`
245
246 ```
247 template<class T>
248   shared_ptr<T> make_shared(const remove_extent_t<T>& v);
249 ```
250 ```
251 template<class T, class A>
252   shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
253 ```
254 [none]
255 * {blank}
256 +
257 Constraints:: `T` is an array of known bounds.
258 Returns:: A `shared_ptr` to a sequence of `extent_v<T>` objects of type
259 `remove_extent_t<T>`, each initialized to `v`.
260 Examples::
261 * `auto p = make_shared<double[1024]>(1.0);`
262 * `auto p = make_shared<double[6][2]>({1.0, 0.0});`
263 * `auto p = make_shared<std::vector<int>[4]>({1, 2});`
264
265 ```
266 template<class T>
267   shared_ptr<T> make_shared_noinit();
268 ```
269 ```
270 template<class T, class A>
271   shared_ptr<T> allocate_shared_noinit(const A& a);
272 ```
273 [none]
274 * {blank}
275 +
276 Constraints:: `T` is not an array, or is an array of known bounds.
277 Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a
278 sequence of `extent_v<T>` default-initialized objects of type
279 `remove_extent_t<T>`, respectively.
280 Example:: `auto p = make_shared_noinit<double[1024]>();`
281
282 ```
283 template<class T>
284   shared_ptr<T> make_shared_noinit(std::size_t n);
285 ```
286 ```
287 template<class T, class A>
288   shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
289 ```
290 [none]
291 * {blank}
292 +
293 Constraints:: `T` is an array of unknown bounds.
294 Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects
295 of type `remove_extent_t<T>`.
296 Example:: `auto p = make_shared_noinit<double[]>(1024);`