Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / smart_ptr / doc / smart_ptr / allocate_unique.adoc
1 ////
2 Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com)
3
4 Distributed under the Boost Software License, Version 1.0.
5
6 See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt
8 ////
9
10 [#allocate_unique]
11 # allocate_unique: Creating unique_ptr
12 :toc:
13 :toc-title:
14 :idprefix: allocate_unique_
15
16 ## Description
17
18 The `allocate_unique` family of function templates provide convenient and safe
19 ways to obtain a `std::unique_ptr` that manages a new object created using an
20 allocator.
21
22 ## Rationale
23
24 The {cpp}14 standard introduced `std::make_unique` which used operator `new` to
25 create new objects. However, there is no convenient facility in the standard
26 library to use an allocator for the creation of the objects managed by
27 `std::unique_ptr`. Users writing allocator aware code have often requested an
28 `allocate_unique` factory function. This function is to `std::unique_ptr` what
29 `std::allocate_shared` is to `std::shared_ptr`.
30
31 ## Synopsis
32
33 `allocate_unique` is defined in `<boost/smart_ptr/allocate_unique.hpp>`.
34
35 [subs=+quotes]
36 ```
37 namespace boost {
38   template<class T, class A>
39   class alloc_deleter;
40
41   template<class T, class A>
42   using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A>>;
43
44   `// T is not an array`
45   template<class T, class A, class... Args>
46     std::unique_ptr<T, alloc_deleter<T, A>>
47       allocate_unique(const A& a, Args&&... args);
48
49   `// T is not an array`
50   template<class T, class A>
51     std::unique_ptr<T, alloc_deleter<T, A>>
52       allocate_unique(const A& a, type_identity_t<T>&& v);
53
54   `// T is an array of unknown bounds`
55   template<class T, class A>
56     std::unique_ptr<T, alloc_deleter<T, A>>
57       allocate_unique(const A& a, std::size_t n);
58
59   `// T is an array of known bounds`
60   template<class T, class A>
61     std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
62       allocate_unique(const A& a);
63
64   `// T is an array of unknown bounds`
65   template<class T, class A>
66     std::unique_ptr<T, alloc_deleter<T, A>>
67       allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);
68
69   `// T is an array of known bounds`
70   template<class T, class A>
71     std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
72       allocate_unique(const A& a, const remove_extent_t<T>& v);
73
74   `// T is not an array`
75   template<class T, class A>
76     std::unique_ptr<T, alloc_noinit_deleter<T, A>>
77       allocate_unique_noinit(const A& a);
78
79   `// T is an array of unknown bounds`
80   template<class T, class A>
81     std::unique_ptr<T, alloc_noinit_deleter<T, A>>
82       allocate_unique_noinit(const A& a, std::size_t n);
83
84   `// T is an array of known bounds`
85   template<class T, class A>
86     std::unique_ptr<remove_extent_t<T>[], alloc_noinit_deleter<T, A>>
87       allocate_unique_noinit(const A& a);
88 }
89 ```
90
91 ## Common Requirements
92
93 The common requirements that apply to all `allocate_unique` and
94 `allocate_unique_noinit` overloads, unless specified otherwise, are described
95 below.
96
97 Requires:: `A` shall be an _allocator_. The copy constructor and destructor
98 of `A` shall not throw exceptions.
99
100 Effects:: Allocates memory for an object of type `T` or `n` objects of `U`
101 (if `T` is an array type of the form `U[]` and  `n` is determined by
102 arguments, as specified by the concrete overload). The object is initialized
103 from arguments as specified by the concrete overload. Uses a rebound copy of
104 `a` (for an unspecified `value_type`) to allocate memory. If an exception is
105 thrown, the functions have no effect.
106
107 Returns:: A `std::unique_ptr` instance that stores and owns the address of the
108 newly constructed object.
109
110 Postconditions:: `r.get() != 0`, where `r` is the return value.
111
112 Throws:: An exception thrown from `A::allocate`, or from the initialization of
113 the object.
114
115 Remarks::
116 * When an object of an array type is specified to be initialized to a value of
117 the same type `v`, this shall be interpreted to mean that each array element
118 of the object is initialized to the corresponding element from `v`.
119 * When an object of an array type is specified to be value-initialized, this
120 shall be interpreted to mean that each array element of the object is
121 value-initialized.
122 * When a (sub)object of non-array type `U` is specified to be initialized to a
123 value `v`, or constructed from `args\...`, `allocate_unique` shall perform this
124 initialization via the expression
125 `std::allocator_traits<A2>::construct(a2, p, expr)` (where `_expr_` is `v` or
126 `std::forward<Args>(args)\...)` respectively), `p` points to storage suitable
127 to hold an object of type `U`, and `a2` of type `A2` is a potentially rebound
128 copy of `a`.
129 * When a (sub)object of non-array type `U` is specified to be
130 default-initialized, `allocate_unique_noinit` shall perform this initialization
131 via the expression `::new(p) U`, where `p` has type `void*` and points to
132 storage suitable to hold an object of type `U`.
133 * When a (sub)object of non-array type `U` is specified to be
134 value-initialized, `allocate_unique` shall perform this initialization via the
135 expression `std::allocator_traits<A2>::construct(a2, p)`, where `p` points to
136 storage suitable to hold an object of type `U` and `a2` of type `A2` is a
137 potentially rebound copy of `a`.
138 * Array elements are initialized in ascending order of their addresses.
139 * When the lifetime of the object managed by the return value ends, or when the
140 initialization of an array element throws an exception, the initialized
141 elements should be destroyed in the reverse order of their construction.
142
143 ## Free Functions
144
145 ```
146 template<class T, class A, class... Args>
147   std::unique_ptr<T, alloc_deleter<T, A>>
148     allocate_unique(const A& a, Args&&... args);
149 ```
150 [none]
151 * {blank}
152 +
153 Constraints:: `T` is not an array.
154 Returns:: A `std::unique_ptr` to an object of type `T`, constructed from
155 `args\...`.
156 Examples::
157 * `auto p = allocate_unique<int>(a);`
158 * `auto p = allocate_unique<std::vector<int>>(a, 16, 1);`
159
160 ```
161 template<class T, class A>
162   std::unique_ptr<T, alloc_deleter<T, A>>
163     allocate_unique(const A& a, type_identity_t<T>&& v);
164 ```
165 [none]
166 * {blank}
167 +
168 Constraints:: `T` is not an array.
169 Returns:: A `std::unique_ptr` to an object of type `T`, constructed from `v`.
170 Example:: `auto p = allocate_unique<std::vector<int>>(a, {1, 2});`
171
172 ```
173 template<class T, class A>
174   std::unique_ptr<T, alloc_deleter<T, A>>
175     allocate_unique(const A& a, std::size_t n);
176 ```
177 [none]
178 * {blank}
179 +
180 Constraints:: `T` is an array of unknown bounds.
181 Returns:: A `std::unique_ptr` to a sequence of `n` value-initialized objects of
182 type `remove_extent_t<T>`.
183 Examples::
184 * `auto p = allocate_unique<double[]>(a, 1024);`
185 * `auto p = allocate_unique<double[][2][2]>(a, 6);`
186
187 ```
188 template<class T, class A>
189   std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
190     allocate_unique(const A& a);
191 ```
192 [none]
193 * {blank}
194 +
195 Constraints:: `T` is an array of known bounds.
196 Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` value-initialized
197 objects of type `remove_extent_t<T>`.
198 Examples::
199 * `auto p = allocate_unique<double[1024]>(a);`
200 * `auto p = allocate_unique<double[6][2][2]>(a);`
201
202 ```
203 template<class T, class A>
204   std::unique_ptr<T, alloc_deleter<T, A>>
205     allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);
206 ```
207 [none]
208 * {blank}
209 +
210 Constraints:: `T` is an array of unknown bounds.
211 Returns:: A `std::unique_ptr` to a sequence of `n` objects of type
212 `remove_extent_t<T>`, each initialized to `v`.
213 Examples::
214 * `auto p = allocate_unique<double[]>(a, 1024, 1.0);`
215 * `auto p = allocate_unique<double[][2]>(a, 6, {1.0, 0.0});`
216 * `auto p = allocate_unique<std::vector<int>[]>(a, 4, {1, 2});`
217
218 ```
219 template<class T, class A>
220   std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
221     allocate_unique(const A& a, const remove_extent_t<T>& v);
222 ```
223 [none]
224 * {blank}
225 +
226 Constraints:: `T` is an array of known bounds.
227 Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` objects of type
228 `remove_extent_t<T>`, each initialized to `v`.
229 Examples::
230 * `auto p = allocate_unique<double[1024]>(a, 1.0);`
231 * `auto p = allocate_unique<double[6][2]>(a, {1.0, 0.0});`
232 * `auto p = allocate_unique<std::vector<int>[4]>(a, {1, 2});`
233
234 ```
235 template<class T, class A>
236   std::unique_ptr<T, alloc_noinit_deleter<T, A>>
237     allocate_unique_noinit(const A& a);
238 ```
239 [none]
240 * {blank}
241 +
242 Constraints:: `T` is not an array.
243 Returns:: A `std::unique_ptr` to a default-initialized object of type `T`.
244 Example:: `auto p = allocate_unique_noinit<double>(a);`
245
246 ```
247 template<class T, class A>
248   std::unique_ptr<T, alloc_noinit_deleter<T, A>>
249     allocate_unique_noinit(const A& a, std::size_t n);
250 ```
251 [none]
252 * {blank}
253 +
254 Constraints:: `T` is an array of unknown bounds.
255 Returns:: A `std::unique_ptr` to a sequence of `n` default-initialized objects
256 of type `remove_extent_t<T>`.
257 Example:: `auto p = allocate_unique_noinit<double[]>(a, 1024);`
258
259 ```
260 template<class T, class A>
261   std::unique_ptr<remove_extent_t<T>, alloc_noinit_deleter<T, A>>
262     allocate_unique_noinit(const A& a);
263 ```
264 [none]
265 * {blank}
266 +
267 Constraints:: `T` is an array of known bounds.
268 Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>`
269 default-initialized objects of type `remove_extent_t<T>`.
270 Example:: `auto p = allocate_unique_noinit<double[1024]>(a);`
271
272 ## Deleter
273
274 Class template `alloc_deleter` is the deleter used by the `allocate_unique`
275 functions.
276
277 ### Synopsis
278
279 [subs=+quotes]
280 ```
281 template<class T, class A>
282 class alloc_deleter {
283 public:
284   using pointer = `unspecified`;
285
286   explicit alloc_deleter(const A& a) noexcept;
287
288   void operator()(pointer p);
289 };
290 ```
291
292 ### Members
293
294 [subs=+quotes]
295 ```
296 using pointer = `unspecified`;
297 ```
298 [none]
299 * {blank}
300 +
301 A type that satisfies _NullablePointer_.
302
303 ```
304 explicit alloc_deleter(const A& a) noexcept;
305 ```
306 [none]
307 * {blank}
308 +
309 Effects:: Initializes the stored allocator from `a`.
310
311 ```
312 void operator()(pointer p);
313 ```
314 [none]
315 * {blank}
316 +
317 Effects:: Destroys the objects and deallocates the storage referenced by `p`,
318 using the stored allocator.