STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Namespaces | Classes | Typedefs | Functions
Exceptions

Namespaces

 std::__exception_ptr
 

Classes

class  std::__exception_ptr::exception_ptr
 An opaque pointer to an arbitrary exception. More...
 
class  std::exception
 STL class.
 
class  std::bad_exception
 STL class.
 
class  std::bad_alloc
 STL class.
 
class  std::bad_cast
 STL class.
 
class  std::bad_typeid
 STL class.
 

Typedefs

typedef void(* std::terminate_handler )()
 If you write a replacement terminate handler, it must be of this type. More...
 
typedef void(* std::unexpected_handler )()
 If you write a replacement unexpected handler, it must be of this type. More...
 

Functions

exception_ptr std::current_exception () _GLIBCXX_USE_NOEXCEPT
 
void std::rethrow_exception (exception_ptr) __attribute__((__noreturn__))
 Throw the object pointed to by the exception_ptr. More...
 
template<typename _Ex >
exception_ptr std::copy_exception (_Ex __ex) _GLIBCXX_USE_NOEXCEPT
 Obtain an exception_ptr pointing to a copy of the supplied object. More...
 
template<typename _Ex >
exception_ptr std::make_exception_ptr (_Ex __ex) _GLIBCXX_USE_NOEXCEPT
 Obtain an exception_ptr pointing to a copy of the supplied object. More...
 
namespace std _GLIBCXX_VISIBILITY (default)
 
terminate_handler std::set_terminate (terminate_handler) _GLIBCXX_USE_NOEXCEPT
 Takes a new handler function as an argument, returns the old function. More...
 
void std::terminate () _GLIBCXX_USE_NOEXCEPT __attribute__((__noreturn__))
 
unexpected_handler std::set_unexpected (unexpected_handler) _GLIBCXX_USE_NOEXCEPT
 Takes a new handler function as an argument, returns the old function. More...
 
void std::unexpected () __attribute__((__noreturn__))
 
bool std::uncaught_exception () _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
 
_GLIBCXX_BEGIN_NAMESPACE_VERSION
void 
__gnu_cxx::__verbose_terminate_handler ()
 A replacement for the standard terminate_handler which prints more information about the terminating exception (if any) on stderr. More...
 

Detailed Description

Classes and functions for reporting errors via exception classes.

Typedef Documentation

typedef void(* std::terminate_handler)()

If you write a replacement terminate handler, it must be of this type.

typedef void(* std::unexpected_handler)()

If you write a replacement unexpected handler, it must be of this type.

Function Documentation

_GLIBCXX_BEGIN_NAMESPACE_VERSION void __gnu_cxx::__verbose_terminate_handler ( )

A replacement for the standard terminate_handler which prints more information about the terminating exception (if any) on stderr.

Call

to use. For more info, see http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html

In 3.4 and later, this is on by default.

namespace std _GLIBCXX_VISIBILITY ( default  )

Exception possibly thrown by shared_ptr.

static_pointer_cast

const_pointer_cast

dynamic_pointer_cast

std::hash specialization for __shared_ptr.

Thown by exception safety machinery.

Base class for checking address and label information about allocations. Create a std::map between the allocated address (void*) and a datum for annotations, which are a pair of numbers corresponding to label and allocated size.

Base struct for condition policy.

Requires a public member function with the signature void throw_conditionally()

Base class for incremental control and throw.

Never enter the condition.

Always enter the condition.

Enter the nth condition.

Base class for random probability control and throw.

Group condition.

Never enter the condition.

Always enter the condition.

Class with exception generation control. Intended to be used as a value_type in templatized code.

Note: Destructor not allowed to throw.

Type throwing via limit condition.

Type throwing via random condition.

Allocator class with logging and exception generation control. Intended to be used as an allocator_type in templatized code.

Note: Deallocate not allowed to throw.

Allocator throwing via limit condition.

Allocator throwing via random condition.

Exception possibly thrown by shared_ptr.

