Chris@16
|
1 #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP
|
Chris@16
|
2 #define BOOST_SIGNALS2_DECONSTRUCT_HPP
|
Chris@16
|
3
|
Chris@16
|
4 // deconstruct.hpp
|
Chris@16
|
5 //
|
Chris@16
|
6 // A factory function for creating a shared_ptr which creates
|
Chris@16
|
7 // an object and its owning shared_ptr with one allocation, similar
|
Chris@16
|
8 // to make_shared<T>(). It also supports postconstructors
|
Chris@16
|
9 // and predestructors through unqualified calls of adl_postconstruct() and
|
Chris@16
|
10 // adl_predestruct, relying on argument-dependent
|
Chris@16
|
11 // lookup to find the appropriate postconstructor or predestructor.
|
Chris@16
|
12 // Passing arguments to postconstructors is also supported.
|
Chris@16
|
13 //
|
Chris@16
|
14 // based on make_shared.hpp and make_shared_access patch from Michael Marcin
|
Chris@16
|
15 //
|
Chris@16
|
16 // Copyright (c) 2007, 2008 Peter Dimov
|
Chris@16
|
17 // Copyright (c) 2008 Michael Marcin
|
Chris@16
|
18 // Copyright (c) 2009 Frank Mori Hess
|
Chris@16
|
19 //
|
Chris@16
|
20 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
21 // See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
22 // http://www.boost.org/LICENSE_1_0.txt
|
Chris@16
|
23 //
|
Chris@16
|
24 // See http://www.boost.org
|
Chris@16
|
25 // for more information
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/config.hpp>
|
Chris@16
|
28 #include <boost/shared_ptr.hpp>
|
Chris@16
|
29 #include <boost/type_traits/alignment_of.hpp>
|
Chris@16
|
30 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
31 #include <boost/type_traits/type_with_alignment.hpp>
|
Chris@16
|
32 #include <cstddef>
|
Chris@16
|
33 #include <new>
|
Chris@16
|
34
|
Chris@16
|
35 namespace boost
|
Chris@16
|
36 {
|
Chris@16
|
37 template<typename T> class enable_shared_from_this;
|
Chris@16
|
38
|
Chris@16
|
39 namespace signals2
|
Chris@16
|
40 {
|
Chris@16
|
41 class deconstruct_access;
|
Chris@16
|
42
|
Chris@16
|
43 namespace detail
|
Chris@16
|
44 {
|
Chris@16
|
45 inline void adl_predestruct(...) {}
|
Chris@16
|
46 } // namespace detail
|
Chris@16
|
47
|
Chris@16
|
48 template<typename T>
|
Chris@16
|
49 class postconstructor_invoker
|
Chris@16
|
50 {
|
Chris@16
|
51 public:
|
Chris@16
|
52 operator const shared_ptr<T> & () const
|
Chris@16
|
53 {
|
Chris@16
|
54 return postconstruct();
|
Chris@16
|
55 }
|
Chris@16
|
56 const shared_ptr<T>& postconstruct() const
|
Chris@16
|
57 {
|
Chris@16
|
58 if(!_postconstructed)
|
Chris@16
|
59 {
|
Chris@16
|
60 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()));
|
Chris@16
|
61 _postconstructed = true;
|
Chris@16
|
62 }
|
Chris@16
|
63 return _sp;
|
Chris@16
|
64 }
|
Chris@16
|
65 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
66 template<class... Args>
|
Chris@16
|
67 const shared_ptr<T>& postconstruct(Args && ... args)
|
Chris@16
|
68 {
|
Chris@16
|
69 if(!_postconstructed)
|
Chris@16
|
70 {
|
Chris@16
|
71 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
72 std::forward<Args>(args)...);
|
Chris@16
|
73 _postconstructed = true;
|
Chris@16
|
74 }
|
Chris@16
|
75 return _sp;
|
Chris@16
|
76 }
|
Chris@16
|
77 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
78 template<typename A1>
|
Chris@16
|
79 const shared_ptr<T>& postconstruct(const A1 &a1) const
|
Chris@16
|
80 {
|
Chris@16
|
81 if(!_postconstructed)
|
Chris@16
|
82 {
|
Chris@16
|
83 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
84 a1);
|
Chris@16
|
85 _postconstructed = true;
|
Chris@16
|
86 }
|
Chris@16
|
87 return _sp;
|
Chris@16
|
88 }
|
Chris@16
|
89 template<typename A1, typename A2>
|
Chris@16
|
90 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2) const
|
Chris@16
|
91 {
|
Chris@16
|
92 if(!_postconstructed)
|
Chris@16
|
93 {
|
Chris@16
|
94 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
95 a1, a2);
|
Chris@16
|
96 _postconstructed = true;
|
Chris@16
|
97 }
|
Chris@16
|
98 return _sp;
|
Chris@16
|
99 }
|
Chris@16
|
100 template<typename A1, typename A2, typename A3>
|
Chris@16
|
101 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3) const
|
Chris@16
|
102 {
|
Chris@16
|
103 if(!_postconstructed)
|
Chris@16
|
104 {
|
Chris@16
|
105 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
106 a1, a2, a3);
|
Chris@16
|
107 _postconstructed = true;
|
Chris@16
|
108 }
|
Chris@16
|
109 return _sp;
|
Chris@16
|
110 }
|
Chris@16
|
111 template<typename A1, typename A2, typename A3, typename A4>
|
Chris@16
|
112 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const
|
Chris@16
|
113 {
|
Chris@16
|
114 if(!_postconstructed)
|
Chris@16
|
115 {
|
Chris@16
|
116 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
117 a1, a2, a3, a4);
|
Chris@16
|
118 _postconstructed = true;
|
Chris@16
|
119 }
|
Chris@16
|
120 return _sp;
|
Chris@16
|
121 }
|
Chris@16
|
122 template<typename A1, typename A2, typename A3, typename A4, typename A5>
|
Chris@16
|
123 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const
|
Chris@16
|
124 {
|
Chris@16
|
125 if(!_postconstructed)
|
Chris@16
|
126 {
|
Chris@16
|
127 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
128 a1, a2, a3, a4, a5);
|
Chris@16
|
129 _postconstructed = true;
|
Chris@16
|
130 }
|
Chris@16
|
131 return _sp;
|
Chris@16
|
132 }
|
Chris@16
|
133 template<typename A1, typename A2, typename A3, typename A4, typename A5,
|
Chris@16
|
134 typename A6>
|
Chris@16
|
135 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
|
Chris@16
|
136 const A6 &a6) const
|
Chris@16
|
137 {
|
Chris@16
|
138 if(!_postconstructed)
|
Chris@16
|
139 {
|
Chris@16
|
140 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
141 a1, a2, a3, a4, a5, a6);
|
Chris@16
|
142 _postconstructed = true;
|
Chris@16
|
143 }
|
Chris@16
|
144 return _sp;
|
Chris@16
|
145 }
|
Chris@16
|
146 template<typename A1, typename A2, typename A3, typename A4, typename A5,
|
Chris@16
|
147 typename A6, typename A7>
|
Chris@16
|
148 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
|
Chris@16
|
149 const A6 &a6, const A7 &a7) const
|
Chris@16
|
150 {
|
Chris@16
|
151 if(!_postconstructed)
|
Chris@16
|
152 {
|
Chris@16
|
153 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
154 a1, a2, a3, a4, a5, a6, a7);
|
Chris@16
|
155 _postconstructed = true;
|
Chris@16
|
156 }
|
Chris@16
|
157 return _sp;
|
Chris@16
|
158 }
|
Chris@16
|
159 template<typename A1, typename A2, typename A3, typename A4, typename A5,
|
Chris@16
|
160 typename A6, typename A7, typename A8>
|
Chris@16
|
161 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
|
Chris@16
|
162 const A6 &a6, const A7 &a7, const A8 &a8) const
|
Chris@16
|
163 {
|
Chris@16
|
164 if(!_postconstructed)
|
Chris@16
|
165 {
|
Chris@16
|
166 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
167 a1, a2, a3, a4, a5, a6, a7, a8);
|
Chris@16
|
168 _postconstructed = true;
|
Chris@16
|
169 }
|
Chris@16
|
170 return _sp;
|
Chris@16
|
171 }
|
Chris@16
|
172 template<typename A1, typename A2, typename A3, typename A4, typename A5,
|
Chris@16
|
173 typename A6, typename A7, typename A8, typename A9>
|
Chris@16
|
174 const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
|
Chris@16
|
175 const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) const
|
Chris@16
|
176 {
|
Chris@16
|
177 if(!_postconstructed)
|
Chris@16
|
178 {
|
Chris@16
|
179 adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
|
Chris@16
|
180 a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
Chris@16
|
181 _postconstructed = true;
|
Chris@16
|
182 }
|
Chris@16
|
183 return _sp;
|
Chris@16
|
184 }
|
Chris@16
|
185 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
186 private:
|
Chris@16
|
187 friend class boost::signals2::deconstruct_access;
|
Chris@16
|
188 postconstructor_invoker(const shared_ptr<T> & sp):
|
Chris@16
|
189 _sp(sp), _postconstructed(false)
|
Chris@16
|
190 {}
|
Chris@16
|
191 shared_ptr<T> _sp;
|
Chris@16
|
192 mutable bool _postconstructed;
|
Chris@16
|
193 };
|
Chris@16
|
194
|
Chris@16
|
195 namespace detail
|
Chris@16
|
196 {
|
Chris@16
|
197
|
Chris@16
|
198 template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
Chris@16
|
199 {
|
Chris@16
|
200 union type
|
Chris@16
|
201 {
|
Chris@16
|
202 char data_[ N ];
|
Chris@16
|
203 typename boost::type_with_alignment< A >::type align_;
|
Chris@16
|
204 };
|
Chris@16
|
205 };
|
Chris@16
|
206
|
Chris@16
|
207 template< class T > class deconstruct_deleter
|
Chris@16
|
208 {
|
Chris@16
|
209 private:
|
Chris@16
|
210
|
Chris@16
|
211 typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
Chris@16
|
212
|
Chris@16
|
213 bool initialized_;
|
Chris@16
|
214 storage_type storage_;
|
Chris@16
|
215
|
Chris@16
|
216 private:
|
Chris@16
|
217
|
Chris@16
|
218 void destroy()
|
Chris@16
|
219 {
|
Chris@16
|
220 if( initialized_ )
|
Chris@16
|
221 {
|
Chris@16
|
222 T* p = reinterpret_cast< T* >( storage_.data_ );
|
Chris@16
|
223 using boost::signals2::detail::adl_predestruct;
|
Chris@16
|
224 adl_predestruct(const_cast<typename boost::remove_const<T>::type *>(p));
|
Chris@16
|
225 p->~T();
|
Chris@16
|
226 initialized_ = false;
|
Chris@16
|
227 }
|
Chris@16
|
228 }
|
Chris@16
|
229
|
Chris@16
|
230 public:
|
Chris@16
|
231
|
Chris@16
|
232 deconstruct_deleter(): initialized_( false )
|
Chris@16
|
233 {
|
Chris@16
|
234 }
|
Chris@16
|
235
|
Chris@16
|
236 // this copy constructor is an optimization: we don't need to copy the storage_ member,
|
Chris@16
|
237 // and shouldn't be copying anyways after initialized_ becomes true
|
Chris@16
|
238 deconstruct_deleter(const deconstruct_deleter &): initialized_( false )
|
Chris@16
|
239 {
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242 ~deconstruct_deleter()
|
Chris@16
|
243 {
|
Chris@16
|
244 destroy();
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 void operator()( T * )
|
Chris@16
|
248 {
|
Chris@16
|
249 destroy();
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 void * address()
|
Chris@16
|
253 {
|
Chris@16
|
254 return storage_.data_;
|
Chris@16
|
255 }
|
Chris@16
|
256
|
Chris@16
|
257 void set_initialized()
|
Chris@16
|
258 {
|
Chris@16
|
259 initialized_ = true;
|
Chris@16
|
260 }
|
Chris@16
|
261 };
|
Chris@16
|
262 } // namespace detail
|
Chris@16
|
263
|
Chris@16
|
264 class deconstruct_access
|
Chris@16
|
265 {
|
Chris@16
|
266 public:
|
Chris@16
|
267
|
Chris@16
|
268 template< class T >
|
Chris@16
|
269 static postconstructor_invoker<T> deconstruct()
|
Chris@16
|
270 {
|
Chris@16
|
271 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
272
|
Chris@16
|
273 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
274
|
Chris@16
|
275 void * pv = pd->address();
|
Chris@16
|
276
|
Chris@16
|
277 new( pv ) T();
|
Chris@16
|
278 pd->set_initialized();
|
Chris@16
|
279
|
Chris@16
|
280 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
281 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
282 return retval;
|
Chris@16
|
283
|
Chris@16
|
284 }
|
Chris@16
|
285
|
Chris@16
|
286 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
287
|
Chris@16
|
288 // Variadic templates, rvalue reference
|
Chris@16
|
289
|
Chris@16
|
290 template< class T, class... Args >
|
Chris@16
|
291 static postconstructor_invoker<T> deconstruct( Args && ... args )
|
Chris@16
|
292 {
|
Chris@16
|
293 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
294
|
Chris@16
|
295 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
296
|
Chris@16
|
297 void * pv = pd->address();
|
Chris@16
|
298
|
Chris@16
|
299 new( pv ) T( std::forward<Args>( args )... );
|
Chris@16
|
300 pd->set_initialized();
|
Chris@16
|
301
|
Chris@16
|
302 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
303 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
304 return retval;
|
Chris@16
|
305 }
|
Chris@16
|
306
|
Chris@16
|
307 #else
|
Chris@16
|
308
|
Chris@16
|
309 template< class T, class A1 >
|
Chris@16
|
310 static postconstructor_invoker<T> deconstruct( A1 const & a1 )
|
Chris@16
|
311 {
|
Chris@16
|
312 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
313
|
Chris@16
|
314 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
315
|
Chris@16
|
316 void * pv = pd->address();
|
Chris@16
|
317
|
Chris@16
|
318 new( pv ) T( a1 );
|
Chris@16
|
319 pd->set_initialized();
|
Chris@16
|
320
|
Chris@16
|
321 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
322 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
323 return retval;
|
Chris@16
|
324 }
|
Chris@16
|
325
|
Chris@16
|
326 template< class T, class A1, class A2 >
|
Chris@16
|
327 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 )
|
Chris@16
|
328 {
|
Chris@16
|
329 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
330
|
Chris@16
|
331 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
332
|
Chris@16
|
333 void * pv = pd->address();
|
Chris@16
|
334
|
Chris@16
|
335 new( pv ) T( a1, a2 );
|
Chris@16
|
336 pd->set_initialized();
|
Chris@16
|
337
|
Chris@16
|
338 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
339 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
340 return retval;
|
Chris@16
|
341 }
|
Chris@16
|
342
|
Chris@16
|
343 template< class T, class A1, class A2, class A3 >
|
Chris@16
|
344 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
|
Chris@16
|
345 {
|
Chris@16
|
346 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
347
|
Chris@16
|
348 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
349
|
Chris@16
|
350 void * pv = pd->address();
|
Chris@16
|
351
|
Chris@16
|
352 new( pv ) T( a1, a2, a3 );
|
Chris@16
|
353 pd->set_initialized();
|
Chris@16
|
354
|
Chris@16
|
355 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
356 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
357 return retval;
|
Chris@16
|
358 }
|
Chris@16
|
359
|
Chris@16
|
360 template< class T, class A1, class A2, class A3, class A4 >
|
Chris@16
|
361 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
Chris@16
|
362 {
|
Chris@16
|
363 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
364
|
Chris@16
|
365 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
366
|
Chris@16
|
367 void * pv = pd->address();
|
Chris@16
|
368
|
Chris@16
|
369 new( pv ) T( a1, a2, a3, a4 );
|
Chris@16
|
370 pd->set_initialized();
|
Chris@16
|
371
|
Chris@16
|
372 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
373 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
374 return retval;
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 template< class T, class A1, class A2, class A3, class A4, class A5 >
|
Chris@16
|
378 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
Chris@16
|
379 {
|
Chris@16
|
380 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
381
|
Chris@16
|
382 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
383
|
Chris@16
|
384 void * pv = pd->address();
|
Chris@16
|
385
|
Chris@16
|
386 new( pv ) T( a1, a2, a3, a4, a5 );
|
Chris@16
|
387 pd->set_initialized();
|
Chris@16
|
388
|
Chris@16
|
389 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
390 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
391 return retval;
|
Chris@16
|
392 }
|
Chris@16
|
393
|
Chris@16
|
394 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
Chris@16
|
395 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
Chris@16
|
396 {
|
Chris@16
|
397 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
398
|
Chris@16
|
399 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
400
|
Chris@16
|
401 void * pv = pd->address();
|
Chris@16
|
402
|
Chris@16
|
403 new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
Chris@16
|
404 pd->set_initialized();
|
Chris@16
|
405
|
Chris@16
|
406 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
407 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
408 return retval;
|
Chris@16
|
409 }
|
Chris@16
|
410
|
Chris@16
|
411 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
Chris@16
|
412 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
Chris@16
|
413 {
|
Chris@16
|
414 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
415
|
Chris@16
|
416 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
417
|
Chris@16
|
418 void * pv = pd->address();
|
Chris@16
|
419
|
Chris@16
|
420 new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
Chris@16
|
421 pd->set_initialized();
|
Chris@16
|
422
|
Chris@16
|
423 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
424 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
425 return retval;
|
Chris@16
|
426 }
|
Chris@16
|
427
|
Chris@16
|
428 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
Chris@16
|
429 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
Chris@16
|
430 {
|
Chris@16
|
431 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
432
|
Chris@16
|
433 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
434
|
Chris@16
|
435 void * pv = pd->address();
|
Chris@16
|
436
|
Chris@16
|
437 new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
Chris@16
|
438 pd->set_initialized();
|
Chris@16
|
439
|
Chris@16
|
440 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
441 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
442 return retval;
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
Chris@16
|
446 static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
Chris@16
|
447 {
|
Chris@16
|
448 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
|
Chris@16
|
449
|
Chris@16
|
450 detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt );
|
Chris@16
|
451
|
Chris@16
|
452 void * pv = pd->address();
|
Chris@16
|
453
|
Chris@16
|
454 new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
Chris@16
|
455 pd->set_initialized();
|
Chris@16
|
456
|
Chris@16
|
457 boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
|
Chris@16
|
458 boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get());
|
Chris@16
|
459 return retval;
|
Chris@16
|
460 }
|
Chris@16
|
461
|
Chris@16
|
462 #endif
|
Chris@16
|
463 };
|
Chris@16
|
464
|
Chris@16
|
465 // Zero-argument versions
|
Chris@16
|
466 //
|
Chris@16
|
467 // Used even when variadic templates are available because of the new T() vs new T issue
|
Chris@16
|
468
|
Chris@16
|
469 template< class T > postconstructor_invoker<T> deconstruct()
|
Chris@16
|
470 {
|
Chris@16
|
471 return deconstruct_access::deconstruct<T>();
|
Chris@16
|
472 }
|
Chris@16
|
473
|
Chris@16
|
474 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
475
|
Chris@16
|
476 // Variadic templates, rvalue reference
|
Chris@16
|
477
|
Chris@16
|
478 template< class T, class... Args > postconstructor_invoker< T > deconstruct( Args && ... args )
|
Chris@16
|
479 {
|
Chris@16
|
480 return deconstruct_access::deconstruct<T>( std::forward<Args>( args )... );
|
Chris@16
|
481 }
|
Chris@16
|
482
|
Chris@16
|
483 #else
|
Chris@16
|
484
|
Chris@16
|
485 // C++03 version
|
Chris@16
|
486
|
Chris@16
|
487 template< class T, class A1 >
|
Chris@16
|
488 postconstructor_invoker<T> deconstruct( A1 const & a1 )
|
Chris@16
|
489 {
|
Chris@16
|
490 return deconstruct_access::deconstruct<T>(a1);
|
Chris@16
|
491 }
|
Chris@16
|
492
|
Chris@16
|
493 template< class T, class A1, class A2 >
|
Chris@16
|
494 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 )
|
Chris@16
|
495 {
|
Chris@16
|
496 return deconstruct_access::deconstruct<T>(a1,a2);
|
Chris@16
|
497 }
|
Chris@16
|
498
|
Chris@16
|
499 template< class T, class A1, class A2, class A3 >
|
Chris@16
|
500 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
|
Chris@16
|
501 {
|
Chris@16
|
502 return deconstruct_access::deconstruct<T>(a1,a2,a3);
|
Chris@16
|
503 }
|
Chris@16
|
504
|
Chris@16
|
505 template< class T, class A1, class A2, class A3, class A4 >
|
Chris@16
|
506 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
Chris@16
|
507 {
|
Chris@16
|
508 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4);
|
Chris@16
|
509 }
|
Chris@16
|
510
|
Chris@16
|
511 template< class T, class A1, class A2, class A3, class A4, class A5 >
|
Chris@16
|
512 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
Chris@16
|
513 {
|
Chris@16
|
514 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5);
|
Chris@16
|
515 }
|
Chris@16
|
516
|
Chris@16
|
517 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
Chris@16
|
518 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
Chris@16
|
519 {
|
Chris@16
|
520 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6);
|
Chris@16
|
521 }
|
Chris@16
|
522
|
Chris@16
|
523 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
Chris@16
|
524 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
Chris@16
|
525 {
|
Chris@16
|
526 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7);
|
Chris@16
|
527 }
|
Chris@16
|
528
|
Chris@16
|
529 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
Chris@16
|
530 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
Chris@16
|
531 {
|
Chris@16
|
532 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8);
|
Chris@16
|
533 }
|
Chris@16
|
534
|
Chris@16
|
535 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
Chris@16
|
536 postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
Chris@16
|
537 {
|
Chris@16
|
538 return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8,a9);
|
Chris@16
|
539 }
|
Chris@16
|
540
|
Chris@16
|
541 #endif
|
Chris@16
|
542
|
Chris@16
|
543 } // namespace signals2
|
Chris@16
|
544 } // namespace boost
|
Chris@16
|
545
|
Chris@16
|
546 #endif // #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP
|