]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>make_shared and allocate_shared for arrays</title> | |
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | |
6 | </head> | |
7 | <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff"> | |
8 | <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" | |
9 | width="277" align="middle" border="0">make_shared and allocate_shared | |
10 | for arrays</h1> | |
11 | <p><a href="#introduction">Introduction</a><br> | |
12 | <a href="#synopsis">Synopsis</a><br> | |
13 | <a href="#common">Common Requirements</a><br> | |
14 | <a href="#functions">Free Functions</a><br> | |
15 | <a href="#history">History</a><br> | |
16 | <a href="#references">References</a></p> | |
17 | <h2><a name="introduction">Introduction</a></h2> | |
18 | <p>Originally the Boost function templates <code>make_shared</code> and | |
19 | <code>allocate_shared</code> were for efficient allocation of shared | |
20 | objects only. There was a need to have efficient allocation of | |
21 | shared arrays. One criticism of class template <code>shared_array</code> | |
22 | was always the lack of a <a href="make_shared.html">make_shared</a> | |
23 | utility which ensures only a single allocation.</p> | |
24 | <p>The header files <boost/smart_ptr/make_shared_array.hpp> and | |
25 | <boost/smart_ptr/allocate_shared_array.hpp> provide function | |
26 | templates, overloads of <code>make_shared</code> and | |
27 | <code>allocate_shared</code> for array types, to address this need. | |
28 | <code>make_shared</code> uses the global operator <code>new</code> to | |
29 | allocate memory, whereas <code>allocate_shared</code> uses an | |
30 | user-supplied allocator, allowing finer control.</p> | |
31 | <h2><a name="synopsis">Synopsis</a></h2> | |
32 | <pre>namespace boost { | |
33 | template<class U> // U is T[] | |
34 | shared_ptr<U> <a href="#functions">make_shared</a>(size_t size); | |
35 | ||
36 | template<class U, class A> // U is T[] | |
37 | shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size); | |
38 | ||
39 | template<class U> // U is T[N] | |
40 | shared_ptr<U> <a href="#functions">make_shared</a>(); | |
41 | ||
42 | template<class U, class A> // U is T[N] | |
43 | shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator); | |
44 | ||
45 | template<class U> // U is T[] | |
46 | shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T& value); | |
47 | ||
48 | template<class U, class A> // U is T[] | |
49 | shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T& value); | |
50 | ||
51 | template<class U> // U is T[N] | |
52 | shared_ptr<U> <a href="#functions">make_shared</a>(const T& value); | |
53 | ||
54 | template<class U, class A> // U is T[N] | |
55 | shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T& value); | |
56 | ||
57 | template<class U> // U is T[] | |
58 | shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size); | |
59 | ||
60 | template<class U, class A> // U is T[] | |
61 | shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size); | |
62 | ||
63 | template<class U> // U is T[N] | |
64 | shared_ptr<U> <a href="#functions">make_shared_noinit</a>(); | |
65 | ||
66 | template<class U, class A> // U is T[N] | |
67 | shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator); | |
68 | }</pre> | |
69 | <h2><a name="common">Common Requirements</a></h2> | |
70 | <pre>template<class U> | |
71 | shared_ptr<U> make_shared(<em>args</em>); | |
72 | template<class U, class A> | |
73 | shared_ptr<U> allocate_shared(const A& allocator, <em>args</em>); | |
74 | template<class U> | |
75 | shared_ptr<U> make_shared_noinit(<em>args</em>); | |
76 | template<class U, class A> | |
77 | shared_ptr<U> allocate_shared_noinit(const A& allocator, <em>args</em>);</pre> | |
78 | <blockquote> | |
79 | <p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or | |
80 | <code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as | |
81 | described in section 17.6.3.5 [<strong>Allocator | |
82 | requirements</strong>] of the C++ Standard. The copy constructor and | |
83 | destructor of <code>A</code> shall not throw exceptions.</p> | |
84 | <p><b>Effects:</b> Allocates memory for an object of type <code>U</code> | |
85 | (or <code>T[size]</code> when <code>U</code> is <code>T[]</code>, | |
86 | where <code>size</code> is determined from <code><em>args</em></code> | |
87 | as specified by the concrete overload). The object is initialized as | |
88 | specified by the concrete overload. The templates | |
89 | <code>allocate_shared</code> and <code>allocate_shared_noinit</code> | |
90 | use a copy of <code>allocator</code> to allocate memory. If an | |
91 | exception is thrown, the functions have no effect.</p> | |
92 | <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and | |
93 | owns the address of the newly constructed object.</p> | |
94 | <p><b>Postconditions:</b> <code>r.get() != 0 && | |
95 | r.use_count() == 1</code>, where <code>r</code> is the return | |
96 | value.</p> | |
97 | <p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from | |
98 | <code>A::allocate</code>, or from the initialization of the | |
99 | object.</p> | |
100 | <p><b>Remarks:</b></p> | |
101 | <blockquote> | |
102 | <p>This implementation performs no more than one memory | |
103 | allocation. This provides efficiency to equivalent to an intrusive | |
104 | smart pointer.</p> | |
105 | <p>When an object of an array type <code>T</code> is specified to be | |
106 | initialized to a value of the same type <code>value</code>, this | |
107 | shall be interpreted to mean that each array element of the object | |
108 | is initialized to the corresponding element from | |
109 | <code>value</code>.</p> | |
110 | <p>When an object of an array type is specified to be | |
111 | value-initialized, this shall be interpreted to mean that each | |
112 | array element of the object is value-initialized.</p> | |
113 | <p>Array elements are initialized in ascending order of their | |
114 | addresses.</p> | |
115 | <p>When a subobject of a non-array type <code>T</code> is specified to | |
116 | be initialized to a value <code>value</code>, | |
117 | <code>make_shared</code> shall perform this initialization via the | |
118 | expression <code>::new(ptr) T(value)</code>, where <code>ptr</code> | |
119 | has type <code>void*</code> and points to storage suitable to hold | |
120 | an object of type <code>T</code>.</p> | |
121 | <p>When a subobject of non-array type <code>T</code> is specified to | |
122 | be initialized to a value <code>value</code>, | |
123 | <code>allocate_shared</code> shall perform this initialization via | |
124 | the expression <code>allocator_traits<A2>::construct(a2, ptr, | |
125 | value)</code>, where <code>ptr</code> points to storage suitable to | |
126 | hold an object of type <code>T</code> and <code>a2</code> of type A2 | |
127 | is a rebound copy of the allocator <code>allocator</code> passed to | |
128 | <code>allocate_shared</code> such that its <code>value_type</code> | |
129 | is <code>T</code>.</p> | |
130 | <p>When a subobject of non-array type <code>T</code> is specified to | |
131 | be value-initialized, <code>make_shared</code> shall perform this | |
132 | initialization via the expression <code>::new(ptr) T()</code>, where | |
133 | <code>ptr</code> has type <code>void*</code> and points to storage | |
134 | suitable to hold an object of type <code>T</code>.</p> | |
135 | <p>When a subobject of non-array type <code>T</code> is specified to | |
136 | be value-initialized, <code>allocate_shared</code> shall perform | |
137 | this initialization via the expression | |
138 | <code>allocator_traits<A2>::construct(a2, ptr)</code>, where | |
139 | <code>ptr</code> points to storage suitable to hold an object | |
140 | of type <code>T</code> and <code>a2</code> of type A2 is a rebound | |
141 | copy of the allocator <code>allocator</code> passed to | |
142 | <code>allocate_shared</code> such that its <code>value_type</code> | |
143 | is <code>T</code>.</p> | |
144 | <p>When a subobject of non-array type <code>T</code> is specified to | |
145 | be default-initialized, <code>make_shared_noinit</code> and | |
146 | <code>allocate_shared_noinit</code> shall perform this | |
147 | initialization via the expression <code>::new(ptr) T</code>, where | |
148 | <code>ptr</code> has type <code>void*</code> and points to storage | |
149 | suitable to hold an object of type <code>T</code>.</p> | |
150 | <p>When the lifetime of the object managed by the return value ends, | |
151 | or when the initialization of an array element throws an exception, | |
152 | the initialized elements should be destroyed in the reverse order | |
153 | of their construction.</p> | |
154 | </blockquote> | |
155 | <p><b>Notes:</b> These functions will typically allocate more memory | |
156 | than <code>sizeof(U)</code> to allow for internal bookkeeping | |
157 | structures such as the reference counts.</p> | |
158 | </blockquote> | |
159 | <h2><a name="functions">Free Functions</a></h2> | |
160 | <pre>template<class U> | |
161 | shared_ptr<U> make_shared(size_t size); | |
162 | template<class U, class A> | |
163 | shared_ptr<U> allocate_shared(const A& allocator, size_t size);</pre> | |
164 | <blockquote> | |
165 | <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized | |
166 | object of type <code>T[size]</code>.</p> | |
167 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
168 | resolution when <code>U</code> is of the form <code>T[]</code>.</p> | |
169 | <p><b>Examples:</b></p> | |
170 | <blockquote> | |
171 | <pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size); | |
172 | boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);</pre> | |
173 | </blockquote> | |
174 | </blockquote> | |
175 | <pre>template<class U> | |
176 | shared_ptr<U> make_shared(); | |
177 | template<class U, class A> | |
178 | shared_ptr<U> allocate_shared(const A& allocator);</pre> | |
179 | <blockquote> | |
180 | <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized | |
181 | object of type <code>T[N]</code>.</p> | |
182 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
183 | resolution when <code>U</code> is of the form <code>T[N]</code>.</p> | |
184 | <p><b>Examples:</b></p> | |
185 | <blockquote> | |
186 | <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(); | |
187 | boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();</pre> | |
188 | </blockquote> | |
189 | </blockquote> | |
190 | <pre>template<class U> | |
191 | shared_ptr<U> make_shared(size_t size, const T& value); | |
192 | template<class U, class A> | |
193 | shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);</pre> | |
194 | <blockquote> | |
195 | <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type | |
196 | <code>T[size]</code>, where each array element of type <code>T</code> | |
197 | is initialized to <code>value</code>.</p> | |
198 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
199 | resolution when <code>U</code> is of the form <code>T[]</code>.</p> | |
200 | <p><b>Examples:</b></p> | |
201 | <blockquote> | |
202 | <pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1); | |
203 | boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});</pre> | |
204 | </blockquote> | |
205 | </blockquote> | |
206 | <pre>template<class U> | |
207 | shared_ptr<U> make_shared(const T& value); | |
208 | template<class U, class A> | |
209 | shared_ptr<U> allocate_shared(const A& allocator, const T& value);</pre> | |
210 | <blockquote> | |
211 | <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type | |
212 | <code>T[N]</code>, where each array element of type <code>T</code> is | |
213 | initialized to <code>value</code>.</p> | |
214 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
215 | resolution when <code>U</code> is of the form <code>T[N]</code>.</p> | |
216 | <p><b>Examples:</b></p> | |
217 | <blockquote> | |
218 | <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1); | |
219 | boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});</pre> | |
220 | </blockquote> | |
221 | </blockquote> | |
222 | <pre>template<class U> | |
223 | shared_ptr<U> make_shared_noinit(size_t size); | |
224 | template<class U, class A> | |
225 | shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);</pre> | |
226 | <blockquote> | |
227 | <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized | |
228 | object of type <code>T[size]</code>.</p> | |
229 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
230 | resolution when <code>U</code> is of the form <code>T[]</code>.</p> | |
231 | <p><b>Examples:</b></p> | |
232 | <blockquote> | |
233 | <pre>boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size); | |
234 | boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);</pre> | |
235 | </blockquote> | |
236 | </blockquote> | |
237 | <pre>template<class U> | |
238 | shared_ptr<U> make_shared_noinit(); | |
239 | template<class U, class A> | |
240 | shared_ptr<U> allocate_shared_noinit(const A& allocator);</pre> | |
241 | <blockquote> | |
242 | <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized | |
243 | object of type <code>T[N]</code>.</p> | |
244 | <p><b>Remarks:</b> These overloads shall only participate in overload | |
245 | resolution when <code>U</code> is of the form <code>T[N]</code>.</p> | |
246 | <p><b>Examples:</b></p> | |
247 | <blockquote> | |
248 | <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>(); | |
249 | boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]>();</pre> | |
250 | </blockquote> | |
251 | </blockquote> | |
252 | <h2><a name="history">History</a></h2> | |
253 | <p>February 2014. Glen Fernandes updated overloads of make_shared and | |
254 | allocate_shared to conform to the specification in C++ standard paper | |
255 | <a href="#N3870">N3870</a>, including resolving C++ standard library | |
256 | defect report 2070, and reduced the spatial overhead of the internal | |
257 | bookkeeping structures.</p> | |
258 | <p>November 2012. Glen Fernandes contributed implementations of | |
259 | make_shared and allocate_shared for arrays.</p> | |
260 | <h2><a name="references">References</a></h2> | |
261 | <p><a name="N3870">N3870</a>, | |
262 | <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html"> | |
263 | Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov | |
264 | & Glen Fernandes, January, 2014.</p> | |
265 | <hr> | |
266 | <p>$Date$</p> | |
267 | <p><small>Copyright 2012-2014 Glen Fernandes. Distributed under the | |
268 | Boost Software License, Version 1.0. See accompanying file | |
269 | <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at | |
270 | <a href="http://www.boost.org/LICENSE_1_0.txt"> | |
271 | http://www.boost.org/LICENSE_1_0.txt</a>.</small></p> | |
272 | </body> | |
273 | </html> |