forked from boostorg/smart_ptr
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_shared_array.html
More file actions
273 lines (262 loc) · 14.8 KB
/
make_shared_array.html
File metadata and controls
273 lines (262 loc) · 14.8 KB
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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_shared and allocate_shared for arrays</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">make_shared and allocate_shared
for arrays</h1>
<p><a href="#introduction">Introduction</a><br>
<a href="#synopsis">Synopsis</a><br>
<a href="#common">Common Requirements</a><br>
<a href="#functions">Free Functions</a><br>
<a href="#history">History</a><br>
<a href="#references">References</a></p>
<h2><a name="introduction">Introduction</a></h2>
<p>Originally the Boost function templates <code>make_shared</code> and
<code>allocate_shared</code> were for efficient allocation of shared
objects only. There was a need to have efficient allocation of
shared arrays. One criticism of class template <code>shared_array</code>
was always the lack of a <a href="make_shared.html">make_shared</a>
utility which ensures only a single allocation.</p>
<p>The header files <boost/smart_ptr/make_shared_array.hpp> and
<boost/smart_ptr/allocate_shared_array.hpp> provide function
templates, overloads of <code>make_shared</code> and
<code>allocate_shared</code> for array types, to address this need.
<code>make_shared</code> uses the global operator <code>new</code> to
allocate memory, whereas <code>allocate_shared</code> uses an
user-supplied allocator, allowing finer control.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<pre>namespace boost {
template<class U> // U is T[]
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> <a href="#functions">make_shared</a>();
template<class U, class A> // U is T[N]
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator);
template<class U> // U is T[]
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T& value);
template<class U, class A> // U is T[]
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T& value);
template<class U> // U is T[N]
shared_ptr<U> <a href="#functions">make_shared</a>(const T& value);
template<class U, class A> // U is T[N]
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T& value);
template<class U> // U is T[]
shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> <a href="#functions">make_shared_noinit</a>();
template<class U, class A> // U is T[N]
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator);
}</pre>
<h2><a name="common">Common Requirements</a></h2>
<pre>template<class U>
shared_ptr<U> make_shared(<em>args</em>);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, <em>args</em>);
template<class U>
shared_ptr<U> make_shared_noinit(<em>args</em>);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, <em>args</em>);</pre>
<blockquote>
<p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or
<code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as
described in section 17.6.3.5 [<strong>Allocator
requirements</strong>] of the C++ Standard. The copy constructor and
destructor of <code>A</code> shall not throw exceptions.</p>
<p><b>Effects:</b> Allocates memory for an object of type <code>U</code>
(or <code>T[size]</code> when <code>U</code> is <code>T[]</code>,
where <code>size</code> is determined from <code><em>args</em></code>
as specified by the concrete overload). The object is initialized as
specified by the concrete overload. The templates
<code>allocate_shared</code> and <code>allocate_shared_noinit</code>
use a copy of <code>allocator</code> to allocate memory. If an
exception is thrown, the functions have no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and
owns the address of the newly constructed object.</p>
<p><b>Postconditions:</b> <code>r.get() != 0 &&
r.use_count() == 1</code>, where <code>r</code> is the return
value.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from
<code>A::allocate</code>, or from the initialization of the
object.</p>
<p><b>Remarks:</b></p>
<blockquote>
<p>This implementation performs no more than one memory
allocation. This provides efficiency to equivalent to an intrusive
smart pointer.</p>
<p>When an object of an array type <code>T</code> is specified to be
initialized to a value of the same type <code>value</code>, this
shall be interpreted to mean that each array element of the object
is initialized to the corresponding element from
<code>value</code>.</p>
<p>When an object of an array type is specified to be
value-initialized, this shall be interpreted to mean that each
array element of the object is value-initialized.</p>
<p>Array elements are initialized in ascending order of their
addresses.</p>
<p>When a subobject of a non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>,
<code>make_shared</code> shall perform this initialization via the
expression <code>::new(ptr) T(value)</code>, where <code>ptr</code>
has type <code>void*</code> and points to storage suitable to hold
an object of type <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>,
<code>allocate_shared</code> shall perform this initialization via
the expression <code>allocator_traits<A2>::construct(a2, ptr,
value)</code>, where <code>ptr</code> points to storage suitable to
hold an object of type <code>T</code> and <code>a2</code> of type A2
is a rebound copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>make_shared</code> shall perform this
initialization via the expression <code>::new(ptr) T()</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>allocate_shared</code> shall perform
this initialization via the expression
<code>allocator_traits<A2>::construct(a2, ptr)</code>, where
<code>ptr</code> points to storage suitable to hold an object
of type <code>T</code> and <code>a2</code> of type A2 is a rebound
copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be default-initialized, <code>make_shared_noinit</code> and
<code>allocate_shared_noinit</code> shall perform this
initialization via the expression <code>::new(ptr) T</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When the lifetime of the object managed by the return value ends,
or when the initialization of an array element throws an exception,
the initialized elements should be destroyed in the reverse order
of their construction.</p>
</blockquote>
<p><b>Notes:</b> These functions will typically allocate more memory
than <code>sizeof(U)</code> to allow for internal bookkeeping
structures such as the reference counts.</p>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<pre>template<class U>
shared_ptr<U> make_shared(size_t size);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized
object of type <code>T[size]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);</pre>
</blockquote>
</blockquote>
<pre>template<class U>
shared_ptr<U> make_shared();
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized
object of type <code>T[N]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>();
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();</pre>
</blockquote>
</blockquote>
<pre>template<class U>
shared_ptr<U> make_shared(size_t size, const T& value);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[size]</code>, where each array element of type <code>T</code>
is initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1);
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});</pre>
</blockquote>
</blockquote>
<pre>template<class U>
shared_ptr<U> make_shared(const T& value);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, const T& value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[N]</code>, where each array element of type <code>T</code> is
initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1);
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});</pre>
</blockquote>
</blockquote>
<pre>template<class U>
shared_ptr<U> make_shared_noinit(size_t size);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[size]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size);
boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);</pre>
</blockquote>
</blockquote>
<pre>template<class U>
shared_ptr<U> make_shared_noinit();
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[N]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>();
boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]>();</pre>
</blockquote>
</blockquote>
<h2><a name="history">History</a></h2>
<p>February 2014. Glen Fernandes updated overloads of make_shared and
allocate_shared to conform to the specification in C++ standard paper
<a href="#N3870">N3870</a>, including resolving C++ standard library
defect report 2070, and reduced the spatial overhead of the internal
bookkeeping structures.</p>
<p>November 2012. Glen Fernandes contributed implementations of
make_shared and allocate_shared for arrays.</p>
<h2><a name="references">References</a></h2>
<p><a name="N3870">N3870</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov
& Glen Fernandes, January, 2014.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 2012-2014 Glen Fernandes. Distributed under the
Boost Software License, Version 1.0. See accompanying file
<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body>
</html>