xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // shared_ptr and weak_ptr implementation -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj // GCC Note: Based on files from version 1.32.0 of the Boost library.
2638fd1498Szrj 
2738fd1498Szrj //  shared_count.hpp
2838fd1498Szrj //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
2938fd1498Szrj 
3038fd1498Szrj //  shared_ptr.hpp
3138fd1498Szrj //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
3238fd1498Szrj //  Copyright (C) 2001, 2002, 2003 Peter Dimov
3338fd1498Szrj 
3438fd1498Szrj //  weak_ptr.hpp
3538fd1498Szrj //  Copyright (C) 2001, 2002, 2003 Peter Dimov
3638fd1498Szrj 
3738fd1498Szrj //  enable_shared_from_this.hpp
3838fd1498Szrj //  Copyright (C) 2002 Peter Dimov
3938fd1498Szrj 
4038fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See
4138fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at
4238fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt)
4338fd1498Szrj 
4438fd1498Szrj /** @file
4538fd1498Szrj  *  This is an internal header file, included by other library headers.
4638fd1498Szrj  *  Do not attempt to use it directly. @headername{memory}
4738fd1498Szrj  */
4838fd1498Szrj 
4938fd1498Szrj #ifndef _SHARED_PTR_H
5038fd1498Szrj #define _SHARED_PTR_H 1
5138fd1498Szrj 
5238fd1498Szrj #include <bits/shared_ptr_base.h>
5338fd1498Szrj 
_GLIBCXX_VISIBILITY(default)5438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
5538fd1498Szrj {
5638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
5738fd1498Szrj 
5838fd1498Szrj   /**
5938fd1498Szrj    * @addtogroup pointer_abstractions
6038fd1498Szrj    * @{
6138fd1498Szrj    */
6238fd1498Szrj 
6338fd1498Szrj   /// 20.7.2.2.11 shared_ptr I/O
6438fd1498Szrj   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
6538fd1498Szrj     inline std::basic_ostream<_Ch, _Tr>&
6638fd1498Szrj     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
6738fd1498Szrj 	       const __shared_ptr<_Tp, _Lp>& __p)
6838fd1498Szrj     {
6938fd1498Szrj       __os << __p.get();
7038fd1498Szrj       return __os;
7138fd1498Szrj     }
7238fd1498Szrj 
7338fd1498Szrj   template<typename _Del, typename _Tp, _Lock_policy _Lp>
7438fd1498Szrj     inline _Del*
7538fd1498Szrj     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
7638fd1498Szrj     {
7738fd1498Szrj #if __cpp_rtti
7838fd1498Szrj       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
7938fd1498Szrj #else
8038fd1498Szrj       return 0;
8138fd1498Szrj #endif
8238fd1498Szrj     }
8338fd1498Szrj 
8438fd1498Szrj   /// 20.7.2.2.10 shared_ptr get_deleter
8538fd1498Szrj   template<typename _Del, typename _Tp>
8638fd1498Szrj     inline _Del*
8738fd1498Szrj     get_deleter(const shared_ptr<_Tp>& __p) noexcept
8838fd1498Szrj     {
8938fd1498Szrj #if __cpp_rtti
9038fd1498Szrj       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
9138fd1498Szrj #else
9238fd1498Szrj       return 0;
9338fd1498Szrj #endif
9438fd1498Szrj     }
9538fd1498Szrj 
9638fd1498Szrj   /**
9738fd1498Szrj    *  @brief  A smart pointer with reference-counted copy semantics.
9838fd1498Szrj    *
9938fd1498Szrj    *  The object pointed to is deleted when the last shared_ptr pointing to
10038fd1498Szrj    *  it is destroyed or reset.
10138fd1498Szrj   */
10238fd1498Szrj   template<typename _Tp>
10338fd1498Szrj     class shared_ptr : public __shared_ptr<_Tp>
10438fd1498Szrj     {
10538fd1498Szrj       template<typename... _Args>
10638fd1498Szrj 	using _Constructible = typename enable_if<
10738fd1498Szrj 	  is_constructible<__shared_ptr<_Tp>, _Args...>::value
10838fd1498Szrj 	>::type;
10938fd1498Szrj 
11038fd1498Szrj       template<typename _Arg>
11138fd1498Szrj 	using _Assignable = typename enable_if<
11238fd1498Szrj 	  is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
11338fd1498Szrj 	>::type;
11438fd1498Szrj 
11538fd1498Szrj     public:
11638fd1498Szrj 
11738fd1498Szrj       using element_type = typename __shared_ptr<_Tp>::element_type;
11838fd1498Szrj 
11938fd1498Szrj #if __cplusplus > 201402L
12038fd1498Szrj # define __cpp_lib_shared_ptr_weak_type 201606
12138fd1498Szrj       using weak_type = weak_ptr<_Tp>;
12238fd1498Szrj #endif
12338fd1498Szrj       /**
12438fd1498Szrj        *  @brief  Construct an empty %shared_ptr.
12538fd1498Szrj        *  @post   use_count()==0 && get()==0
12638fd1498Szrj        */
12738fd1498Szrj       constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
12838fd1498Szrj 
12938fd1498Szrj       shared_ptr(const shared_ptr&) noexcept = default;
13038fd1498Szrj 
13138fd1498Szrj       /**
13238fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
13338fd1498Szrj        *  @param  __p  A pointer that is convertible to element_type*.
13438fd1498Szrj        *  @post   use_count() == 1 && get() == __p
13538fd1498Szrj        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
13638fd1498Szrj        */
13738fd1498Szrj       template<typename _Yp, typename = _Constructible<_Yp*>>
13838fd1498Szrj 	explicit
13938fd1498Szrj 	shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
14038fd1498Szrj 
14138fd1498Szrj       /**
14238fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
14338fd1498Szrj        *          and the deleter @a __d.
14438fd1498Szrj        *  @param  __p  A pointer.
14538fd1498Szrj        *  @param  __d  A deleter.
14638fd1498Szrj        *  @post   use_count() == 1 && get() == __p
14738fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
14838fd1498Szrj        *
14938fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
15038fd1498Szrj        *  not throw
15138fd1498Szrj        *
15238fd1498Szrj        *  __shared_ptr will release __p by calling __d(__p)
15338fd1498Szrj        */
15438fd1498Szrj       template<typename _Yp, typename _Deleter,
15538fd1498Szrj 	       typename = _Constructible<_Yp*, _Deleter>>
15638fd1498Szrj 	shared_ptr(_Yp* __p, _Deleter __d)
15738fd1498Szrj         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
15838fd1498Szrj 
15938fd1498Szrj       /**
16038fd1498Szrj        *  @brief  Construct a %shared_ptr that owns a null pointer
16138fd1498Szrj        *          and the deleter @a __d.
16238fd1498Szrj        *  @param  __p  A null pointer constant.
16338fd1498Szrj        *  @param  __d  A deleter.
16438fd1498Szrj        *  @post   use_count() == 1 && get() == __p
16538fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
16638fd1498Szrj        *
16738fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
16838fd1498Szrj        *  not throw
16938fd1498Szrj        *
17038fd1498Szrj        *  The last owner will call __d(__p)
17138fd1498Szrj        */
17238fd1498Szrj       template<typename _Deleter>
17338fd1498Szrj 	shared_ptr(nullptr_t __p, _Deleter __d)
17438fd1498Szrj         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
17538fd1498Szrj 
17638fd1498Szrj       /**
17738fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
17838fd1498Szrj        *          and the deleter @a __d.
17938fd1498Szrj        *  @param  __p  A pointer.
18038fd1498Szrj        *  @param  __d  A deleter.
18138fd1498Szrj        *  @param  __a  An allocator.
18238fd1498Szrj        *  @post   use_count() == 1 && get() == __p
18338fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
18438fd1498Szrj        *
18538fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
18638fd1498Szrj        *  not throw _Alloc's copy constructor and destructor must not
18738fd1498Szrj        *  throw.
18838fd1498Szrj        *
18938fd1498Szrj        *  __shared_ptr will release __p by calling __d(__p)
19038fd1498Szrj        */
19138fd1498Szrj       template<typename _Yp, typename _Deleter, typename _Alloc,
19238fd1498Szrj 	       typename = _Constructible<_Yp*, _Deleter, _Alloc>>
19338fd1498Szrj 	shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
19438fd1498Szrj 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
19538fd1498Szrj 
19638fd1498Szrj       /**
19738fd1498Szrj        *  @brief  Construct a %shared_ptr that owns a null pointer
19838fd1498Szrj        *          and the deleter @a __d.
19938fd1498Szrj        *  @param  __p  A null pointer constant.
20038fd1498Szrj        *  @param  __d  A deleter.
20138fd1498Szrj        *  @param  __a  An allocator.
20238fd1498Szrj        *  @post   use_count() == 1 && get() == __p
20338fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
20438fd1498Szrj        *
20538fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
20638fd1498Szrj        *  not throw _Alloc's copy constructor and destructor must not
20738fd1498Szrj        *  throw.
20838fd1498Szrj        *
20938fd1498Szrj        *  The last owner will call __d(__p)
21038fd1498Szrj        */
21138fd1498Szrj       template<typename _Deleter, typename _Alloc>
21238fd1498Szrj 	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
21338fd1498Szrj 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
21438fd1498Szrj 
21538fd1498Szrj       // Aliasing constructor
21638fd1498Szrj 
21738fd1498Szrj       /**
21838fd1498Szrj        *  @brief  Constructs a %shared_ptr instance that stores @a __p
21938fd1498Szrj        *          and shares ownership with @a __r.
22038fd1498Szrj        *  @param  __r  A %shared_ptr.
22138fd1498Szrj        *  @param  __p  A pointer that will remain valid while @a *__r is valid.
22238fd1498Szrj        *  @post   get() == __p && use_count() == __r.use_count()
22338fd1498Szrj        *
22438fd1498Szrj        *  This can be used to construct a @c shared_ptr to a sub-object
22538fd1498Szrj        *  of an object managed by an existing @c shared_ptr.
22638fd1498Szrj        *
22738fd1498Szrj        * @code
22838fd1498Szrj        * shared_ptr< pair<int,int> > pii(new pair<int,int>());
22938fd1498Szrj        * shared_ptr<int> pi(pii, &pii->first);
23038fd1498Szrj        * assert(pii.use_count() == 2);
23138fd1498Szrj        * @endcode
23238fd1498Szrj        */
23338fd1498Szrj       template<typename _Yp>
23438fd1498Szrj 	shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
23538fd1498Szrj 	: __shared_ptr<_Tp>(__r, __p) { }
23638fd1498Szrj 
23738fd1498Szrj       /**
23838fd1498Szrj        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
23938fd1498Szrj        *          otherwise construct a %shared_ptr that shares ownership
24038fd1498Szrj        *          with @a __r.
24138fd1498Szrj        *  @param  __r  A %shared_ptr.
24238fd1498Szrj        *  @post   get() == __r.get() && use_count() == __r.use_count()
24338fd1498Szrj        */
24438fd1498Szrj       template<typename _Yp,
24538fd1498Szrj 	       typename = _Constructible<const shared_ptr<_Yp>&>>
24638fd1498Szrj 	shared_ptr(const shared_ptr<_Yp>& __r) noexcept
24738fd1498Szrj         : __shared_ptr<_Tp>(__r) { }
24838fd1498Szrj 
24938fd1498Szrj       /**
25038fd1498Szrj        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
25138fd1498Szrj        *  @param  __r  A %shared_ptr rvalue.
25238fd1498Szrj        *  @post   *this contains the old value of @a __r, @a __r is empty.
25338fd1498Szrj        */
25438fd1498Szrj       shared_ptr(shared_ptr&& __r) noexcept
25538fd1498Szrj       : __shared_ptr<_Tp>(std::move(__r)) { }
25638fd1498Szrj 
25738fd1498Szrj       /**
25838fd1498Szrj        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
25938fd1498Szrj        *  @param  __r  A %shared_ptr rvalue.
26038fd1498Szrj        *  @post   *this contains the old value of @a __r, @a __r is empty.
26138fd1498Szrj        */
26238fd1498Szrj       template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
26338fd1498Szrj 	shared_ptr(shared_ptr<_Yp>&& __r) noexcept
26438fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r)) { }
26538fd1498Szrj 
26638fd1498Szrj       /**
26738fd1498Szrj        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
26838fd1498Szrj        *          and stores a copy of the pointer stored in @a __r.
26938fd1498Szrj        *  @param  __r  A weak_ptr.
27038fd1498Szrj        *  @post   use_count() == __r.use_count()
27138fd1498Szrj        *  @throw  bad_weak_ptr when __r.expired(),
27238fd1498Szrj        *          in which case the constructor has no effect.
27338fd1498Szrj        */
27438fd1498Szrj       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
27538fd1498Szrj 	explicit shared_ptr(const weak_ptr<_Yp>& __r)
27638fd1498Szrj 	: __shared_ptr<_Tp>(__r) { }
27738fd1498Szrj 
27838fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
27938fd1498Szrj #pragma GCC diagnostic push
28038fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
28138fd1498Szrj       template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
28238fd1498Szrj 	shared_ptr(auto_ptr<_Yp>&& __r);
28338fd1498Szrj #pragma GCC diagnostic pop
28438fd1498Szrj #endif
28538fd1498Szrj 
28638fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
28738fd1498Szrj       // 2399. shared_ptr's constructor from unique_ptr should be constrained
28838fd1498Szrj       template<typename _Yp, typename _Del,
28938fd1498Szrj 	       typename = _Constructible<unique_ptr<_Yp, _Del>>>
29038fd1498Szrj 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
29138fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r)) { }
29238fd1498Szrj 
29338fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
29438fd1498Szrj       // This non-standard constructor exists to support conversions that
29538fd1498Szrj       // were possible in C++11 and C++14 but are ill-formed in C++17.
29638fd1498Szrj       // If an exception is thrown this constructor has no effect.
29738fd1498Szrj       template<typename _Yp, typename _Del,
29838fd1498Szrj 		_Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
29938fd1498Szrj 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
30038fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
30138fd1498Szrj #endif
30238fd1498Szrj 
30338fd1498Szrj       /**
30438fd1498Szrj        *  @brief  Construct an empty %shared_ptr.
30538fd1498Szrj        *  @post   use_count() == 0 && get() == nullptr
30638fd1498Szrj        */
30738fd1498Szrj       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
30838fd1498Szrj 
30938fd1498Szrj       shared_ptr& operator=(const shared_ptr&) noexcept = default;
31038fd1498Szrj 
31138fd1498Szrj       template<typename _Yp>
31238fd1498Szrj 	_Assignable<const shared_ptr<_Yp>&>
31338fd1498Szrj 	operator=(const shared_ptr<_Yp>& __r) noexcept
31438fd1498Szrj 	{
31538fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(__r);
31638fd1498Szrj 	  return *this;
31738fd1498Szrj 	}
31838fd1498Szrj 
31938fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
32038fd1498Szrj #pragma GCC diagnostic push
32138fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
32238fd1498Szrj       template<typename _Yp>
32338fd1498Szrj 	_Assignable<auto_ptr<_Yp>>
32438fd1498Szrj 	operator=(auto_ptr<_Yp>&& __r)
32538fd1498Szrj 	{
32638fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
32738fd1498Szrj 	  return *this;
32838fd1498Szrj 	}
32938fd1498Szrj #pragma GCC diagnostic pop
33038fd1498Szrj #endif
33138fd1498Szrj 
33238fd1498Szrj       shared_ptr&
33338fd1498Szrj       operator=(shared_ptr&& __r) noexcept
33438fd1498Szrj       {
33538fd1498Szrj 	this->__shared_ptr<_Tp>::operator=(std::move(__r));
33638fd1498Szrj 	return *this;
33738fd1498Szrj       }
33838fd1498Szrj 
33938fd1498Szrj       template<class _Yp>
34038fd1498Szrj 	_Assignable<shared_ptr<_Yp>>
34138fd1498Szrj 	operator=(shared_ptr<_Yp>&& __r) noexcept
34238fd1498Szrj 	{
34338fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
34438fd1498Szrj 	  return *this;
34538fd1498Szrj 	}
34638fd1498Szrj 
34738fd1498Szrj       template<typename _Yp, typename _Del>
34838fd1498Szrj 	_Assignable<unique_ptr<_Yp, _Del>>
34938fd1498Szrj 	operator=(unique_ptr<_Yp, _Del>&& __r)
35038fd1498Szrj 	{
35138fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
35238fd1498Szrj 	  return *this;
35338fd1498Szrj 	}
35438fd1498Szrj 
35538fd1498Szrj     private:
35638fd1498Szrj       // This constructor is non-standard, it is used by allocate_shared.
35738fd1498Szrj       template<typename _Alloc, typename... _Args>
358*58e805e6Szrj 	shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
359*58e805e6Szrj 	: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
36038fd1498Szrj 	{ }
36138fd1498Szrj 
36238fd1498Szrj       template<typename _Yp, typename _Alloc, typename... _Args>
36338fd1498Szrj 	friend shared_ptr<_Yp>
36438fd1498Szrj 	allocate_shared(const _Alloc& __a, _Args&&... __args);
36538fd1498Szrj 
36638fd1498Szrj       // This constructor is non-standard, it is used by weak_ptr::lock().
36738fd1498Szrj       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
36838fd1498Szrj       : __shared_ptr<_Tp>(__r, std::nothrow) { }
36938fd1498Szrj 
37038fd1498Szrj       friend class weak_ptr<_Tp>;
37138fd1498Szrj     };
37238fd1498Szrj 
37338fd1498Szrj #if __cpp_deduction_guides >= 201606
37438fd1498Szrj   template<typename _Tp>
37538fd1498Szrj     shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;
37638fd1498Szrj   template<typename _Tp, typename _Del>
37738fd1498Szrj     shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;
37838fd1498Szrj #endif
37938fd1498Szrj 
38038fd1498Szrj   // 20.7.2.2.7 shared_ptr comparisons
38138fd1498Szrj   template<typename _Tp, typename _Up>
38238fd1498Szrj     inline bool
38338fd1498Szrj     operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
38438fd1498Szrj     { return __a.get() == __b.get(); }
38538fd1498Szrj 
38638fd1498Szrj   template<typename _Tp>
38738fd1498Szrj     inline bool
38838fd1498Szrj     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
38938fd1498Szrj     { return !__a; }
39038fd1498Szrj 
39138fd1498Szrj   template<typename _Tp>
39238fd1498Szrj     inline bool
39338fd1498Szrj     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
39438fd1498Szrj     { return !__a; }
39538fd1498Szrj 
39638fd1498Szrj   template<typename _Tp, typename _Up>
39738fd1498Szrj     inline bool
39838fd1498Szrj     operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
39938fd1498Szrj     { return __a.get() != __b.get(); }
40038fd1498Szrj 
40138fd1498Szrj   template<typename _Tp>
40238fd1498Szrj     inline bool
40338fd1498Szrj     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
40438fd1498Szrj     { return (bool)__a; }
40538fd1498Szrj 
40638fd1498Szrj   template<typename _Tp>
40738fd1498Szrj     inline bool
40838fd1498Szrj     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
40938fd1498Szrj     { return (bool)__a; }
41038fd1498Szrj 
41138fd1498Szrj   template<typename _Tp, typename _Up>
41238fd1498Szrj     inline bool
41338fd1498Szrj     operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
41438fd1498Szrj     {
41538fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
41638fd1498Szrj       using _Up_elt = typename shared_ptr<_Up>::element_type;
41738fd1498Szrj       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
41838fd1498Szrj       return less<_Vp>()(__a.get(), __b.get());
41938fd1498Szrj     }
42038fd1498Szrj 
42138fd1498Szrj   template<typename _Tp>
42238fd1498Szrj     inline bool
42338fd1498Szrj     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
42438fd1498Szrj     {
42538fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
42638fd1498Szrj       return less<_Tp_elt*>()(__a.get(), nullptr);
42738fd1498Szrj     }
42838fd1498Szrj 
42938fd1498Szrj   template<typename _Tp>
43038fd1498Szrj     inline bool
43138fd1498Szrj     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
43238fd1498Szrj     {
43338fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
43438fd1498Szrj       return less<_Tp_elt*>()(nullptr, __a.get());
43538fd1498Szrj     }
43638fd1498Szrj 
43738fd1498Szrj   template<typename _Tp, typename _Up>
43838fd1498Szrj     inline bool
43938fd1498Szrj     operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
44038fd1498Szrj     { return !(__b < __a); }
44138fd1498Szrj 
44238fd1498Szrj   template<typename _Tp>
44338fd1498Szrj     inline bool
44438fd1498Szrj     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
44538fd1498Szrj     { return !(nullptr < __a); }
44638fd1498Szrj 
44738fd1498Szrj   template<typename _Tp>
44838fd1498Szrj     inline bool
44938fd1498Szrj     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
45038fd1498Szrj     { return !(__a < nullptr); }
45138fd1498Szrj 
45238fd1498Szrj   template<typename _Tp, typename _Up>
45338fd1498Szrj     inline bool
45438fd1498Szrj     operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
45538fd1498Szrj     { return (__b < __a); }
45638fd1498Szrj 
45738fd1498Szrj   template<typename _Tp>
45838fd1498Szrj     inline bool
45938fd1498Szrj     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
46038fd1498Szrj     { return nullptr < __a; }
46138fd1498Szrj 
46238fd1498Szrj   template<typename _Tp>
46338fd1498Szrj     inline bool
46438fd1498Szrj     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
46538fd1498Szrj     { return __a < nullptr; }
46638fd1498Szrj 
46738fd1498Szrj   template<typename _Tp, typename _Up>
46838fd1498Szrj     inline bool
46938fd1498Szrj     operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
47038fd1498Szrj     { return !(__a < __b); }
47138fd1498Szrj 
47238fd1498Szrj   template<typename _Tp>
47338fd1498Szrj     inline bool
47438fd1498Szrj     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
47538fd1498Szrj     { return !(__a < nullptr); }
47638fd1498Szrj 
47738fd1498Szrj   template<typename _Tp>
47838fd1498Szrj     inline bool
47938fd1498Szrj     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
48038fd1498Szrj     { return !(nullptr < __a); }
48138fd1498Szrj 
48238fd1498Szrj   template<typename _Tp>
48338fd1498Szrj     struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
48438fd1498Szrj     { };
48538fd1498Szrj 
48638fd1498Szrj   // 20.7.2.2.8 shared_ptr specialized algorithms.
48738fd1498Szrj   template<typename _Tp>
48838fd1498Szrj     inline void
48938fd1498Szrj     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
49038fd1498Szrj     { __a.swap(__b); }
49138fd1498Szrj 
49238fd1498Szrj   // 20.7.2.2.9 shared_ptr casts.
49338fd1498Szrj   template<typename _Tp, typename _Up>
49438fd1498Szrj     inline shared_ptr<_Tp>
49538fd1498Szrj     static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
49638fd1498Szrj     {
49738fd1498Szrj       using _Sp = shared_ptr<_Tp>;
49838fd1498Szrj       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
49938fd1498Szrj     }
50038fd1498Szrj 
50138fd1498Szrj   template<typename _Tp, typename _Up>
50238fd1498Szrj     inline shared_ptr<_Tp>
50338fd1498Szrj     const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
50438fd1498Szrj     {
50538fd1498Szrj       using _Sp = shared_ptr<_Tp>;
50638fd1498Szrj       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
50738fd1498Szrj     }
50838fd1498Szrj 
50938fd1498Szrj   template<typename _Tp, typename _Up>
51038fd1498Szrj     inline shared_ptr<_Tp>
51138fd1498Szrj     dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
51238fd1498Szrj     {
51338fd1498Szrj       using _Sp = shared_ptr<_Tp>;
51438fd1498Szrj       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
51538fd1498Szrj 	return _Sp(__r, __p);
51638fd1498Szrj       return _Sp();
51738fd1498Szrj     }
51838fd1498Szrj 
51938fd1498Szrj #if __cplusplus > 201402L
52038fd1498Szrj   template<typename _Tp, typename _Up>
52138fd1498Szrj     inline shared_ptr<_Tp>
52238fd1498Szrj     reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
52338fd1498Szrj     {
52438fd1498Szrj       using _Sp = shared_ptr<_Tp>;
52538fd1498Szrj       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
52638fd1498Szrj     }
52738fd1498Szrj #endif
52838fd1498Szrj 
52938fd1498Szrj   /**
53038fd1498Szrj    *  @brief  A smart pointer with weak semantics.
53138fd1498Szrj    *
53238fd1498Szrj    *  With forwarding constructors and assignment operators.
53338fd1498Szrj    */
53438fd1498Szrj   template<typename _Tp>
53538fd1498Szrj     class weak_ptr : public __weak_ptr<_Tp>
53638fd1498Szrj     {
53738fd1498Szrj       template<typename _Arg>
53838fd1498Szrj 	using _Constructible = typename enable_if<
53938fd1498Szrj 	  is_constructible<__weak_ptr<_Tp>, _Arg>::value
54038fd1498Szrj 	>::type;
54138fd1498Szrj 
54238fd1498Szrj       template<typename _Arg>
54338fd1498Szrj 	using _Assignable = typename enable_if<
54438fd1498Szrj 	  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
54538fd1498Szrj 	>::type;
54638fd1498Szrj 
54738fd1498Szrj     public:
54838fd1498Szrj       constexpr weak_ptr() noexcept = default;
54938fd1498Szrj 
55038fd1498Szrj       template<typename _Yp,
55138fd1498Szrj 	       typename = _Constructible<const shared_ptr<_Yp>&>>
55238fd1498Szrj 	weak_ptr(const shared_ptr<_Yp>& __r) noexcept
55338fd1498Szrj 	: __weak_ptr<_Tp>(__r) { }
55438fd1498Szrj 
55538fd1498Szrj       weak_ptr(const weak_ptr&) noexcept = default;
55638fd1498Szrj 
55738fd1498Szrj       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
55838fd1498Szrj 	weak_ptr(const weak_ptr<_Yp>& __r) noexcept
55938fd1498Szrj 	: __weak_ptr<_Tp>(__r) { }
56038fd1498Szrj 
56138fd1498Szrj       weak_ptr(weak_ptr&&) noexcept = default;
56238fd1498Szrj 
56338fd1498Szrj       template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
56438fd1498Szrj 	weak_ptr(weak_ptr<_Yp>&& __r) noexcept
56538fd1498Szrj 	: __weak_ptr<_Tp>(std::move(__r)) { }
56638fd1498Szrj 
56738fd1498Szrj       weak_ptr&
56838fd1498Szrj       operator=(const weak_ptr& __r) noexcept = default;
56938fd1498Szrj 
57038fd1498Szrj       template<typename _Yp>
57138fd1498Szrj 	_Assignable<const weak_ptr<_Yp>&>
57238fd1498Szrj 	operator=(const weak_ptr<_Yp>& __r) noexcept
57338fd1498Szrj 	{
57438fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(__r);
57538fd1498Szrj 	  return *this;
57638fd1498Szrj 	}
57738fd1498Szrj 
57838fd1498Szrj       template<typename _Yp>
57938fd1498Szrj 	_Assignable<const shared_ptr<_Yp>&>
58038fd1498Szrj 	operator=(const shared_ptr<_Yp>& __r) noexcept
58138fd1498Szrj 	{
58238fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(__r);
58338fd1498Szrj 	  return *this;
58438fd1498Szrj 	}
58538fd1498Szrj 
58638fd1498Szrj       weak_ptr&
58738fd1498Szrj       operator=(weak_ptr&& __r) noexcept = default;
58838fd1498Szrj 
58938fd1498Szrj       template<typename _Yp>
59038fd1498Szrj 	_Assignable<weak_ptr<_Yp>>
59138fd1498Szrj 	operator=(weak_ptr<_Yp>&& __r) noexcept
59238fd1498Szrj 	{
59338fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(std::move(__r));
59438fd1498Szrj 	  return *this;
59538fd1498Szrj 	}
59638fd1498Szrj 
59738fd1498Szrj       shared_ptr<_Tp>
59838fd1498Szrj       lock() const noexcept
59938fd1498Szrj       { return shared_ptr<_Tp>(*this, std::nothrow); }
60038fd1498Szrj     };
60138fd1498Szrj 
60238fd1498Szrj #if __cpp_deduction_guides >= 201606
60338fd1498Szrj   template<typename _Tp>
60438fd1498Szrj     weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;
60538fd1498Szrj #endif
60638fd1498Szrj 
60738fd1498Szrj   // 20.7.2.3.6 weak_ptr specialized algorithms.
60838fd1498Szrj   template<typename _Tp>
60938fd1498Szrj     inline void
61038fd1498Szrj     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
61138fd1498Szrj     { __a.swap(__b); }
61238fd1498Szrj 
61338fd1498Szrj 
61438fd1498Szrj   /// Primary template owner_less
61538fd1498Szrj   template<typename _Tp = void>
61638fd1498Szrj     struct owner_less;
61738fd1498Szrj 
61838fd1498Szrj   /// Void specialization of owner_less
61938fd1498Szrj   template<>
62038fd1498Szrj     struct owner_less<void> : _Sp_owner_less<void, void>
62138fd1498Szrj     { };
62238fd1498Szrj 
62338fd1498Szrj   /// Partial specialization of owner_less for shared_ptr.
62438fd1498Szrj   template<typename _Tp>
62538fd1498Szrj     struct owner_less<shared_ptr<_Tp>>
62638fd1498Szrj     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
62738fd1498Szrj     { };
62838fd1498Szrj 
62938fd1498Szrj   /// Partial specialization of owner_less for weak_ptr.
63038fd1498Szrj   template<typename _Tp>
63138fd1498Szrj     struct owner_less<weak_ptr<_Tp>>
63238fd1498Szrj     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
63338fd1498Szrj     { };
63438fd1498Szrj 
63538fd1498Szrj   /**
63638fd1498Szrj    *  @brief Base class allowing use of member function shared_from_this.
63738fd1498Szrj    */
63838fd1498Szrj   template<typename _Tp>
63938fd1498Szrj     class enable_shared_from_this
64038fd1498Szrj     {
64138fd1498Szrj     protected:
64238fd1498Szrj       constexpr enable_shared_from_this() noexcept { }
64338fd1498Szrj 
64438fd1498Szrj       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
64538fd1498Szrj 
64638fd1498Szrj       enable_shared_from_this&
64738fd1498Szrj       operator=(const enable_shared_from_this&) noexcept
64838fd1498Szrj       { return *this; }
64938fd1498Szrj 
65038fd1498Szrj       ~enable_shared_from_this() { }
65138fd1498Szrj 
65238fd1498Szrj     public:
65338fd1498Szrj       shared_ptr<_Tp>
65438fd1498Szrj       shared_from_this()
65538fd1498Szrj       { return shared_ptr<_Tp>(this->_M_weak_this); }
65638fd1498Szrj 
65738fd1498Szrj       shared_ptr<const _Tp>
65838fd1498Szrj       shared_from_this() const
65938fd1498Szrj       { return shared_ptr<const _Tp>(this->_M_weak_this); }
66038fd1498Szrj 
66138fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
66238fd1498Szrj #define __cpp_lib_enable_shared_from_this 201603
66338fd1498Szrj       weak_ptr<_Tp>
66438fd1498Szrj       weak_from_this() noexcept
66538fd1498Szrj       { return this->_M_weak_this; }
66638fd1498Szrj 
66738fd1498Szrj       weak_ptr<const _Tp>
66838fd1498Szrj       weak_from_this() const noexcept
66938fd1498Szrj       { return this->_M_weak_this; }
67038fd1498Szrj #endif
67138fd1498Szrj 
67238fd1498Szrj     private:
67338fd1498Szrj       template<typename _Tp1>
67438fd1498Szrj 	void
67538fd1498Szrj 	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
67638fd1498Szrj 	{ _M_weak_this._M_assign(__p, __n); }
67738fd1498Szrj 
67838fd1498Szrj       // Found by ADL when this is an associated class.
67938fd1498Szrj       friend const enable_shared_from_this*
68038fd1498Szrj       __enable_shared_from_this_base(const __shared_count<>&,
68138fd1498Szrj 				     const enable_shared_from_this* __p)
68238fd1498Szrj       { return __p; }
68338fd1498Szrj 
68438fd1498Szrj       template<typename, _Lock_policy>
68538fd1498Szrj 	friend class __shared_ptr;
68638fd1498Szrj 
68738fd1498Szrj       mutable weak_ptr<_Tp>  _M_weak_this;
68838fd1498Szrj     };
68938fd1498Szrj 
69038fd1498Szrj   /**
69138fd1498Szrj    *  @brief  Create an object that is owned by a shared_ptr.
69238fd1498Szrj    *  @param  __a     An allocator.
69338fd1498Szrj    *  @param  __args  Arguments for the @a _Tp object's constructor.
69438fd1498Szrj    *  @return A shared_ptr that owns the newly created object.
69538fd1498Szrj    *  @throw  An exception thrown from @a _Alloc::allocate or from the
69638fd1498Szrj    *          constructor of @a _Tp.
69738fd1498Szrj    *
69838fd1498Szrj    *  A copy of @a __a will be used to allocate memory for the shared_ptr
69938fd1498Szrj    *  and the new object.
70038fd1498Szrj    */
70138fd1498Szrj   template<typename _Tp, typename _Alloc, typename... _Args>
70238fd1498Szrj     inline shared_ptr<_Tp>
70338fd1498Szrj     allocate_shared(const _Alloc& __a, _Args&&... __args)
70438fd1498Szrj     {
705*58e805e6Szrj       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
70638fd1498Szrj 			     std::forward<_Args>(__args)...);
70738fd1498Szrj     }
70838fd1498Szrj 
70938fd1498Szrj   /**
71038fd1498Szrj    *  @brief  Create an object that is owned by a shared_ptr.
71138fd1498Szrj    *  @param  __args  Arguments for the @a _Tp object's constructor.
71238fd1498Szrj    *  @return A shared_ptr that owns the newly created object.
71338fd1498Szrj    *  @throw  std::bad_alloc, or an exception thrown from the
71438fd1498Szrj    *          constructor of @a _Tp.
71538fd1498Szrj    */
71638fd1498Szrj   template<typename _Tp, typename... _Args>
71738fd1498Szrj     inline shared_ptr<_Tp>
71838fd1498Szrj     make_shared(_Args&&... __args)
71938fd1498Szrj     {
720*58e805e6Szrj       typedef typename std::remove_cv<_Tp>::type _Tp_nc;
72138fd1498Szrj       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
72238fd1498Szrj 				       std::forward<_Args>(__args)...);
72338fd1498Szrj     }
72438fd1498Szrj 
72538fd1498Szrj   /// std::hash specialization for shared_ptr.
72638fd1498Szrj   template<typename _Tp>
72738fd1498Szrj     struct hash<shared_ptr<_Tp>>
72838fd1498Szrj     : public __hash_base<size_t, shared_ptr<_Tp>>
72938fd1498Szrj     {
73038fd1498Szrj       size_t
73138fd1498Szrj       operator()(const shared_ptr<_Tp>& __s) const noexcept
73238fd1498Szrj       {
73338fd1498Szrj 	return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
73438fd1498Szrj       }
73538fd1498Szrj     };
73638fd1498Szrj 
73738fd1498Szrj   // @} group pointer_abstractions
73838fd1498Szrj 
73938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
74038fd1498Szrj } // namespace
74138fd1498Szrj 
74238fd1498Szrj #endif // _SHARED_PTR_H
743