]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/tr1_impl/boost_shared_ptr.h
mips.h (ISA_HAS_SEQ_SNE): New macro.
[thirdparty/gcc.git] / libstdc++-v3 / include / tr1_impl / boost_shared_ptr.h
CommitLineData
e133ace8 1// <tr1_impl/boost_shared_ptr.h> -*- C++ -*-
b758b22a 2
08df5d3e 3// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
b758b22a
BK
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING. If not, write to the Free
83f51799 18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
b758b22a
BK
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30// shared_count.hpp
31// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
32
33// shared_ptr.hpp
34// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
35// Copyright (C) 2001, 2002, 2003 Peter Dimov
36
37// weak_ptr.hpp
38// Copyright (C) 2001, 2002, 2003 Peter Dimov
39
40// enable_shared_from_this.hpp
41// Copyright (C) 2002 Peter Dimov
42
43// Distributed under the Boost Software License, Version 1.0. (See
44// accompanying file LICENSE_1_0.txt or copy at
45// http://www.boost.org/LICENSE_1_0.txt)
46
47// GCC Note: based on version 1.32.0 of the Boost library.
48
e133ace8 49/** @file tr1_impl/boost_shared_ptr.h
b758b22a
BK
50 * This is an internal header file, included by other library headers.
51 * You should not attempt to use it directly.
52 */
53
aaf0ca6f 54
b758b22a
BK
55namespace std
56{
e133ace8 57_GLIBCXX_BEGIN_NAMESPACE_TR1
b758b22a 58
459f9f82 59 template<_Lock_policy _Lp>
c8bd30dd 60 class __weak_count
a25ce4db 61 {
c8bd30dd
PC
62 public:
63 __weak_count()
459f9f82
PC
64 : _M_pi(0) // nothrow
65 { }
a25ce4db 66
c8bd30dd 67 __weak_count(const __shared_count<_Lp>& __r)
459f9f82
PC
68 : _M_pi(__r._M_pi) // nothrow
69 {
70 if (_M_pi != 0)
c8bd30dd 71 _M_pi->_M_weak_add_ref();
459f9f82
PC
72 }
73
c8bd30dd 74 __weak_count(const __weak_count<_Lp>& __r)
459f9f82
PC
75 : _M_pi(__r._M_pi) // nothrow
76 {
77 if (_M_pi != 0)
c8bd30dd 78 _M_pi->_M_weak_add_ref();
459f9f82
PC
79 }
80
c8bd30dd 81 ~__weak_count() // nothrow
459f9f82
PC
82 {
83 if (_M_pi != 0)
c8bd30dd 84 _M_pi->_M_weak_release();
459f9f82
PC
85 }
86
c8bd30dd
PC
87 __weak_count<_Lp>&
88 operator=(const __shared_count<_Lp>& __r) // nothrow
459f9f82
PC
89 {
90 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
91 if (__tmp != 0)
c8bd30dd 92 __tmp->_M_weak_add_ref();
459f9f82 93 if (_M_pi != 0)
c8bd30dd 94 _M_pi->_M_weak_release();
459f9f82
PC
95 _M_pi = __tmp;
96 return *this;
97 }
98
c8bd30dd
PC
99 __weak_count<_Lp>&
100 operator=(const __weak_count<_Lp>& __r) // nothrow
459f9f82 101 {
c8bd30dd 102 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
459f9f82 103 if (__tmp != 0)
c8bd30dd 104 __tmp->_M_weak_add_ref();
459f9f82 105 if (_M_pi != 0)
c8bd30dd 106 _M_pi->_M_weak_release();
459f9f82
PC
107 _M_pi = __tmp;
108 return *this;
109 }
c8bd30dd 110
459f9f82 111 void
c8bd30dd 112 _M_swap(__weak_count<_Lp>& __r) // nothrow
459f9f82 113 {
c8bd30dd 114 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
459f9f82
PC
115 __r._M_pi = _M_pi;
116 _M_pi = __tmp;
117 }
a25ce4db 118
459f9f82 119 long
c8bd30dd
PC
120 _M_get_use_count() const // nothrow
121 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
122
459f9f82 123 friend inline bool
c8bd30dd 124 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
459f9f82
PC
125 { return __a._M_pi == __b._M_pi; }
126
127 friend inline bool
c8bd30dd 128 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
459f9f82 129 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
c8bd30dd
PC
130
131 private:
132 friend class __shared_count<_Lp>;
133
134 _Sp_counted_base<_Lp>* _M_pi;
459f9f82
PC
135 };
136
aaf0ca6f 137 // now that __weak_count is defined we can define this constructor:
459f9f82
PC
138 template<_Lock_policy _Lp>
139 inline
c8bd30dd
PC
140 __shared_count<_Lp>::
141 __shared_count(const __weak_count<_Lp>& __r)
459f9f82 142 : _M_pi(__r._M_pi)
a25ce4db 143 {
a25ce4db 144 if (_M_pi != 0)
c8bd30dd 145 _M_pi->_M_add_ref_lock();
459f9f82
PC
146 else
147 __throw_bad_weak_ptr();
a25ce4db 148 }
459f9f82 149
c8bd30dd 150 // Forward declarations.
459f9f82
PC
151 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
152 class __shared_ptr;
a25ce4db 153
459f9f82
PC
154 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
155 class __weak_ptr;
b758b22a 156
c8bd30dd 157 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
459f9f82 158 class __enable_shared_from_this;
b758b22a 159
c8bd30dd
PC
160 template<typename _Tp>
161 class shared_ptr;
162
163 template<typename _Tp>
164 class weak_ptr;
a15024e6 165
c8bd30dd
PC
166 template<typename _Tp>
167 class enable_shared_from_this;
b758b22a 168
459f9f82 169 // Support for enable_shared_from_this.
b758b22a 170
459f9f82
PC
171 // Friend of __enable_shared_from_this.
172 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
173 void
c8bd30dd 174 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
459f9f82
PC
175 const __enable_shared_from_this<_Tp1,
176 _Lp>*, const _Tp2*);
b758b22a 177
c8bd30dd
PC
178 // Friend of enable_shared_from_this.
179 template<typename _Tp1, typename _Tp2>
180 void
181 __enable_shared_from_this_helper(const __shared_count<>&,
182 const enable_shared_from_this<_Tp1>*,
183 const _Tp2*);
184
459f9f82
PC
185 template<_Lock_policy _Lp>
186 inline void
c8bd30dd 187 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
459f9f82 188 { }
b758b22a
BK
189
190
aaf0ca6f 191#ifdef _GLIBCXX_INCLUDE_AS_TR1
c8bd30dd
PC
192 struct __static_cast_tag { };
193 struct __const_cast_tag { };
194 struct __dynamic_cast_tag { };
aaf0ca6f 195#endif
c8bd30dd 196
459f9f82 197 /**
939759fc 198 * @class __shared_ptr
459f9f82
PC
199 *
200 * A smart pointer with reference-counted copy semantics.
201 * The object pointed to is deleted when the last shared_ptr pointing to
202 * it is destroyed or reset.
203 */
204 template<typename _Tp, _Lock_policy _Lp>
205 class __shared_ptr
206 {
459f9f82
PC
207 public:
208 typedef _Tp element_type;
209
210 /** @brief Construct an empty %__shared_ptr.
211 * @post use_count()==0 && get()==0
212 */
213 __shared_ptr()
214 : _M_ptr(0), _M_refcount() // never throws
215 { }
b758b22a 216
c8bd30dd
PC
217 /** @brief Construct a %__shared_ptr that owns the pointer @a __p.
218 * @param __p A pointer that is convertible to element_type*.
219 * @post use_count() == 1 && get() == __p
220 * @throw std::bad_alloc, in which case @c delete @a __p is called.
459f9f82
PC
221 */
222 template<typename _Tp1>
223 explicit
224 __shared_ptr(_Tp1* __p)
aaf0ca6f 225 : _M_ptr(__p), _M_refcount(__p)
459f9f82
PC
226 {
227 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
228 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
c8bd30dd 229 __enable_shared_from_this_helper(_M_refcount, __p, __p);
459f9f82 230 }
b758b22a 231
459f9f82 232 //
939759fc
BK
233 // Requirements: _Deleter's copy constructor and destructor must
234 // not throw
459f9f82 235 //
c8bd30dd 236 // __shared_ptr will release __p by calling __d(__p)
459f9f82 237 //
c8bd30dd
PC
238 /** @brief Construct a %__shared_ptr that owns the pointer @a __p
239 * and the deleter @a __d.
240 * @param __p A pointer.
241 * @param __d A deleter.
242 * @post use_count() == 1 && get() == __p
243 * @throw std::bad_alloc, in which case @a __d(__p) is called.
459f9f82
PC
244 */
245 template<typename _Tp1, typename _Deleter>
246 __shared_ptr(_Tp1* __p, _Deleter __d)
aaf0ca6f 247 : _M_ptr(__p), _M_refcount(__p, __d)
459f9f82
PC
248 {
249 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
c8bd30dd
PC
250 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
251 __enable_shared_from_this_helper(_M_refcount, __p, __p);
459f9f82
PC
252 }
253
aaf0ca6f
JW
254#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
255 //
939759fc
BK
256 // Requirements: _Deleter's copy constructor and destructor must
257 // not throw _Alloc's copy constructor and destructor must not
258 // throw.
aaf0ca6f
JW
259 //
260 // __shared_ptr will release __p by calling __d(__p)
261 //
262 /** @brief Construct a %__shared_ptr that owns the pointer @a __p
263 * and the deleter @a __d.
264 * @param __p A pointer.
265 * @param __d A deleter.
266 * @param __a An allocator.
267 * @post use_count() == 1 && get() == __p
268 * @throw std::bad_alloc, in which case @a __d(__p) is called.
269 */
270 template<typename _Tp1, typename _Deleter, typename _Alloc>
271 __shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
272 : _M_ptr(__p), _M_refcount(__p, __d, __a)
273 {
274 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
275 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
276 __enable_shared_from_this_helper(_M_refcount, __p, __p);
277 }
278
279 /** @brief Constructs a %__shared_ptr instance that stores @a __p
280 * and shares ownership with @a __r.
281 * @param __r A %__shared_ptr.
282 * @param __p A pointer that will remain valid while @a *__r is valid.
283 * @post get() == __p && use_count() == __r.use_count()
284 *
285 * This can be used to construct a @c shared_ptr to a sub-object
286 * of an object managed by an existing @c shared_ptr.
287 *
288 * @code
289 * shared_ptr< pair<int,int> > pii(new pair<int,int>());
290 * shared_ptr<int> pi(pii, &pii->first);
291 * assert(pii.use_count() == 2);
292 * @endcode
293 */
294 template<typename _Tp1>
295 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
296 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
297 { }
298#endif
299
459f9f82
PC
300 // generated copy constructor, assignment, destructor are fine.
301
c8bd30dd 302 /** @brief If @a __r is empty, constructs an empty %__shared_ptr;
459f9f82 303 * otherwise construct a %__shared_ptr that shares ownership
c8bd30dd
PC
304 * with @a __r.
305 * @param __r A %__shared_ptr.
306 * @post get() == __r.get() && use_count() == __r.use_count()
459f9f82
PC
307 */
308 template<typename _Tp1>
309 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
310 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
311 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
312
aaf0ca6f
JW
313#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
314 /** @brief Move-constructs a %__shared_ptr instance from @a __r.
315 * @param __r A %__shared_ptr rvalue.
316 * @post *this contains the old value of @a __r, @a __r is empty.
317 */
318 __shared_ptr(__shared_ptr&& __r)
319 : _M_ptr(__r._M_ptr), _M_refcount() // never throws
320 {
321 _M_refcount._M_swap(__r._M_refcount);
322 __r._M_ptr = 0;
323 }
324
325 /** @brief Move-constructs a %__shared_ptr instance from @a __r.
326 * @param __r A %__shared_ptr rvalue.
327 * @post *this contains the old value of @a __r, @a __r is empty.
328 */
329 template<typename _Tp1>
330 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
331 : _M_ptr(__r._M_ptr), _M_refcount() // never throws
332 {
333 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
334 _M_refcount._M_swap(__r._M_refcount);
335 __r._M_ptr = 0;
336 }
337#endif
338
c8bd30dd
PC
339 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r
340 * and stores a copy of the pointer stored in @a __r.
341 * @param __r A weak_ptr.
342 * @post use_count() == __r.use_count()
343 * @throw bad_weak_ptr when __r.expired(),
459f9f82
PC
344 * in which case the constructor has no effect.
345 */
346 template<typename _Tp1>
347 explicit
348 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
349 : _M_refcount(__r._M_refcount) // may throw
350 {
351 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
c8bd30dd 352 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
459f9f82
PC
353 // did not throw.
354 _M_ptr = __r._M_ptr;
355 }
81daf4ba 356
459f9f82 357 /**
c8bd30dd 358 * @post use_count() == 1 and __r.get() == 0
459f9f82 359 */
4dd9d9db 360#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
459f9f82
PC
361 template<typename _Tp1>
362 explicit
363 __shared_ptr(std::auto_ptr<_Tp1>& __r)
364 : _M_ptr(__r.get()), _M_refcount()
365 {
aaf0ca6f
JW
366 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
367 // TODO requires _Tp1 is complete, delete __r.release() well-formed
c8bd30dd
PC
368 _Tp1* __tmp = __r.get();
369 _M_refcount = __shared_count<_Lp>(__r);
370 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
459f9f82 371 }
40abbf1f 372#endif
b758b22a 373
aaf0ca6f 374#ifdef _GLIBCXX_INCLUDE_AS_TR1
459f9f82
PC
375 template<typename _Tp1>
376 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
377 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
378 _M_refcount(__r._M_refcount)
379 { }
380
381 template<typename _Tp1>
382 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
383 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
384 _M_refcount(__r._M_refcount)
385 { }
386
387 template<typename _Tp1>
388 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
389 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
390 _M_refcount(__r._M_refcount)
391 {
392 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
c8bd30dd 393 _M_refcount = __shared_count<_Lp>();
459f9f82 394 }
aaf0ca6f 395#endif
459f9f82
PC
396
397 template<typename _Tp1>
398 __shared_ptr&
399 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
400 {
401 _M_ptr = __r._M_ptr;
c8bd30dd 402 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
459f9f82
PC
403 return *this;
404 }
b758b22a 405
4dd9d9db 406#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
459f9f82
PC
407 template<typename _Tp1>
408 __shared_ptr&
409 operator=(std::auto_ptr<_Tp1>& __r)
410 {
411 __shared_ptr(__r).swap(*this);
412 return *this;
413 }
40abbf1f 414#endif
b758b22a 415
aaf0ca6f
JW
416#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
417 __shared_ptr&
418 operator=(__shared_ptr&& __r)
419 {
420 __shared_ptr(std::move(__r)).swap(*this);
421 return *this;
422 }
423
424 template<class _Tp1>
425 __shared_ptr&
426 operator=(__shared_ptr<_Tp1, _Lp>&& __r)
427 {
428 __shared_ptr(std::move(__r)).swap(*this);
429 return *this;
430 }
431#endif
432
459f9f82
PC
433 void
434 reset() // never throws
435 { __shared_ptr().swap(*this); }
b758b22a 436
459f9f82
PC
437 template<typename _Tp1>
438 void
439 reset(_Tp1* __p) // _Tp1 must be complete.
440 {
441 // Catch self-reset errors.
442 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
443 __shared_ptr(__p).swap(*this);
444 }
b758b22a 445
459f9f82
PC
446 template<typename _Tp1, typename _Deleter>
447 void
c8bd30dd 448 reset(_Tp1* __p, _Deleter __d)
459f9f82 449 { __shared_ptr(__p, __d).swap(*this); }
b758b22a 450
4a27a739 451#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
aaf0ca6f
JW
452 template<typename _Tp1, typename _Deleter, typename _Alloc>
453 void
454 reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
455 { __shared_ptr(__p, __d, __a).swap(*this); }
456
457 // Allow class instantiation when _Tp is [cv-qual] void.
4a27a739
PC
458 typename std::add_lvalue_reference<_Tp>::type
459#else
aaf0ca6f 460 // Allow class instantiation when _Tp is [cv-qual] void.
4a27a739
PC
461 typename std::tr1::add_reference<_Tp>::type
462#endif
459f9f82 463 operator*() const // never throws
b758b22a 464 {
459f9f82
PC
465 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
466 return *_M_ptr;
b758b22a
BK
467 }
468
459f9f82
PC
469 _Tp*
470 operator->() const // never throws
b758b22a 471 {
459f9f82
PC
472 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
473 return _M_ptr;
b758b22a 474 }
459f9f82
PC
475
476 _Tp*
477 get() const // never throws
478 { return _M_ptr; }
b758b22a 479
459f9f82
PC
480 // Implicit conversion to "bool"
481 private:
482 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
b758b22a 483
459f9f82
PC
484 public:
485 operator __unspecified_bool_type() const // never throws
486 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
b758b22a 487
459f9f82
PC
488 bool
489 unique() const // never throws
c8bd30dd 490 { return _M_refcount._M_unique(); }
459f9f82
PC
491
492 long
493 use_count() const // never throws
c8bd30dd 494 { return _M_refcount._M_get_use_count(); }
b758b22a 495
b758b22a 496 void
459f9f82 497 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
b758b22a 498 {
459f9f82 499 std::swap(_M_ptr, __other._M_ptr);
c8bd30dd 500 _M_refcount._M_swap(__other._M_refcount);
b758b22a
BK
501 }
502
aaf0ca6f
JW
503#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
504 protected:
505 // This constructor is non-standard, it is used by allocate_shared.
506 template<typename _Alloc, typename... _Args>
507 __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
08df5d3e
PC
508 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
509 std::forward<_Args>(__args)...)
aaf0ca6f
JW
510 {
511 // _M_ptr needs to point to the newly constructed object.
512 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
08df5d3e 513 void* __p = _M_refcount._M_get_deleter(typeid(__tag));
aaf0ca6f 514 _M_ptr = static_cast<_Tp*>(__p);
08df5d3e 515 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
aaf0ca6f
JW
516 }
517
518 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
519 typename... _Args>
520 friend __shared_ptr<_Tp1, _Lp1>
521 __allocate_shared(_Alloc __a, _Args&&... __args);
522#endif
523
459f9f82
PC
524 private:
525 void*
526 _M_get_deleter(const std::type_info& __ti) const
c8bd30dd 527 { return _M_refcount._M_get_deleter(__ti); }
459f9f82
PC
528
529 template<typename _Tp1, _Lock_policy _Lp1>
530 bool
531 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
532 { return _M_refcount < __rhs._M_refcount; }
533
534 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
535 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
536
537 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
538 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
539
540 // Friends injected into enclosing namespace and found by ADL:
541 template<typename _Tp1>
542 friend inline bool
543 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
544 { return __a.get() == __b.get(); }
545
546 template<typename _Tp1>
547 friend inline bool
548 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
549 { return __a.get() != __b.get(); }
550
551 template<typename _Tp1>
552 friend inline bool
553 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
554 { return __a._M_less(__b); }
555
c8bd30dd
PC
556 _Tp* _M_ptr; // Contained pointer.
557 __shared_count<_Lp> _M_refcount; // Reference counter.
459f9f82
PC
558 };
559
560 // 2.2.3.8 shared_ptr specialized algorithms.
561 template<typename _Tp, _Lock_policy _Lp>
562 inline void
563 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
564 { __a.swap(__b); }
565
566 // 2.2.3.9 shared_ptr casts
567 /** @warning The seemingly equivalent
c8bd30dd 568 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
459f9f82
PC
569 * will eventually result in undefined behaviour,
570 * attempting to delete the same object twice.
571 */
572 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
aaf0ca6f 573 inline __shared_ptr<_Tp, _Lp>
459f9f82 574 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
aaf0ca6f
JW
575 {
576#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
577 return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get()));
578#else
579 return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag());
580#endif
581 }
459f9f82
PC
582
583 /** @warning The seemingly equivalent
c8bd30dd 584 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
459f9f82
PC
585 * will eventually result in undefined behaviour,
586 * attempting to delete the same object twice.
587 */
588 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
aaf0ca6f 589 inline __shared_ptr<_Tp, _Lp>
459f9f82 590 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
aaf0ca6f
JW
591 {
592#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
593 return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get()));
594#else
595 return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag());
596#endif
597 }
459f9f82
PC
598
599 /** @warning The seemingly equivalent
c8bd30dd 600 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
459f9f82
PC
601 * will eventually result in undefined behaviour,
602 * attempting to delete the same object twice.
603 */
604 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
aaf0ca6f 605 inline __shared_ptr<_Tp, _Lp>
459f9f82 606 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
aaf0ca6f
JW
607 {
608#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
609 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
610 return __shared_ptr<_Tp, _Lp>(__r, __p);
611 return __shared_ptr<_Tp, _Lp>();
612#else
613 return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag());
614#endif
615 }
459f9f82
PC
616
617 // 2.2.3.7 shared_ptr I/O
618 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
619 std::basic_ostream<_Ch, _Tr>&
620 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
621 const __shared_ptr<_Tp, _Lp>& __p)
b758b22a 622 {
459f9f82
PC
623 __os << __p.get();
624 return __os;
b758b22a 625 }
b758b22a 626
459f9f82
PC
627 // 2.2.3.10 shared_ptr get_deleter (experimental)
628 template<typename _Del, typename _Tp, _Lock_policy _Lp>
629 inline _Del*
630 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
631 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
b758b22a 632
b758b22a 633
459f9f82
PC
634 template<typename _Tp, _Lock_policy _Lp>
635 class __weak_ptr
b758b22a 636 {
459f9f82
PC
637 public:
638 typedef _Tp element_type;
639
c8bd30dd
PC
640 __weak_ptr()
641 : _M_ptr(0), _M_refcount() // never throws
459f9f82 642 { }
b758b22a 643
459f9f82
PC
644 // Generated copy constructor, assignment, destructor are fine.
645
646 // The "obvious" converting constructor implementation:
647 //
c8bd30dd
PC
648 // template<typename _Tp1>
649 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
650 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
459f9f82
PC
651 // { }
652 //
653 // has a serious problem.
654 //
c8bd30dd
PC
655 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
656 // conversion may require access to *__r._M_ptr (virtual inheritance).
459f9f82
PC
657 //
658 // It is not possible to avoid spurious access violations since
c8bd30dd 659 // in multithreaded programs __r._M_ptr may be invalidated at any point.
459f9f82 660 template<typename _Tp1>
dcd400b5
PC
661 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
662 : _M_refcount(__r._M_refcount) // never throws
459f9f82
PC
663 {
664 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
c8bd30dd 665 _M_ptr = __r.lock().get();
459f9f82 666 }
b758b22a 667
459f9f82 668 template<typename _Tp1>
dcd400b5
PC
669 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
670 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
459f9f82 671 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
b758b22a 672
459f9f82
PC
673 template<typename _Tp1>
674 __weak_ptr&
dcd400b5 675 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
459f9f82 676 {
dcd400b5
PC
677 _M_ptr = __r.lock().get();
678 _M_refcount = __r._M_refcount;
459f9f82
PC
679 return *this;
680 }
681
682 template<typename _Tp1>
683 __weak_ptr&
dcd400b5 684 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
459f9f82 685 {
dcd400b5
PC
686 _M_ptr = __r._M_ptr;
687 _M_refcount = __r._M_refcount;
459f9f82
PC
688 return *this;
689 }
b758b22a 690
459f9f82
PC
691 __shared_ptr<_Tp, _Lp>
692 lock() const // never throws
b758b22a 693 {
b758b22a 694#ifdef __GTHREADS
459f9f82
PC
695 // Optimization: avoid throw overhead.
696 if (expired())
697 return __shared_ptr<element_type, _Lp>();
c8bd30dd 698
459f9f82
PC
699 try
700 {
701 return __shared_ptr<element_type, _Lp>(*this);
702 }
c8bd30dd 703 catch(const bad_weak_ptr&)
459f9f82
PC
704 {
705 // Q: How can we get here?
706 // A: Another thread may have invalidated r after the
707 // use_count test above.
e31fc6a5 708 return __shared_ptr<element_type, _Lp>();
459f9f82
PC
709 }
710
b758b22a 711#else
459f9f82
PC
712 // Optimization: avoid try/catch overhead when single threaded.
713 return expired() ? __shared_ptr<element_type, _Lp>()
714 : __shared_ptr<element_type, _Lp>(*this);
b758b22a
BK
715
716#endif
459f9f82 717 } // XXX MT
b758b22a 718
459f9f82
PC
719 long
720 use_count() const // never throws
c8bd30dd 721 { return _M_refcount._M_get_use_count(); }
b758b22a 722
b758b22a 723 bool
459f9f82 724 expired() const // never throws
c8bd30dd 725 { return _M_refcount._M_get_use_count() == 0; }
459f9f82
PC
726
727 void
728 reset() // never throws
729 { __weak_ptr().swap(*this); }
77633f4c 730
459f9f82
PC
731 void
732 swap(__weak_ptr& __s) // never throws
733 {
734 std::swap(_M_ptr, __s._M_ptr);
c8bd30dd 735 _M_refcount._M_swap(__s._M_refcount);
459f9f82 736 }
b758b22a 737
459f9f82 738 private:
459f9f82
PC
739 // Used by __enable_shared_from_this.
740 void
c8bd30dd 741 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
459f9f82
PC
742 {
743 _M_ptr = __ptr;
744 _M_refcount = __refcount;
745 }
b758b22a 746
c8bd30dd
PC
747 template<typename _Tp1>
748 bool
749 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
750 { return _M_refcount < __rhs._M_refcount; }
751
752 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
753 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
754 friend class __enable_shared_from_this<_Tp, _Lp>;
755 friend class enable_shared_from_this<_Tp>;
756
459f9f82
PC
757 // Friend injected into namespace and found by ADL.
758 template<typename _Tp1>
759 friend inline bool
760 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
761 { return __lhs._M_less(__rhs); }
c8bd30dd
PC
762
763 _Tp* _M_ptr; // Contained pointer.
764 __weak_count<_Lp> _M_refcount; // Reference counter.
459f9f82 765 };
b758b22a 766
459f9f82
PC
767 // 2.2.4.7 weak_ptr specialized algorithms.
768 template<typename _Tp, _Lock_policy _Lp>
c8bd30dd 769 inline void
459f9f82
PC
770 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
771 { __a.swap(__b); }
b758b22a 772
b758b22a 773
c8bd30dd 774 template<typename _Tp, _Lock_policy _Lp>
459f9f82 775 class __enable_shared_from_this
b758b22a 776 {
459f9f82
PC
777 protected:
778 __enable_shared_from_this() { }
779
780 __enable_shared_from_this(const __enable_shared_from_this&) { }
781
782 __enable_shared_from_this&
783 operator=(const __enable_shared_from_this&)
784 { return *this; }
b758b22a 785
459f9f82
PC
786 ~__enable_shared_from_this() { }
787
788 public:
789 __shared_ptr<_Tp, _Lp>
790 shared_from_this()
c8bd30dd
PC
791 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
792
459f9f82
PC
793 __shared_ptr<const _Tp, _Lp>
794 shared_from_this() const
c8bd30dd
PC
795 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
796
459f9f82
PC
797 private:
798 template<typename _Tp1>
799 void
c8bd30dd 800 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
459f9f82
PC
801 { _M_weak_this._M_assign(__p, __n); }
802
803 template<typename _Tp1>
804 friend void
c8bd30dd 805 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
459f9f82
PC
806 const __enable_shared_from_this* __pe,
807 const _Tp1* __px)
808 {
809 if (__pe != 0)
810 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
811 }
a25ce4db 812
c8bd30dd 813 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
459f9f82 814 };
a25ce4db 815
c8bd30dd 816
939759fc
BK
817 /// shared_ptr
818 // The actual shared_ptr, with forwarding constructors and
459f9f82
PC
819 // assignment operators.
820 template<typename _Tp>
c8bd30dd
PC
821 class shared_ptr
822 : public __shared_ptr<_Tp>
459f9f82
PC
823 {
824 public:
c8bd30dd
PC
825 shared_ptr()
826 : __shared_ptr<_Tp>() { }
827
459f9f82
PC
828 template<typename _Tp1>
829 explicit
830 shared_ptr(_Tp1* __p)
831 : __shared_ptr<_Tp>(__p) { }
c8bd30dd 832
459f9f82
PC
833 template<typename _Tp1, typename _Deleter>
834 shared_ptr(_Tp1* __p, _Deleter __d)
835 : __shared_ptr<_Tp>(__p, __d) { }
c8bd30dd 836
aaf0ca6f
JW
837#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
838 template<typename _Tp1, typename _Deleter, typename _Alloc>
839 shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
840 : __shared_ptr<_Tp>(__p, __d, __a) { }
841
842 // Aliasing constructor
843 template<typename _Tp1>
844 shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p)
845 : __shared_ptr<_Tp>(__r, __p) { }
846#endif
847
459f9f82 848 template<typename _Tp1>
c8bd30dd 849 shared_ptr(const shared_ptr<_Tp1>& __r)
459f9f82 850 : __shared_ptr<_Tp>(__r) { }
c8bd30dd 851
aaf0ca6f
JW
852#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
853 shared_ptr(shared_ptr&& __r)
854 : __shared_ptr<_Tp>(std::move(__r)) { }
855
856 template<typename _Tp1>
857 shared_ptr(shared_ptr<_Tp1>&& __r)
858 : __shared_ptr<_Tp>(std::move(__r)) { }
859#endif
860
459f9f82
PC
861 template<typename _Tp1>
862 explicit
c8bd30dd 863 shared_ptr(const weak_ptr<_Tp1>& __r)
459f9f82 864 : __shared_ptr<_Tp>(__r) { }
c8bd30dd 865
4dd9d9db 866#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
459f9f82
PC
867 template<typename _Tp1>
868 explicit
869 shared_ptr(std::auto_ptr<_Tp1>& __r)
870 : __shared_ptr<_Tp>(__r) { }
40abbf1f 871#endif
459f9f82 872
aaf0ca6f 873#ifdef _GLIBCXX_INCLUDE_AS_TR1
459f9f82 874 template<typename _Tp1>
c8bd30dd 875 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
459f9f82
PC
876 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
877
878 template<typename _Tp1>
c8bd30dd 879 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
459f9f82 880 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
c8bd30dd 881
459f9f82 882 template<typename _Tp1>
c8bd30dd 883 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
459f9f82 884 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
aaf0ca6f 885#endif
459f9f82 886
459f9f82
PC
887 template<typename _Tp1>
888 shared_ptr&
c8bd30dd 889 operator=(const shared_ptr<_Tp1>& __r) // never throws
459f9f82
PC
890 {
891 this->__shared_ptr<_Tp>::operator=(__r);
892 return *this;
893 }
a25ce4db 894
4dd9d9db 895#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
459f9f82
PC
896 template<typename _Tp1>
897 shared_ptr&
c8bd30dd 898 operator=(std::auto_ptr<_Tp1>& __r)
459f9f82
PC
899 {
900 this->__shared_ptr<_Tp>::operator=(__r);
901 return *this;
902 }
40abbf1f 903#endif
aaf0ca6f
JW
904
905#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
906 shared_ptr&
907 operator=(shared_ptr&& __r)
908 {
909 this->__shared_ptr<_Tp>::operator=(std::move(__r));
910 return *this;
911 }
912
913 template<class _Tp1>
914 shared_ptr&
915 operator=(shared_ptr<_Tp1>&& __r)
916 {
917 this->__shared_ptr<_Tp>::operator=(std::move(__r));
918 return *this;
919 }
920#endif
921
922#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
923 private:
924 // This constructor is non-standard, it is used by allocate_shared.
925 template<typename _Alloc, typename... _Args>
926 shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
927 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
928 { }
929
930 template<typename _Tp1, typename _Alloc, typename... _Args>
931 friend shared_ptr<_Tp1>
932 allocate_shared(_Alloc __a, _Args&&... __args);
933#endif
459f9f82 934 };
b758b22a 935
c8bd30dd 936 template<typename _Tp, typename _Tp1>
aaf0ca6f 937 inline shared_ptr<_Tp>
c8bd30dd 938 static_pointer_cast(const shared_ptr<_Tp1>& __r)
aaf0ca6f
JW
939 {
940#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
941 return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
942#else
943 return shared_ptr<_Tp>(__r, __static_cast_tag());
944#endif
945 }
c8bd30dd
PC
946
947 template<typename _Tp, typename _Tp1>
aaf0ca6f 948 inline shared_ptr<_Tp>
c8bd30dd 949 const_pointer_cast(const shared_ptr<_Tp1>& __r)
aaf0ca6f
JW
950 {
951#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
952 return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get()));
953#else
954 return shared_ptr<_Tp>(__r, __const_cast_tag());
955#endif
956 }
c8bd30dd
PC
957
958 template<typename _Tp, typename _Tp1>
aaf0ca6f 959 inline shared_ptr<_Tp>
c8bd30dd 960 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
aaf0ca6f
JW
961 {
962#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
963 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
964 return shared_ptr<_Tp>(__r, __p);
965 return shared_ptr<_Tp>();
966#else
967 return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
968#endif
969 }
c8bd30dd
PC
970
971
939759fc
BK
972 /// weak_ptr
973 // The actual weak_ptr, with forwarding constructors and
c8bd30dd
PC
974 // assignment operators.
975 template<typename _Tp>
976 class weak_ptr
977 : public __weak_ptr<_Tp>
978 {
979 public:
980 weak_ptr()
981 : __weak_ptr<_Tp>() { }
982
983 template<typename _Tp1>
984 weak_ptr(const weak_ptr<_Tp1>& __r)
985 : __weak_ptr<_Tp>(__r) { }
986
987 template<typename _Tp1>
988 weak_ptr(const shared_ptr<_Tp1>& __r)
989 : __weak_ptr<_Tp>(__r) { }
990
991 template<typename _Tp1>
992 weak_ptr&
993 operator=(const weak_ptr<_Tp1>& __r) // never throws
994 {
995 this->__weak_ptr<_Tp>::operator=(__r);
996 return *this;
997 }
998
999 template<typename _Tp1>
1000 weak_ptr&
1001 operator=(const shared_ptr<_Tp1>& __r) // never throws
1002 {
1003 this->__weak_ptr<_Tp>::operator=(__r);
1004 return *this;
1005 }
1006
1007 shared_ptr<_Tp>
1008 lock() const // never throws
1009 {
1010#ifdef __GTHREADS
1011 if (this->expired())
1012 return shared_ptr<_Tp>();
1013
1014 try
1015 {
1016 return shared_ptr<_Tp>(*this);
1017 }
1018 catch(const bad_weak_ptr&)
1019 {
1020 return shared_ptr<_Tp>();
1021 }
1022#else
1023 return this->expired() ? shared_ptr<_Tp>()
1024 : shared_ptr<_Tp>(*this);
1025#endif
1026 }
1027 };
1028
939759fc 1029 /// enable_shared_from_this
459f9f82 1030 template<typename _Tp>
c8bd30dd 1031 class enable_shared_from_this
459f9f82
PC
1032 {
1033 protected:
c8bd30dd 1034 enable_shared_from_this() { }
459f9f82 1035
c8bd30dd
PC
1036 enable_shared_from_this(const enable_shared_from_this&) { }
1037
1038 enable_shared_from_this&
1039 operator=(const enable_shared_from_this&)
1040 { return *this; }
1041
1042 ~enable_shared_from_this() { }
1043
1044 public:
1045 shared_ptr<_Tp>
1046 shared_from_this()
1047 { return shared_ptr<_Tp>(this->_M_weak_this); }
1048
1049 shared_ptr<const _Tp>
1050 shared_from_this() const
1051 { return shared_ptr<const _Tp>(this->_M_weak_this); }
1052
1053 private:
1054 template<typename _Tp1>
1055 void
1056 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1057 { _M_weak_this._M_assign(__p, __n); }
1058
1059 template<typename _Tp1>
1060 friend void
1061 __enable_shared_from_this_helper(const __shared_count<>& __pn,
1062 const enable_shared_from_this* __pe,
1063 const _Tp1* __px)
1064 {
1065 if (__pe != 0)
1066 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1067 }
1068
1069 mutable weak_ptr<_Tp> _M_weak_this;
459f9f82 1070 };
c8bd30dd 1071
aaf0ca6f
JW
1072#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
1073 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
1074 inline __shared_ptr<_Tp, _Lp>
1075 __allocate_shared(_Alloc __a, _Args&&... __args)
1076 {
1077 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
1078 std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
1079 }
1080
1081 template<typename _Tp, _Lock_policy _Lp, typename... _Args>
1082 inline __shared_ptr<_Tp, _Lp>
1083 __make_shared(_Args&&... __args)
1084 {
1085 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1086 return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1087 std::forward<_Args>(__args)...);
1088 }
1089
1090 /** @brief Create an object that is owned by a shared_ptr.
1091 * @param __a An allocator.
1092 * @param __args Arguments for the @a _Tp object's constructor.
1093 * @return A shared_ptr that owns the newly created object.
1094 * @throw An exception thrown from @a _Alloc::allocate or from the
1095 * constructor of @a _Tp.
1096 *
1097 * A copy of @a __a will be used to allocate memory for the shared_ptr
1098 * and the new object.
1099 */
1100 template<typename _Tp, typename _Alloc, typename... _Args>
1101 inline shared_ptr<_Tp>
1102 allocate_shared(_Alloc __a, _Args&&... __args)
1103 {
1104 return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a),
1105 std::forward<_Args>(__args)...);
1106 }
1107
1108 /** @brief Create an object that is owned by a shared_ptr.
1109 * @param __args Arguments for the @a _Tp object's constructor.
1110 * @return A shared_ptr that owns the newly created object.
1111 * @throw std::bad_alloc, or an exception thrown from the
1112 * constructor of @a _Tp.
1113 */
1114 template<typename _Tp, typename... _Args>
1115 inline shared_ptr<_Tp>
1116 make_shared(_Args&&... __args)
1117 {
1118 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1119 return allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
1120 std::forward<_Args>(__args)...);
1121 }
1122#endif
1123
e133ace8
PC
1124_GLIBCXX_END_NAMESPACE_TR1
1125}