53 {
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 
56 #if _GLIBCXX_USE_DEPRECATED
57  template<typename> class auto_ptr;
58 #endif
59 
64  class bad_weak_ptr : public std::exception
65  {
66  public:
67  virtual char const*
68  what() const noexcept;
69 
70  virtual ~bad_weak_ptr() noexcept;
71  };
72 
73  // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
74  inline void
75  __throw_bad_weak_ptr()
76  { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
77 
78  using __gnu_cxx::_Lock_policy;
79  using __gnu_cxx::__default_lock_policy;
80  using __gnu_cxx::_S_single;
81  using __gnu_cxx::_S_mutex;
82  using __gnu_cxx::_S_atomic;
83 
84  // Empty helper class except when the template argument is _S_mutex.
85  template<_Lock_policy _Lp>
86  class _Mutex_base
87  {
88  protected:
89  // The atomic policy uses fully-fenced builtins, single doesn't care.
90  enum { _S_need_barriers = 0 };
91  };
92 
93  template<>
94  class _Mutex_base<_S_mutex>
95  : public __gnu_cxx::__mutex
96  {
97  protected:
98  // This policy is used when atomic builtins are not available.
99  // The replacement atomic operations might not have the necessary
100  // memory barriers.
101  enum { _S_need_barriers = 1 };
102  };
103 
104  template<_Lock_policy _Lp = __default_lock_policy>
105  class _Sp_counted_base
106  : public _Mutex_base<_Lp>
107  {
108  public:
109  _Sp_counted_base() noexcept
110  : _M_use_count(1), _M_weak_count(1) { }
111 
112  virtual
113  ~_Sp_counted_base() noexcept
114  { }
115 
116  // Called when _M_use_count drops to zero, to release the resources
117  // managed by *this.
118  virtual void
119  _M_dispose() noexcept = 0;
120 
121  // Called when _M_weak_count drops to zero.
122  virtual void
123  _M_destroy() noexcept
124  { delete this; }
125 
126  virtual void*
127  _M_get_deleter(const std::type_info&) = 0;
128 
129  void
130  _M_add_ref_copy()
131  { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
132 
133  void
134  _M_add_ref_lock();
135 
136  void
137  _M_release() noexcept
138  {
139  // Be race-detector-friendly. For more info see bits/c++config.
140  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
141  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
142  {
143  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
144  _M_dispose();
145  // There must be a memory barrier between dispose() and destroy()
146  // to ensure that the effects of dispose() are observed in the
147  // thread that runs destroy().
148  // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
149  if (_Mutex_base<_Lp>::_S_need_barriers)
150  {
153  }
154 
155  // Be race-detector-friendly. For more info see bits/c++config.
156  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
157  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
158  -1) == 1)
159  {
160  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
161  _M_destroy();
162  }
163  }
164  }
165 
166  void
167  _M_weak_add_ref() noexcept
168  { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
169 
170  void
171  _M_weak_release() noexcept
172  {
173  // Be race-detector-friendly. For more info see bits/c++config.
174  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
175  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
176  {
177  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
178  if (_Mutex_base<_Lp>::_S_need_barriers)
179  {
180  // See _M_release(),
181  // destroy() must observe results of dispose()
184  }
185  _M_destroy();
186  }
187  }
188 
189  long
190  _M_get_use_count() const noexcept
191  {
192  // No memory barrier is used here so there is no synchronization
193  // with other threads.
194  return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
195  }
196 
197  private:
198  _Sp_counted_base(_Sp_counted_base const&) = delete;
199  _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
200 
201  _Atomic_word _M_use_count; // #shared
202  _Atomic_word _M_weak_count; // #weak + (#shared != 0)
203  };
204 
205  template<>
206  inline void
207  _Sp_counted_base<_S_single>::
208  _M_add_ref_lock()
209  {
210  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
211  {
212  _M_use_count = 0;
213  __throw_bad_weak_ptr();
214  }
215  }
216 
217  template<>
218  inline void
219  _Sp_counted_base<_S_mutex>::
220  _M_add_ref_lock()
221  {
222  __gnu_cxx::__scoped_lock sentry(*this);
223  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
224  {
225  _M_use_count = 0;
226  __throw_bad_weak_ptr();
227  }
228  }
229 
230  template<>
231  inline void
232  _Sp_counted_base<_S_atomic>::
233  _M_add_ref_lock()
234  {
235  // Perform lock-free add-if-not-zero operation.
236  _Atomic_word __count = _M_get_use_count();
237  do
238  {
239  if (__count == 0)
240  __throw_bad_weak_ptr();
241  // Replace the current counter value with the old value + 1, as
242  // long as it's not changed meanwhile.
243  }
244  while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
245  true, __ATOMIC_ACQ_REL,
246  __ATOMIC_RELAXED));
247  }
248 
249 
250  // Forward declarations.
251  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
252  class __shared_ptr;
253 
254  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
255  class __weak_ptr;
256 
257  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
258  class __enable_shared_from_this;
259 
260  template<typename _Tp>
261  class shared_ptr;
262 
263  template<typename _Tp>
264  class weak_ptr;
265 
266  template<typename _Tp>
267  struct owner_less;
268 
269  template<typename _Tp>
270  class enable_shared_from_this;
271 
272  template<_Lock_policy _Lp = __default_lock_policy>
273  class __weak_count;
274 
275  template<_Lock_policy _Lp = __default_lock_policy>
276  class __shared_count;
277 
278 
279  // Counted ptr with no deleter or allocator support
280  template<typename _Ptr, _Lock_policy _Lp>
281  class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
282  {
283  public:
284  explicit
285  _Sp_counted_ptr(_Ptr __p)
286  : _M_ptr(__p) { }
287 
288  virtual void
289  _M_dispose() noexcept
290  { delete _M_ptr; }
291 
292  virtual void
293  _M_destroy() noexcept
294  { delete this; }
295 
296  virtual void*
297  _M_get_deleter(const std::type_info&)
298  { return 0; }
299 
300  _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
301  _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
302 
303  protected:
304  _Ptr _M_ptr; // copy constructor must not throw
305  };
306 
307  template<>
308  inline void
309  _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
310 
311  template<>
312  inline void
313  _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
314 
315  template<>
316  inline void
317  _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
318 
319  // Support for custom deleter and/or allocator
320  template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
321  class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
322  {
323  // Helper class that stores the Deleter and also acts as an allocator.
324  // Used to dispose of the owned pointer and the internal refcount
325  // Requires that copies of _Alloc can free each other's memory.
326  struct _My_Deleter
327  : public _Alloc // copy constructor must not throw
328  {
329  _Deleter _M_del; // copy constructor must not throw
330  _My_Deleter(_Deleter __d, const _Alloc& __a)
331  : _Alloc(__a), _M_del(__d) { }
332  };
333 
334  public:
335  // __d(__p) must not throw.
336  _Sp_counted_deleter(_Ptr __p, _Deleter __d)
337  : _M_ptr(__p), _M_del(__d, _Alloc()) { }
338 
339  // __d(__p) must not throw.
340  _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
341  : _M_ptr(__p), _M_del(__d, __a) { }
342 
343  ~_Sp_counted_deleter() noexcept { }
344 
345  virtual void
346  _M_dispose() noexcept
347  { _M_del._M_del(_M_ptr); }
348 
349  virtual void
350  _M_destroy() noexcept
351  {
352  typedef typename allocator_traits<_Alloc>::template
353  rebind_traits<_Sp_counted_deleter> _Alloc_traits;
354  typename _Alloc_traits::allocator_type __a(_M_del);
355  _Alloc_traits::destroy(__a, this);
356  _Alloc_traits::deallocate(__a, this, 1);
357  }
358 
359  virtual void*
360  _M_get_deleter(const std::type_info& __ti)
361  {
362 #ifdef __GXX_RTTI
363  return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
364 #else
365  return 0;
366 #endif
367  }
368 
369  protected:
370  _Ptr _M_ptr; // copy constructor must not throw
371  _My_Deleter _M_del; // copy constructor must not throw
372  };
373 
374  // helpers for make_shared / allocate_shared
375 
376  struct _Sp_make_shared_tag { };
377 
378  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
379  class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
380  {
381  // Helper class that stores the pointer and also acts as an allocator.
382  // Used to dispose of the owned pointer and the internal refcount
383  // Requires that copies of _Alloc can free each other's memory.
384  struct _Impl
385  : public _Alloc // copy constructor must not throw
386  {
387  _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { }
388  _Tp* _M_ptr;
389  };
390 
391  public:
392  template<typename... _Args>
393  _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
394  : _M_impl(__a)
395  {
396  _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage));
397  // _GLIBCXX_RESOLVE_LIB_DEFECTS
398  // 2070. allocate_shared should use allocator_traits<A>::construct
399  allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr,
400  std::forward<_Args>(__args)...); // might throw
401  }
402 
403  ~_Sp_counted_ptr_inplace() noexcept { }
404 
405  virtual void
406  _M_dispose() noexcept
407  { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); }
408 
409  // Override because the allocator needs to know the dynamic type
410  virtual void
411  _M_destroy() noexcept
412  {
413  typedef typename allocator_traits<_Alloc>::template
414  rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits;
415  typename _Alloc_traits::allocator_type __a(_M_impl);
416  _Alloc_traits::destroy(__a, this);
417  _Alloc_traits::deallocate(__a, this, 1);
418  }
419 
420  // Sneaky trick so __shared_ptr can get the managed pointer
421  virtual void*
422  _M_get_deleter(const std::type_info& __ti) noexcept
423  {
424 #ifdef __GXX_RTTI
425  return __ti == typeid(_Sp_make_shared_tag)
426  ? static_cast<void*>(&_M_storage)
427  : 0;
428 #else
429  return 0;
430 #endif
431  }
432 
433  private:
434  _Impl _M_impl;
435  typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
436  _M_storage;
437  };
438 
439  template<_Lock_policy _Lp>
440  class __shared_count
441  {
442  public:
443  constexpr __shared_count() noexcept : _M_pi(0)
444  { }
445 
446  template<typename _Ptr>
447  explicit
448  __shared_count(_Ptr __p) : _M_pi(0)
449  {
450  __try
451  {
452  _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
453  }
454  __catch(...)
455  {
456  delete __p;
458  }
459  }
460 
461  template<typename _Ptr, typename _Deleter>
462  __shared_count(_Ptr __p, _Deleter __d)
463  : __shared_count(__p, std::move(__d), allocator<int>())
464  { }
465 
466  template<typename _Ptr, typename _Deleter, typename _Alloc>
467  __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
468  {
469  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
470  typedef typename allocator_traits<_Alloc>::template
471  rebind_traits<_Sp_cd_type> _Alloc_traits;
472  typename _Alloc_traits::allocator_type __a2(__a);
473  _Sp_cd_type* __mem = 0;
474  __try
475  {
476  __mem = _Alloc_traits::allocate(__a2, 1);
477  _Alloc_traits::construct(__a2, __mem,
478  __p, std::move(__d), std::move(__a));
479  _M_pi = __mem;
480  }
481  __catch(...)
482  {
483  __d(__p); // Call _Deleter on __p.
484  if (__mem)
485  _Alloc_traits::deallocate(__a2, __mem, 1);
487  }
488  }
489 
490  template<typename _Tp, typename _Alloc, typename... _Args>
491  __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
492  _Args&&... __args)
493  : _M_pi(0)
494  {
495  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
496  typedef typename allocator_traits<_Alloc>::template
497  rebind_traits<_Sp_cp_type> _Alloc_traits;
498  typename _Alloc_traits::allocator_type __a2(__a);
499  _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1);
500  __try
501  {
502  _Alloc_traits::construct(__a2, __mem, std::move(__a),
503  std::forward<_Args>(__args)...);
504  _M_pi = __mem;
505  }
506  __catch(...)
507  {
508  _Alloc_traits::deallocate(__a2, __mem, 1);
510  }
511  }
512 
513 #if _GLIBCXX_USE_DEPRECATED
514  // Special case for auto_ptr<_Tp> to provide the strong guarantee.
515  template<typename _Tp>
516  explicit
517  __shared_count(std::auto_ptr<_Tp>&& __r);
518 #endif
519 
520  // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
521  template<typename _Tp, typename _Del>
522  explicit
523  __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
524  {
525  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
526  using _Del2 = typename conditional<is_reference<_Del>::value,
527  reference_wrapper<typename remove_reference<_Del>::type>,
528  _Del>::type;
529  using _Sp_cd_type
530  = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
531  using _Alloc = allocator<_Sp_cd_type>;
532  using _Alloc_traits = allocator_traits<_Alloc>;
533  _Alloc __a;
534  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
535  _Alloc_traits::construct(__a, __mem, __r.release(),
536  __r.get_deleter()); // non-throwing
537  _M_pi = __mem;
538  }
539 
540  // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
541  explicit __shared_count(const __weak_count<_Lp>& __r);
542 
543  ~__shared_count() noexcept
544  {
545  if (_M_pi != nullptr)
546  _M_pi->_M_release();
547  }
548 
549  __shared_count(const __shared_count& __r) noexcept
550  : _M_pi(__r._M_pi)
551  {
552  if (_M_pi != 0)
553  _M_pi->_M_add_ref_copy();
554  }
555 
556  __shared_count&
557  operator=(const __shared_count& __r) noexcept
558  {
559  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
560  if (__tmp != _M_pi)
561  {
562  if (__tmp != 0)
563  __tmp->_M_add_ref_copy();
564  if (_M_pi != 0)
565  _M_pi->_M_release();
566  _M_pi = __tmp;
567  }
568  return *this;
569  }
570 
571  void
572  _M_swap(__shared_count& __r) noexcept
573  {
574  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
575  __r._M_pi = _M_pi;
576  _M_pi = __tmp;
577  }
578 
579  long
580  _M_get_use_count() const noexcept
581  { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
582 
583  bool
584  _M_unique() const noexcept
585  { return this->_M_get_use_count() == 1; }
586 
587  void*
588  _M_get_deleter(const std::type_info& __ti) const noexcept
589  { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
590 
591  bool
592  _M_less(const __shared_count& __rhs) const noexcept
593  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
594 
595  bool
596  _M_less(const __weak_count<_Lp>& __rhs) const noexcept
597  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
598 
599  // Friend function injected into enclosing namespace and found by ADL
600  friend inline bool
601  operator==(const __shared_count& __a, const __shared_count& __b) noexcept
602  { return __a._M_pi == __b._M_pi; }
603 
604  private:
605  friend class __weak_count<_Lp>;
606 
607  _Sp_counted_base<_Lp>* _M_pi;
608  };
609 
610 
611  template<_Lock_policy _Lp>
612  class __weak_count
613  {
614  public:
615  constexpr __weak_count() noexcept : _M_pi(0)
616  { }
617 
618  __weak_count(const __shared_count<_Lp>& __r) noexcept
619  : _M_pi(__r._M_pi)
620  {
621  if (_M_pi != 0)
622  _M_pi->_M_weak_add_ref();
623  }
624 
625  __weak_count(const __weak_count<_Lp>& __r) noexcept
626  : _M_pi(__r._M_pi)
627  {
628  if (_M_pi != 0)
629  _M_pi->_M_weak_add_ref();
630  }
631 
632  ~__weak_count() noexcept
633  {
634  if (_M_pi != 0)
635  _M_pi->_M_weak_release();
636  }
637 
638  __weak_count<_Lp>&
639  operator=(const __shared_count<_Lp>& __r) noexcept
640  {
641  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
642  if (__tmp != 0)
643  __tmp->_M_weak_add_ref();
644  if (_M_pi != 0)
645  _M_pi->_M_weak_release();
646  _M_pi = __tmp;
647  return *this;
648  }
649 
650  __weak_count<_Lp>&
651  operator=(const __weak_count<_Lp>& __r) noexcept
652  {
653  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
654  if (__tmp != 0)
655  __tmp->_M_weak_add_ref();
656  if (_M_pi != 0)
657  _M_pi->_M_weak_release();
658  _M_pi = __tmp;
659  return *this;
660  }
661 
662  void
663  _M_swap(__weak_count<_Lp>& __r) noexcept
664  {
665  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
666  __r._M_pi = _M_pi;
667  _M_pi = __tmp;
668  }
669 
670  long
671  _M_get_use_count() const noexcept
672  { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
673 
674  bool
675  _M_less(const __weak_count& __rhs) const noexcept
676  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
677 
678  bool
679  _M_less(const __shared_count<_Lp>& __rhs) const noexcept
680  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
681 
682  // Friend function injected into enclosing namespace and found by ADL
683  friend inline bool
684  operator==(const __weak_count& __a, const __weak_count& __b) noexcept
685  { return __a._M_pi == __b._M_pi; }
686 
687  private:
688  friend class __shared_count<_Lp>;
689 
690  _Sp_counted_base<_Lp>* _M_pi;
691  };
692 
693  // Now that __weak_count is defined we can define this constructor:
694  template<_Lock_policy _Lp>
695  inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r)
696  : _M_pi(__r._M_pi)
697  {
698  if (_M_pi != 0)
699  _M_pi->_M_add_ref_lock();
700  else
701  __throw_bad_weak_ptr();
702  }
703 
704 
705  // Support for enable_shared_from_this.
706 
707  // Friend of __enable_shared_from_this.
708  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
709  void
710  __enable_shared_from_this_helper(const __shared_count<_Lp>&,
711  const __enable_shared_from_this<_Tp1,
712  _Lp>*, const _Tp2*) noexcept;
713 
714  // Friend of enable_shared_from_this.
715  template<typename _Tp1, typename _Tp2>
716  void
717  __enable_shared_from_this_helper(const __shared_count<>&,
718  const enable_shared_from_this<_Tp1>*,
719  const _Tp2*) noexcept;
720 
721  template<_Lock_policy _Lp>
722  inline void
723  __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
724  { }
725 
726 
727  template<typename _Tp, _Lock_policy _Lp>
728  class __shared_ptr
729  {
730  public:
731  typedef _Tp element_type;
732 
733  constexpr __shared_ptr() noexcept
734  : _M_ptr(0), _M_refcount()
735  { }
736 
737  template<typename _Tp1>
738  explicit __shared_ptr(_Tp1* __p)
739  : _M_ptr(__p), _M_refcount(__p)
740  {
741  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
742  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
743  __enable_shared_from_this_helper(_M_refcount, __p, __p);
744  }
745 
746  template<typename _Tp1, typename _Deleter>
747  __shared_ptr(_Tp1* __p, _Deleter __d)
748  : _M_ptr(__p), _M_refcount(__p, __d)
749  {
750  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
751  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
752  __enable_shared_from_this_helper(_M_refcount, __p, __p);
753  }
754 
755  template<typename _Tp1, typename _Deleter, typename _Alloc>
756  __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
757  : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
758  {
759  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
760  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
761  __enable_shared_from_this_helper(_M_refcount, __p, __p);
762  }
763 
764  template<typename _Deleter>
765  __shared_ptr(nullptr_t __p, _Deleter __d)
766  : _M_ptr(0), _M_refcount(__p, __d)
767  { }
768 
769  template<typename _Deleter, typename _Alloc>
770  __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
771  : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
772  { }
773 
774  template<typename _Tp1>
775  __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
776  : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
777  { }
778 
779  __shared_ptr(const __shared_ptr&) noexcept = default;
780  __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
781  ~__shared_ptr() = default;
782 
783  template<typename _Tp1, typename = typename
784  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
785  __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
786  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
787  { }
788 
789  __shared_ptr(__shared_ptr&& __r) noexcept
790  : _M_ptr(__r._M_ptr), _M_refcount()
791  {
792  _M_refcount._M_swap(__r._M_refcount);
793  __r._M_ptr = 0;
794  }
795 
796  template<typename _Tp1, typename = typename
797  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
798  __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
799  : _M_ptr(__r._M_ptr), _M_refcount()
800  {
801  _M_refcount._M_swap(__r._M_refcount);
802  __r._M_ptr = 0;
803  }
804 
805  template<typename _Tp1>
806  explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
807  : _M_refcount(__r._M_refcount) // may throw
808  {
809  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
810 
811  // It is now safe to copy __r._M_ptr, as
812  // _M_refcount(__r._M_refcount) did not throw.
813  _M_ptr = __r._M_ptr;
814  }
815 
816  // If an exception is thrown this constructor has no effect.
817  template<typename _Tp1, typename _Del>
818  __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
819  : _M_ptr(__r.get()), _M_refcount()
820  {
821  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
822  auto __tmp = __r.get();
823  _M_refcount = __shared_count<_Lp>(std::move(__r));
824  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
825  }
826 
827 #if _GLIBCXX_USE_DEPRECATED
828  // Postcondition: use_count() == 1 and __r.get() == 0
829  template<typename _Tp1>
830  __shared_ptr(std::auto_ptr<_Tp1>&& __r);
831 #endif
832 
833  /* TODO: use delegating constructor */
834  constexpr __shared_ptr(nullptr_t) noexcept
835  : _M_ptr(0), _M_refcount()
836  { }
837 
838  template<typename _Tp1>
839  __shared_ptr&
840  operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
841  {
842  _M_ptr = __r._M_ptr;
843  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
844  return *this;
845  }
846 
847 #if _GLIBCXX_USE_DEPRECATED
848  template<typename _Tp1>
849  __shared_ptr&
850  operator=(std::auto_ptr<_Tp1>&& __r)
851  {
852  __shared_ptr(std::move(__r)).swap(*this);
853  return *this;
854  }
855 #endif
856 
857  __shared_ptr&
858  operator=(__shared_ptr&& __r) noexcept
859  {
860  __shared_ptr(std::move(__r)).swap(*this);
861  return *this;
862  }
863 
864  template<class _Tp1>
865  __shared_ptr&
866  operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
867  {
868  __shared_ptr(std::move(__r)).swap(*this);
869  return *this;
870  }
871 
872  template<typename _Tp1, typename _Del>
873  __shared_ptr&
874  operator=(std::unique_ptr<_Tp1, _Del>&& __r)
875  {
876  __shared_ptr(std::move(__r)).swap(*this);
877  return *this;
878  }
879 
880  void
881  reset() noexcept
882  { __shared_ptr().swap(*this); }
883 
884  template<typename _Tp1>
885  void
886  reset(_Tp1* __p) // _Tp1 must be complete.
887  {
888  // Catch self-reset errors.
889  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
890  __shared_ptr(__p).swap(*this);
891  }
892 
893  template<typename _Tp1, typename _Deleter>
894  void
895  reset(_Tp1* __p, _Deleter __d)
896  { __shared_ptr(__p, __d).swap(*this); }
897 
898  template<typename _Tp1, typename _Deleter, typename _Alloc>
899  void
900  reset(_Tp1* __p, _Deleter __d, _Alloc __a)
901  { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
902 
903  // Allow class instantiation when _Tp is [cv-qual] void.
904  typename std::add_lvalue_reference<_Tp>::type
905  operator*() const noexcept
906  {
907  _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
908  return *_M_ptr;
909  }
910 
911  _Tp*
912  operator->() const noexcept
913  {
914  _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
915  return _M_ptr;
916  }
917 
918  _Tp*
919  get() const noexcept
920  { return _M_ptr; }
921 
922  explicit operator bool() const // never throws
923  { return _M_ptr == 0 ? false : true; }
924 
925  bool
926  unique() const noexcept
927  { return _M_refcount._M_unique(); }
928 
929  long
930  use_count() const noexcept
931  { return _M_refcount._M_get_use_count(); }
932 
933  void
934  swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
935  {
936  std::swap(_M_ptr, __other._M_ptr);
937  _M_refcount._M_swap(__other._M_refcount);
938  }
939 
940  template<typename _Tp1>
941  bool
942  owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
943  { return _M_refcount._M_less(__rhs._M_refcount); }
944 
945  template<typename _Tp1>
946  bool
947  owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
948  { return _M_refcount._M_less(__rhs._M_refcount); }
949 
950 #ifdef __GXX_RTTI
951  protected:
952  // This constructor is non-standard, it is used by allocate_shared.
953  template<typename _Alloc, typename... _Args>
954  __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
955  _Args&&... __args)
956  : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
957  std::forward<_Args>(__args)...)
958  {
959  // _M_ptr needs to point to the newly constructed object.
960  // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
961  void* __p = _M_refcount._M_get_deleter(typeid(__tag));
962  _M_ptr = static_cast<_Tp*>(__p);
963  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
964  }
965 #else
966  template<typename _Alloc>
967  struct _Deleter
968  {
969  void operator()(_Tp* __ptr)
970  {
971  typedef allocator_traits<_Alloc> _Alloc_traits;
972  _Alloc_traits::destroy(_M_alloc, __ptr);
973  _Alloc_traits::deallocate(_M_alloc, __ptr, 1);
974  }
975  _Alloc _M_alloc;
976  };
977 
978  template<typename _Alloc, typename... _Args>
979  __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
980  _Args&&... __args)
981  : _M_ptr(), _M_refcount()
982  {
983  typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
984  _Deleter<_Alloc2> __del = { _Alloc2(__a) };
985  typedef allocator_traits<_Alloc2> __traits;
986  _M_ptr = __traits::allocate(__del._M_alloc, 1);
987  __try
988  {
989  // _GLIBCXX_RESOLVE_LIB_DEFECTS
990  // 2070. allocate_shared should use allocator_traits<A>::construct
991  __traits::construct(__del._M_alloc, _M_ptr,
992  std::forward<_Args>(__args)...);
993  }
994  __catch(...)
995  {
996  __traits::deallocate(__del._M_alloc, _M_ptr, 1);
998  }
999  __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
1000  _M_refcount._M_swap(__count);
1001  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1002  }
1003 #endif
1004 
1005  template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1006  typename... _Args>
1007  friend __shared_ptr<_Tp1, _Lp1>
1008  __allocate_shared(const _Alloc& __a, _Args&&... __args);
1009 
1010  private:
1011  void*
1012  _M_get_deleter(const std::type_info& __ti) const noexcept
1013  { return _M_refcount._M_get_deleter(__ti); }
1014 
1015  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1016  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1017 
1018  template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1019  friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1020 
1021  _Tp* _M_ptr; // Contained pointer.
1022  __shared_count<_Lp> _M_refcount; // Reference counter.
1023  };
1024 
1025 
1026  // 20.7.2.2.7 shared_ptr comparisons
1027  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1028  inline bool
1029  operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1030  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1031  { return __a.get() == __b.get(); }
1032 
1033  template<typename _Tp, _Lock_policy _Lp>
1034  inline bool
1035  operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1036  { return !__a; }
1037 
1038  template<typename _Tp, _Lock_policy _Lp>
1039  inline bool
1040  operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1041  { return !__a; }
1042 
1043  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1044  inline bool
1045  operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1046  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1047  { return __a.get() != __b.get(); }
1048 
1049  template<typename _Tp, _Lock_policy _Lp>
1050  inline bool
1051  operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1052  { return (bool)__a; }
1053 
1054  template<typename _Tp, _Lock_policy _Lp>
1055  inline bool
1056  operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1057  { return (bool)__a; }
1058 
1059  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1060  inline bool
1061  operator<(const __shared_ptr<_Tp1, _Lp>& __a,
1062  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1063  {
1064  typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
1065  return std::less<_CT>()(__a.get(), __b.get());
1066  }
1067 
1068  template<typename _Tp, _Lock_policy _Lp>
1069  inline bool
1070  operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1071  { return std::less<_Tp*>()(__a.get(), nullptr); }
1072 
1073  template<typename _Tp, _Lock_policy _Lp>
1074  inline bool
1075  operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1076  { return std::less<_Tp*>()(nullptr, __a.get()); }
1077 
1078  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1079  inline bool
1080  operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1081  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1082  { return !(__b < __a); }
1083 
1084  template<typename _Tp, _Lock_policy _Lp>
1085  inline bool
1086  operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1087  { return !(nullptr < __a); }
1088 
1089  template<typename _Tp, _Lock_policy _Lp>
1090  inline bool
1091  operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1092  { return !(__a < nullptr); }
1093 
1094  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1095  inline bool
1096  operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1097  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1098  { return (__b < __a); }
1099 
1100  template<typename _Tp, _Lock_policy _Lp>
1101  inline bool
1102  operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1103  { return std::less<_Tp*>()(nullptr, __a.get()); }
1104 
1105  template<typename _Tp, _Lock_policy _Lp>
1106  inline bool
1107  operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1108  { return std::less<_Tp*>()(__a.get(), nullptr); }
1109 
1110  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1111  inline bool
1112  operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1113  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1114  { return !(__a < __b); }
1115 
1116  template<typename _Tp, _Lock_policy _Lp>
1117  inline bool
1118  operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1119  { return !(__a < nullptr); }
1120 
1121  template<typename _Tp, _Lock_policy _Lp>
1122  inline bool
1123  operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1124  { return !(nullptr < __a); }
1125 
1126  template<typename _Sp>
1127  struct _Sp_less : public binary_function<_Sp, _Sp, bool>
1128  {
1129  bool
1130  operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
1131  {
1132  typedef typename _Sp::element_type element_type;
1133  return std::less<element_type*>()(__lhs.get(), __rhs.get());
1134  }
1135  };
1136 
1137  template<typename _Tp, _Lock_policy _Lp>
1138  struct less<__shared_ptr<_Tp, _Lp>>
1139  : public _Sp_less<__shared_ptr<_Tp, _Lp>>
1140  { };
1141 
1142  // 2.2.3.8 shared_ptr specialized algorithms.
1143  template<typename _Tp, _Lock_policy _Lp>
1144  inline void
1145  swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1146  { __a.swap(__b); }
1147 
1148  // 2.2.3.9 shared_ptr casts
1149 
1150  // The seemingly equivalent code:
1151  // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1152  // will eventually result in undefined behaviour, attempting to
1153  // delete the same object twice.
1155  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1156  inline __shared_ptr<_Tp, _Lp>
1157  static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1158  { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
1159 
1160  // The seemingly equivalent code:
1161  // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1162  // will eventually result in undefined behaviour, attempting to
1163  // delete the same object twice.
1165  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1166  inline __shared_ptr<_Tp, _Lp>
1167  const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1168  { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
1169 
1170  // The seemingly equivalent code:
1171  // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1172  // will eventually result in undefined behaviour, attempting to
1173  // delete the same object twice.
1175  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1176  inline __shared_ptr<_Tp, _Lp>
1177  dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1178  {
1179  if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
1180  return __shared_ptr<_Tp, _Lp>(__r, __p);
1181  return __shared_ptr<_Tp, _Lp>();
1182  }
1183 
1184 
1185  template<typename _Tp, _Lock_policy _Lp>
1186  class __weak_ptr
1187  {
1188  public:
1189  typedef _Tp element_type;
1190 
1191  constexpr __weak_ptr() noexcept
1192  : _M_ptr(0), _M_refcount()
1193  { }
1194 
1195  __weak_ptr(const __weak_ptr&) noexcept = default;
1196  __weak_ptr& operator=(const __weak_ptr&) noexcept = default;
1197  ~__weak_ptr() = default;
1198 
1199  // The "obvious" converting constructor implementation:
1200  //
1201  // template<typename _Tp1>
1202  // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1203  // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1204  // { }
1205  //
1206  // has a serious problem.
1207  //
1208  // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1209  // conversion may require access to *__r._M_ptr (virtual inheritance).
1210  //
1211  // It is not possible to avoid spurious access violations since
1212  // in multithreaded programs __r._M_ptr may be invalidated at any point.
1213  template<typename _Tp1, typename = typename
1214  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
1215  __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1216  : _M_refcount(__r._M_refcount)
1217  { _M_ptr = __r.lock().get(); }
1218 
1219  template<typename _Tp1, typename = typename
1220  std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
1221  __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1222  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1223  { }
1224 
1225  template<typename _Tp1>
1226  __weak_ptr&
1227  operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1228  {
1229  _M_ptr = __r.lock().get();
1230  _M_refcount = __r._M_refcount;
1231  return *this;
1232  }
1233 
1234  template<typename _Tp1>
1235  __weak_ptr&
1236  operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1237  {
1238  _M_ptr = __r._M_ptr;
1239  _M_refcount = __r._M_refcount;
1240  return *this;
1241  }
1242 
1243  __shared_ptr<_Tp, _Lp>
1244  lock() const noexcept
1245  {
1246 #ifdef __GTHREADS
1247  // Optimization: avoid throw overhead.
1248  if (expired())
1249  return __shared_ptr<element_type, _Lp>();
1250 
1251  __try
1252  {
1253  return __shared_ptr<element_type, _Lp>(*this);
1254  }
1255  __catch(const bad_weak_ptr&)
1256  {
1257  // Q: How can we get here?
1258  // A: Another thread may have invalidated r after the
1259  // use_count test above.
1260  return __shared_ptr<element_type, _Lp>();
1261  }
1262 
1263 #else
1264  // Optimization: avoid try/catch overhead when single threaded.
1265  return expired() ? __shared_ptr<element_type, _Lp>()
1266  : __shared_ptr<element_type, _Lp>(*this);
1267 
1268 #endif
1269  } // XXX MT
1270 
1271  long
1272  use_count() const noexcept
1273  { return _M_refcount._M_get_use_count(); }
1274 
1275  bool
1276  expired() const noexcept
1277  { return _M_refcount._M_get_use_count() == 0; }
1278 
1279  template<typename _Tp1>
1280  bool
1281  owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
1282  { return _M_refcount._M_less(__rhs._M_refcount); }
1283 
1284  template<typename _Tp1>
1285  bool
1286  owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
1287  { return _M_refcount._M_less(__rhs._M_refcount); }
1288 
1289  void
1290  reset() noexcept
1291  { __weak_ptr().swap(*this); }
1292 
1293  void
1294  swap(__weak_ptr& __s) noexcept
1295  {
1296  std::swap(_M_ptr, __s._M_ptr);
1297  _M_refcount._M_swap(__s._M_refcount);
1298  }
1299 
1300  private:
1301  // Used by __enable_shared_from_this.
1302  void
1303  _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1304  {
1305  _M_ptr = __ptr;
1306  _M_refcount = __refcount;
1307  }
1308 
1309  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1310  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1311  friend class __enable_shared_from_this<_Tp, _Lp>;
1312  friend class enable_shared_from_this<_Tp>;
1313 
1314  _Tp* _M_ptr; // Contained pointer.
1315  __weak_count<_Lp> _M_refcount; // Reference counter.
1316  };
1317 
1318  // 20.7.2.3.6 weak_ptr specialized algorithms.
1319  template<typename _Tp, _Lock_policy _Lp>
1320  inline void
1321  swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1322  { __a.swap(__b); }
1323 
1324  template<typename _Tp, typename _Tp1>
1325  struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1326  {
1327  bool
1328  operator()(const _Tp& __lhs, const _Tp& __rhs) const
1329  { return __lhs.owner_before(__rhs); }
1330 
1331  bool
1332  operator()(const _Tp& __lhs, const _Tp1& __rhs) const
1333  { return __lhs.owner_before(__rhs); }
1334 
1335  bool
1336  operator()(const _Tp1& __lhs, const _Tp& __rhs) const
1337  { return __lhs.owner_before(__rhs); }
1338  };
1339 
1340  template<typename _Tp, _Lock_policy _Lp>
1341  struct owner_less<__shared_ptr<_Tp, _Lp>>
1342  : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1343  { };
1344 
1345  template<typename _Tp, _Lock_policy _Lp>
1346  struct owner_less<__weak_ptr<_Tp, _Lp>>
1347  : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1348  { };
1349 
1350 
1351  template<typename _Tp, _Lock_policy _Lp>
1352  class __enable_shared_from_this
1353  {
1354  protected:
1355  constexpr __enable_shared_from_this() noexcept { }
1356 
1357  __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1358 
1359  __enable_shared_from_this&
1360  operator=(const __enable_shared_from_this&) noexcept
1361  { return *this; }
1362 
1363  ~__enable_shared_from_this() { }
1364 
1365  public:
1366  __shared_ptr<_Tp, _Lp>
1367  shared_from_this()
1368  { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1369 
1370  __shared_ptr<const _Tp, _Lp>
1371  shared_from_this() const
1372  { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1373 
1374  private:
1375  template<typename _Tp1>
1376  void
1377  _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1378  { _M_weak_this._M_assign(__p, __n); }
1379 
1380  template<typename _Tp1>
1381  friend void
1382  __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
1383  const __enable_shared_from_this* __pe,
1384  const _Tp1* __px) noexcept
1385  {
1386  if (__pe != 0)
1387  __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1388  }
1389 
1390  mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1391  };
1392 
1393 
1394  template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
1395  inline __shared_ptr<_Tp, _Lp>
1396  __allocate_shared(const _Alloc& __a, _Args&&... __args)
1397  {
1398  return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
1399  std::forward<_Args>(__args)...);
1400  }
1401 
1402  template<typename _Tp, _Lock_policy _Lp, typename... _Args>
1403  inline __shared_ptr<_Tp, _Lp>
1404  __make_shared(_Args&&... __args)
1405  {
1406  typedef typename std::remove_const<_Tp>::type _Tp_nc;
1407  return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1408  std::forward<_Args>(__args)...);
1409  }
1410 
1412  template<typename _Tp, _Lock_policy _Lp>
1413  struct hash<__shared_ptr<_Tp, _Lp>>
1414  : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1415  {
1416  size_t
1417  operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1418  { return std::hash<_Tp*>()(__s.get()); }
1419  };
1420 
1421 _GLIBCXX_END_NAMESPACE_VERSION
1422 } // namespace
#define __glibcxx_function_requires(...)
Definition: concept_check.h:47
bool operator>=(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:644
bool operator==(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
#define __try
Definition: exception_defines.h:35
Part of RTTI.
Definition: typeinfo:88
#define _GLIBCXX_DEBUG_ASSERT(_Condition)
Definition: debug.h:61
#define __throw_exception_again
Definition: exception_defines.h:37
#define bool
Definition: stdbool.h:33
bool operator>(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:612
#define _GLIBCXX_READ_MEM_BARRIER
Definition: atomicity.h:111
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
#define __catch(X)
Definition: exception_defines.h:36
#define _GLIBCXX_WRITE_MEM_BARRIER
Definition: atomicity.h:114
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160
template<typename _Ex >
exception_ptr std::copy_exception ( _Ex  __ex)

Obtain an exception_ptr pointing to a copy of the supplied object.

170  {
171  __try
172  {
173 #ifdef __EXCEPTIONS
174  throw __ex;
175 #endif
176  }
177  __catch(...)
178  {
179  return current_exception();
180  }
181  }
#define __try
Definition: exception_defines.h:35
#define __catch(X)
Definition: exception_defines.h:36
exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT
exception_ptr std::current_exception ( )

Obtain an exception_ptr to the currently handled exception. If there is none, or the currently handled exception is foreign, return the null value.

template<typename _Ex >
exception_ptr std::make_exception_ptr ( _Ex  __ex)

Obtain an exception_ptr pointing to a copy of the supplied object.

189  { return std::copy_exception<_Ex>(__ex); }
void std::rethrow_exception ( exception_ptr  )

Throw the object pointed to by the exception_ptr.

terminate_handler std::set_terminate ( terminate_handler  )

Takes a new handler function as an argument, returns the old function.

unexpected_handler std::set_unexpected ( unexpected_handler  )

Takes a new handler function as an argument, returns the old function.

void std::terminate ( )

The runtime will call this function if exception handling must be abandoned for any reason. It can also be called by the user.

bool std::uncaught_exception ( )

[18.6.4]/1: 'Returns true after completing evaluation of a throw-expression until either completing initialization of the exception-declaration in the matching handler or entering unexpected() due to the throw; or after entering terminate() for any reason other than an explicit call to terminate(). [Note: This includes stack unwinding [15.2]. end note]'

2: 'When uncaught_exception() is true, throwing an exception can result in a call of terminate() (15.5.1).'

void std::unexpected ( )

The runtime will call this function if an exception is thrown which violates the function's exception specification.