Install gcc-4.4.0-tdm-1-core-2.tar.gz
[msysgit.git] / mingw / lib / gcc / mingw32 / 4.3.3 / include / c++ / tr1_impl / boost_shared_ptr.h
bloba3fd80e85512f5bacacc05b01bf9402fb05dd100
1 // <tr1_impl/boost_shared_ptr.h> -*- C++ -*-
3 // Copyright (C) 2007 Free Software Foundation, Inc.
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.
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.
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
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
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.
30 // shared_count.hpp
31 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
33 // shared_ptr.hpp
34 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
37 // weak_ptr.hpp
38 // Copyright (C) 2001, 2002, 2003 Peter Dimov
40 // enable_shared_from_this.hpp
41 // Copyright (C) 2002 Peter Dimov
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)
47 // GCC Note: based on version 1.32.0 of the Boost library.
49 /** @file tr1_impl/boost_shared_ptr.h
50 * This is an internal header file, included by other library headers.
51 * You should not attempt to use it directly.
55 namespace std
57 _GLIBCXX_BEGIN_NAMESPACE_TR1
59 template<_Lock_policy _Lp>
60 class __weak_count
62 public:
63 __weak_count()
64 : _M_pi(0) // nothrow
65 { }
67 __weak_count(const __shared_count<_Lp>& __r)
68 : _M_pi(__r._M_pi) // nothrow
70 if (_M_pi != 0)
71 _M_pi->_M_weak_add_ref();
74 __weak_count(const __weak_count<_Lp>& __r)
75 : _M_pi(__r._M_pi) // nothrow
77 if (_M_pi != 0)
78 _M_pi->_M_weak_add_ref();
81 ~__weak_count() // nothrow
83 if (_M_pi != 0)
84 _M_pi->_M_weak_release();
87 __weak_count<_Lp>&
88 operator=(const __shared_count<_Lp>& __r) // nothrow
90 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
91 if (__tmp != 0)
92 __tmp->_M_weak_add_ref();
93 if (_M_pi != 0)
94 _M_pi->_M_weak_release();
95 _M_pi = __tmp;
96 return *this;
99 __weak_count<_Lp>&
100 operator=(const __weak_count<_Lp>& __r) // nothrow
102 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
103 if (__tmp != 0)
104 __tmp->_M_weak_add_ref();
105 if (_M_pi != 0)
106 _M_pi->_M_weak_release();
107 _M_pi = __tmp;
108 return *this;
111 void
112 _M_swap(__weak_count<_Lp>& __r) // nothrow
114 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
115 __r._M_pi = _M_pi;
116 _M_pi = __tmp;
119 long
120 _M_get_use_count() const // nothrow
121 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
123 friend inline bool
124 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
125 { return __a._M_pi == __b._M_pi; }
127 friend inline bool
128 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
129 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
131 private:
132 friend class __shared_count<_Lp>;
134 _Sp_counted_base<_Lp>* _M_pi;
137 // now that __weak_count is defined we can define this constructor:
138 template<_Lock_policy _Lp>
139 inline
140 __shared_count<_Lp>::
141 __shared_count(const __weak_count<_Lp>& __r)
142 : _M_pi(__r._M_pi)
144 if (_M_pi != 0)
145 _M_pi->_M_add_ref_lock();
146 else
147 __throw_bad_weak_ptr();
150 // Forward declarations.
151 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
152 class __shared_ptr;
154 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
155 class __weak_ptr;
157 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
158 class __enable_shared_from_this;
160 template<typename _Tp>
161 class shared_ptr;
163 template<typename _Tp>
164 class weak_ptr;
166 template<typename _Tp>
167 class enable_shared_from_this;
169 // Support for enable_shared_from_this.
171 // Friend of __enable_shared_from_this.
172 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
173 void
174 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
175 const __enable_shared_from_this<_Tp1,
176 _Lp>*, const _Tp2*);
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*);
185 template<_Lock_policy _Lp>
186 inline void
187 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
191 #ifdef _GLIBCXX_INCLUDE_AS_TR1
192 struct __static_cast_tag { };
193 struct __const_cast_tag { };
194 struct __dynamic_cast_tag { };
195 #endif
198 * @class __shared_ptr
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.
204 template<typename _Tp, _Lock_policy _Lp>
205 class __shared_ptr
207 public:
208 typedef _Tp element_type;
210 /** @brief Construct an empty %__shared_ptr.
211 * @post use_count()==0 && get()==0
213 __shared_ptr()
214 : _M_ptr(0), _M_refcount() // never throws
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.
222 template<typename _Tp1>
223 explicit
224 __shared_ptr(_Tp1* __p)
225 : _M_ptr(__p), _M_refcount(__p)
227 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
228 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
229 __enable_shared_from_this_helper(_M_refcount, __p, __p);
233 // Requirements: _Deleter's copy constructor and destructor must
234 // not throw
236 // __shared_ptr will release __p by calling __d(__p)
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.
245 template<typename _Tp1, typename _Deleter>
246 __shared_ptr(_Tp1* __p, _Deleter __d)
247 : _M_ptr(__p), _M_refcount(__p, __d)
249 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
250 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
251 __enable_shared_from_this_helper(_M_refcount, __p, __p);
254 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
256 // Requirements: _Deleter's copy constructor and destructor must
257 // not throw _Alloc's copy constructor and destructor must not
258 // throw.
260 // __shared_ptr will release __p by calling __d(__p)
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.
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)
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);
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()
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.
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
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
298 #endif
300 // generated copy constructor, assignment, destructor are fine.
302 /** @brief If @a __r is empty, constructs an empty %__shared_ptr;
303 * otherwise construct a %__shared_ptr that shares ownership
304 * with @a __r.
305 * @param __r A %__shared_ptr.
306 * @post get() == __r.get() && use_count() == __r.use_count()
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*>) }
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.
318 __shared_ptr(__shared_ptr&& __r)
319 : _M_ptr(__r._M_ptr), _M_refcount() // never throws
321 _M_refcount._M_swap(__r._M_refcount);
322 __r._M_ptr = 0;
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.
329 template<typename _Tp1>
330 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
331 : _M_ptr(__r._M_ptr), _M_refcount() // never throws
333 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
334 _M_refcount._M_swap(__r._M_refcount);
335 __r._M_ptr = 0;
337 #endif
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(),
344 * in which case the constructor has no effect.
346 template<typename _Tp1>
347 explicit
348 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
349 : _M_refcount(__r._M_refcount) // may throw
351 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
352 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
353 // did not throw.
354 _M_ptr = __r._M_ptr;
358 * @post use_count() == 1 and __r.get() == 0
360 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
361 template<typename _Tp1>
362 explicit
363 __shared_ptr(std::auto_ptr<_Tp1>& __r)
364 : _M_ptr(__r.get()), _M_refcount()
366 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
367 // TODO requires _Tp1 is complete, delete __r.release() well-formed
368 _Tp1* __tmp = __r.get();
369 _M_refcount = __shared_count<_Lp>(__r);
370 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
372 #endif
374 #ifdef _GLIBCXX_INCLUDE_AS_TR1
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)
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)
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)
392 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
393 _M_refcount = __shared_count<_Lp>();
395 #endif
397 template<typename _Tp1>
398 __shared_ptr&
399 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
401 _M_ptr = __r._M_ptr;
402 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
403 return *this;
406 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
407 template<typename _Tp1>
408 __shared_ptr&
409 operator=(std::auto_ptr<_Tp1>& __r)
411 __shared_ptr(__r).swap(*this);
412 return *this;
414 #endif
416 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
417 __shared_ptr&
418 operator=(__shared_ptr&& __r)
420 __shared_ptr(std::move(__r)).swap(*this);
421 return *this;
424 template<class _Tp1>
425 __shared_ptr&
426 operator=(__shared_ptr<_Tp1, _Lp>&& __r)
428 __shared_ptr(std::move(__r)).swap(*this);
429 return *this;
431 #endif
433 void
434 reset() // never throws
435 { __shared_ptr().swap(*this); }
437 template<typename _Tp1>
438 void
439 reset(_Tp1* __p) // _Tp1 must be complete.
441 // Catch self-reset errors.
442 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
443 __shared_ptr(__p).swap(*this);
446 template<typename _Tp1, typename _Deleter>
447 void
448 reset(_Tp1* __p, _Deleter __d)
449 { __shared_ptr(__p, __d).swap(*this); }
451 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
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); }
457 // Allow class instantiation when _Tp is [cv-qual] void.
458 typename std::add_lvalue_reference<_Tp>::type
459 #else
460 // Allow class instantiation when _Tp is [cv-qual] void.
461 typename std::tr1::add_reference<_Tp>::type
462 #endif
463 operator*() const // never throws
465 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
466 return *_M_ptr;
469 _Tp*
470 operator->() const // never throws
472 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
473 return _M_ptr;
476 _Tp*
477 get() const // never throws
478 { return _M_ptr; }
480 // Implicit conversion to "bool"
481 private:
482 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
484 public:
485 operator __unspecified_bool_type() const // never throws
486 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
488 bool
489 unique() const // never throws
490 { return _M_refcount._M_unique(); }
492 long
493 use_count() const // never throws
494 { return _M_refcount._M_get_use_count(); }
496 void
497 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
499 std::swap(_M_ptr, __other._M_ptr);
500 _M_refcount._M_swap(__other._M_refcount);
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)
508 : _M_ptr()
509 , _M_refcount(__tag, (_Tp*)0, __a, std::forward<_Args>(__args)...)
511 // _M_ptr needs to point to the newly constructed object.
512 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
513 void * __p = _M_refcount._M_get_deleter(typeid(__tag));
514 _M_ptr = static_cast<_Tp*>(__p);
517 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
518 typename... _Args>
519 friend __shared_ptr<_Tp1, _Lp1>
520 __allocate_shared(_Alloc __a, _Args&&... __args);
521 #endif
523 private:
524 void*
525 _M_get_deleter(const std::type_info& __ti) const
526 { return _M_refcount._M_get_deleter(__ti); }
528 template<typename _Tp1, _Lock_policy _Lp1>
529 bool
530 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
531 { return _M_refcount < __rhs._M_refcount; }
533 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
534 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
536 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
537 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
539 // Friends injected into enclosing namespace and found by ADL:
540 template<typename _Tp1>
541 friend inline bool
542 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
543 { return __a.get() == __b.get(); }
545 template<typename _Tp1>
546 friend inline bool
547 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
548 { return __a.get() != __b.get(); }
550 template<typename _Tp1>
551 friend inline bool
552 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
553 { return __a._M_less(__b); }
555 _Tp* _M_ptr; // Contained pointer.
556 __shared_count<_Lp> _M_refcount; // Reference counter.
559 // 2.2.3.8 shared_ptr specialized algorithms.
560 template<typename _Tp, _Lock_policy _Lp>
561 inline void
562 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
563 { __a.swap(__b); }
565 // 2.2.3.9 shared_ptr casts
566 /** @warning The seemingly equivalent
567 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
568 * will eventually result in undefined behaviour,
569 * attempting to delete the same object twice.
571 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
572 inline __shared_ptr<_Tp, _Lp>
573 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
575 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
576 return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get()));
577 #else
578 return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag());
579 #endif
582 /** @warning The seemingly equivalent
583 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
584 * will eventually result in undefined behaviour,
585 * attempting to delete the same object twice.
587 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
588 inline __shared_ptr<_Tp, _Lp>
589 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
591 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
592 return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get()));
593 #else
594 return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag());
595 #endif
598 /** @warning The seemingly equivalent
599 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
600 * will eventually result in undefined behaviour,
601 * attempting to delete the same object twice.
603 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
604 inline __shared_ptr<_Tp, _Lp>
605 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
607 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
608 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
609 return __shared_ptr<_Tp, _Lp>(__r, __p);
610 return __shared_ptr<_Tp, _Lp>();
611 #else
612 return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag());
613 #endif
616 // 2.2.3.7 shared_ptr I/O
617 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
618 std::basic_ostream<_Ch, _Tr>&
619 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
620 const __shared_ptr<_Tp, _Lp>& __p)
622 __os << __p.get();
623 return __os;
626 // 2.2.3.10 shared_ptr get_deleter (experimental)
627 template<typename _Del, typename _Tp, _Lock_policy _Lp>
628 inline _Del*
629 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
630 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
633 template<typename _Tp, _Lock_policy _Lp>
634 class __weak_ptr
636 public:
637 typedef _Tp element_type;
639 __weak_ptr()
640 : _M_ptr(0), _M_refcount() // never throws
643 // Generated copy constructor, assignment, destructor are fine.
645 // The "obvious" converting constructor implementation:
647 // template<typename _Tp1>
648 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
649 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
650 // { }
652 // has a serious problem.
654 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
655 // conversion may require access to *__r._M_ptr (virtual inheritance).
657 // It is not possible to avoid spurious access violations since
658 // in multithreaded programs __r._M_ptr may be invalidated at any point.
659 template<typename _Tp1>
660 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
661 : _M_refcount(__r._M_refcount) // never throws
663 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
664 _M_ptr = __r.lock().get();
667 template<typename _Tp1>
668 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
669 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
670 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
672 template<typename _Tp1>
673 __weak_ptr&
674 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
676 _M_ptr = __r.lock().get();
677 _M_refcount = __r._M_refcount;
678 return *this;
681 template<typename _Tp1>
682 __weak_ptr&
683 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
685 _M_ptr = __r._M_ptr;
686 _M_refcount = __r._M_refcount;
687 return *this;
690 __shared_ptr<_Tp, _Lp>
691 lock() const // never throws
693 #ifdef __GTHREADS
694 // Optimization: avoid throw overhead.
695 if (expired())
696 return __shared_ptr<element_type, _Lp>();
700 return __shared_ptr<element_type, _Lp>(*this);
702 catch(const bad_weak_ptr&)
704 // Q: How can we get here?
705 // A: Another thread may have invalidated r after the
706 // use_count test above.
707 return __shared_ptr<element_type, _Lp>();
710 #else
711 // Optimization: avoid try/catch overhead when single threaded.
712 return expired() ? __shared_ptr<element_type, _Lp>()
713 : __shared_ptr<element_type, _Lp>(*this);
715 #endif
716 } // XXX MT
718 long
719 use_count() const // never throws
720 { return _M_refcount._M_get_use_count(); }
722 bool
723 expired() const // never throws
724 { return _M_refcount._M_get_use_count() == 0; }
726 void
727 reset() // never throws
728 { __weak_ptr().swap(*this); }
730 void
731 swap(__weak_ptr& __s) // never throws
733 std::swap(_M_ptr, __s._M_ptr);
734 _M_refcount._M_swap(__s._M_refcount);
737 private:
738 // Used by __enable_shared_from_this.
739 void
740 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
742 _M_ptr = __ptr;
743 _M_refcount = __refcount;
746 template<typename _Tp1>
747 bool
748 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
749 { return _M_refcount < __rhs._M_refcount; }
751 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
752 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
753 friend class __enable_shared_from_this<_Tp, _Lp>;
754 friend class enable_shared_from_this<_Tp>;
756 // Friend injected into namespace and found by ADL.
757 template<typename _Tp1>
758 friend inline bool
759 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
760 { return __lhs._M_less(__rhs); }
762 _Tp* _M_ptr; // Contained pointer.
763 __weak_count<_Lp> _M_refcount; // Reference counter.
766 // 2.2.4.7 weak_ptr specialized algorithms.
767 template<typename _Tp, _Lock_policy _Lp>
768 inline void
769 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
770 { __a.swap(__b); }
773 template<typename _Tp, _Lock_policy _Lp>
774 class __enable_shared_from_this
776 protected:
777 __enable_shared_from_this() { }
779 __enable_shared_from_this(const __enable_shared_from_this&) { }
781 __enable_shared_from_this&
782 operator=(const __enable_shared_from_this&)
783 { return *this; }
785 ~__enable_shared_from_this() { }
787 public:
788 __shared_ptr<_Tp, _Lp>
789 shared_from_this()
790 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
792 __shared_ptr<const _Tp, _Lp>
793 shared_from_this() const
794 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
796 private:
797 template<typename _Tp1>
798 void
799 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
800 { _M_weak_this._M_assign(__p, __n); }
802 template<typename _Tp1>
803 friend void
804 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
805 const __enable_shared_from_this* __pe,
806 const _Tp1* __px)
808 if (__pe != 0)
809 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
812 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
816 /// shared_ptr
817 // The actual shared_ptr, with forwarding constructors and
818 // assignment operators.
819 template<typename _Tp>
820 class shared_ptr
821 : public __shared_ptr<_Tp>
823 public:
824 shared_ptr()
825 : __shared_ptr<_Tp>() { }
827 template<typename _Tp1>
828 explicit
829 shared_ptr(_Tp1* __p)
830 : __shared_ptr<_Tp>(__p) { }
832 template<typename _Tp1, typename _Deleter>
833 shared_ptr(_Tp1* __p, _Deleter __d)
834 : __shared_ptr<_Tp>(__p, __d) { }
836 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
837 template<typename _Tp1, typename _Deleter, typename _Alloc>
838 shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
839 : __shared_ptr<_Tp>(__p, __d, __a) { }
841 // Aliasing constructor
842 template<typename _Tp1>
843 shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p)
844 : __shared_ptr<_Tp>(__r, __p) { }
845 #endif
847 template<typename _Tp1>
848 shared_ptr(const shared_ptr<_Tp1>& __r)
849 : __shared_ptr<_Tp>(__r) { }
851 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
852 shared_ptr(shared_ptr&& __r)
853 : __shared_ptr<_Tp>(std::move(__r)) { }
855 template<typename _Tp1>
856 shared_ptr(shared_ptr<_Tp1>&& __r)
857 : __shared_ptr<_Tp>(std::move(__r)) { }
858 #endif
860 template<typename _Tp1>
861 explicit
862 shared_ptr(const weak_ptr<_Tp1>& __r)
863 : __shared_ptr<_Tp>(__r) { }
865 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
866 template<typename _Tp1>
867 explicit
868 shared_ptr(std::auto_ptr<_Tp1>& __r)
869 : __shared_ptr<_Tp>(__r) { }
870 #endif
872 #ifdef _GLIBCXX_INCLUDE_AS_TR1
873 template<typename _Tp1>
874 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
875 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
877 template<typename _Tp1>
878 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
879 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
881 template<typename _Tp1>
882 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
883 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
884 #endif
886 template<typename _Tp1>
887 shared_ptr&
888 operator=(const shared_ptr<_Tp1>& __r) // never throws
890 this->__shared_ptr<_Tp>::operator=(__r);
891 return *this;
894 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
895 template<typename _Tp1>
896 shared_ptr&
897 operator=(std::auto_ptr<_Tp1>& __r)
899 this->__shared_ptr<_Tp>::operator=(__r);
900 return *this;
902 #endif
904 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
905 shared_ptr&
906 operator=(shared_ptr&& __r)
908 this->__shared_ptr<_Tp>::operator=(std::move(__r));
909 return *this;
912 template<class _Tp1>
913 shared_ptr&
914 operator=(shared_ptr<_Tp1>&& __r)
916 this->__shared_ptr<_Tp>::operator=(std::move(__r));
917 return *this;
919 #endif
921 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
922 private:
923 // This constructor is non-standard, it is used by allocate_shared.
924 template<typename _Alloc, typename... _Args>
925 shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
926 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
929 template<typename _Tp1, typename _Alloc, typename... _Args>
930 friend shared_ptr<_Tp1>
931 allocate_shared(_Alloc __a, _Args&&... __args);
932 #endif
935 template<typename _Tp, typename _Tp1>
936 inline shared_ptr<_Tp>
937 static_pointer_cast(const shared_ptr<_Tp1>& __r)
939 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
940 return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
941 #else
942 return shared_ptr<_Tp>(__r, __static_cast_tag());
943 #endif
946 template<typename _Tp, typename _Tp1>
947 inline shared_ptr<_Tp>
948 const_pointer_cast(const shared_ptr<_Tp1>& __r)
950 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
951 return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get()));
952 #else
953 return shared_ptr<_Tp>(__r, __const_cast_tag());
954 #endif
957 template<typename _Tp, typename _Tp1>
958 inline shared_ptr<_Tp>
959 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
961 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
962 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
963 return shared_ptr<_Tp>(__r, __p);
964 return shared_ptr<_Tp>();
965 #else
966 return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
967 #endif
971 /// weak_ptr
972 // The actual weak_ptr, with forwarding constructors and
973 // assignment operators.
974 template<typename _Tp>
975 class weak_ptr
976 : public __weak_ptr<_Tp>
978 public:
979 weak_ptr()
980 : __weak_ptr<_Tp>() { }
982 template<typename _Tp1>
983 weak_ptr(const weak_ptr<_Tp1>& __r)
984 : __weak_ptr<_Tp>(__r) { }
986 template<typename _Tp1>
987 weak_ptr(const shared_ptr<_Tp1>& __r)
988 : __weak_ptr<_Tp>(__r) { }
990 template<typename _Tp1>
991 weak_ptr&
992 operator=(const weak_ptr<_Tp1>& __r) // never throws
994 this->__weak_ptr<_Tp>::operator=(__r);
995 return *this;
998 template<typename _Tp1>
999 weak_ptr&
1000 operator=(const shared_ptr<_Tp1>& __r) // never throws
1002 this->__weak_ptr<_Tp>::operator=(__r);
1003 return *this;
1006 shared_ptr<_Tp>
1007 lock() const // never throws
1009 #ifdef __GTHREADS
1010 if (this->expired())
1011 return shared_ptr<_Tp>();
1015 return shared_ptr<_Tp>(*this);
1017 catch(const bad_weak_ptr&)
1019 return shared_ptr<_Tp>();
1021 #else
1022 return this->expired() ? shared_ptr<_Tp>()
1023 : shared_ptr<_Tp>(*this);
1024 #endif
1028 /// enable_shared_from_this
1029 template<typename _Tp>
1030 class enable_shared_from_this
1032 protected:
1033 enable_shared_from_this() { }
1035 enable_shared_from_this(const enable_shared_from_this&) { }
1037 enable_shared_from_this&
1038 operator=(const enable_shared_from_this&)
1039 { return *this; }
1041 ~enable_shared_from_this() { }
1043 public:
1044 shared_ptr<_Tp>
1045 shared_from_this()
1046 { return shared_ptr<_Tp>(this->_M_weak_this); }
1048 shared_ptr<const _Tp>
1049 shared_from_this() const
1050 { return shared_ptr<const _Tp>(this->_M_weak_this); }
1052 private:
1053 template<typename _Tp1>
1054 void
1055 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1056 { _M_weak_this._M_assign(__p, __n); }
1058 template<typename _Tp1>
1059 friend void
1060 __enable_shared_from_this_helper(const __shared_count<>& __pn,
1061 const enable_shared_from_this* __pe,
1062 const _Tp1* __px)
1064 if (__pe != 0)
1065 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1068 mutable weak_ptr<_Tp> _M_weak_this;
1071 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
1072 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
1073 inline __shared_ptr<_Tp, _Lp>
1074 __allocate_shared(_Alloc __a, _Args&&... __args)
1076 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
1077 std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
1080 template<typename _Tp, _Lock_policy _Lp, typename... _Args>
1081 inline __shared_ptr<_Tp, _Lp>
1082 __make_shared(_Args&&... __args)
1084 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1085 return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1086 std::forward<_Args>(__args)...);
1089 /** @brief Create an object that is owned by a shared_ptr.
1090 * @param __a An allocator.
1091 * @param __args Arguments for the @a _Tp object's constructor.
1092 * @return A shared_ptr that owns the newly created object.
1093 * @throw An exception thrown from @a _Alloc::allocate or from the
1094 * constructor of @a _Tp.
1096 * A copy of @a __a will be used to allocate memory for the shared_ptr
1097 * and the new object.
1099 template<typename _Tp, typename _Alloc, typename... _Args>
1100 inline shared_ptr<_Tp>
1101 allocate_shared(_Alloc __a, _Args&&... __args)
1103 return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a),
1104 std::forward<_Args>(__args)...);
1107 /** @brief Create an object that is owned by a shared_ptr.
1108 * @param __args Arguments for the @a _Tp object's constructor.
1109 * @return A shared_ptr that owns the newly created object.
1110 * @throw std::bad_alloc, or an exception thrown from the
1111 * constructor of @a _Tp.
1113 template<typename _Tp, typename... _Args>
1114 inline shared_ptr<_Tp>
1115 make_shared(_Args&&... __args)
1117 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1118 return allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
1119 std::forward<_Args>(__args)...);
1121 #endif
1123 _GLIBCXX_END_NAMESPACE_TR1