xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/shared_ptr.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
14fee23f9Smrg // shared_ptr and weak_ptr implementation -*- C++ -*-
24fee23f9Smrg 
3*b1e83836Smrg // Copyright (C) 2007-2022 Free Software Foundation, Inc.
44fee23f9Smrg //
54fee23f9Smrg // This file is part of the GNU ISO C++ Library.  This library is free
64fee23f9Smrg // software; you can redistribute it and/or modify it under the
74fee23f9Smrg // terms of the GNU General Public License as published by the
84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg // any later version.
104fee23f9Smrg 
114fee23f9Smrg // This library is distributed in the hope that it will be useful,
124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144fee23f9Smrg // GNU General Public License for more details.
154fee23f9Smrg 
164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg // 3.1, as published by the Free Software Foundation.
194fee23f9Smrg 
204fee23f9Smrg // You should have received a copy of the GNU General Public License and
214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234fee23f9Smrg // <http://www.gnu.org/licenses/>.
244fee23f9Smrg 
254fee23f9Smrg // GCC Note: Based on files from version 1.32.0 of the Boost library.
264fee23f9Smrg 
274fee23f9Smrg //  shared_count.hpp
284fee23f9Smrg //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
294fee23f9Smrg 
304fee23f9Smrg //  shared_ptr.hpp
314fee23f9Smrg //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
324fee23f9Smrg //  Copyright (C) 2001, 2002, 2003 Peter Dimov
334fee23f9Smrg 
344fee23f9Smrg //  weak_ptr.hpp
354fee23f9Smrg //  Copyright (C) 2001, 2002, 2003 Peter Dimov
364fee23f9Smrg 
374fee23f9Smrg //  enable_shared_from_this.hpp
384fee23f9Smrg //  Copyright (C) 2002 Peter Dimov
394fee23f9Smrg 
404fee23f9Smrg // Distributed under the Boost Software License, Version 1.0. (See
414fee23f9Smrg // accompanying file LICENSE_1_0.txt or copy at
424fee23f9Smrg // http://www.boost.org/LICENSE_1_0.txt)
434fee23f9Smrg 
44f9a78e0eSmrg /** @file
454fee23f9Smrg  *  This is an internal header file, included by other library headers.
4648fb7bfaSmrg  *  Do not attempt to use it directly. @headername{memory}
474fee23f9Smrg  */
484fee23f9Smrg 
494fee23f9Smrg #ifndef _SHARED_PTR_H
504fee23f9Smrg #define _SHARED_PTR_H 1
514fee23f9Smrg 
52*b1e83836Smrg #include <iosfwd>           	  // std::basic_ostream
534fee23f9Smrg #include <bits/shared_ptr_base.h>
544fee23f9Smrg 
_GLIBCXX_VISIBILITY(default)5548fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default)
5648fb7bfaSmrg {
5748fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
584fee23f9Smrg 
594fee23f9Smrg   /**
604fee23f9Smrg    * @addtogroup pointer_abstractions
614fee23f9Smrg    * @{
624fee23f9Smrg    */
634fee23f9Smrg 
64fb8a8121Smrg   // 20.7.2.2.11 shared_ptr I/O
65fb8a8121Smrg 
66fb8a8121Smrg   /// Write the stored pointer to an ostream.
67fb8a8121Smrg   /// @relates shared_ptr
684fee23f9Smrg   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
694fee23f9Smrg     inline std::basic_ostream<_Ch, _Tr>&
704fee23f9Smrg     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
714fee23f9Smrg 	       const __shared_ptr<_Tp, _Lp>& __p)
724fee23f9Smrg     {
734fee23f9Smrg       __os << __p.get();
744fee23f9Smrg       return __os;
754fee23f9Smrg     }
764fee23f9Smrg 
774fee23f9Smrg   template<typename _Del, typename _Tp, _Lock_policy _Lp>
784fee23f9Smrg     inline _Del*
7948fb7bfaSmrg     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
804fee23f9Smrg     {
814d5abbe8Smrg #if __cpp_rtti
824fee23f9Smrg       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
834fee23f9Smrg #else
844fee23f9Smrg       return 0;
854fee23f9Smrg #endif
864fee23f9Smrg     }
874fee23f9Smrg 
88a3e9eb18Smrg   /// 20.7.2.2.10 shared_ptr get_deleter
89fb8a8121Smrg 
90fb8a8121Smrg   /// If `__p` has a deleter of type `_Del`, return a pointer to it.
91fb8a8121Smrg   /// @relates shared_ptr
92a3e9eb18Smrg   template<typename _Del, typename _Tp>
93a3e9eb18Smrg     inline _Del*
94a3e9eb18Smrg     get_deleter(const shared_ptr<_Tp>& __p) noexcept
95a3e9eb18Smrg     {
96a3e9eb18Smrg #if __cpp_rtti
97a3e9eb18Smrg       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
98a3e9eb18Smrg #else
99a3e9eb18Smrg       return 0;
100a3e9eb18Smrg #endif
101a3e9eb18Smrg     }
1024fee23f9Smrg 
103*b1e83836Smrg   /// @cond undocumented
104*b1e83836Smrg 
105*b1e83836Smrg   // Constraint for overloads taking non-array types.
106*b1e83836Smrg #if __cpp_concepts && __cpp_lib_type_trait_variable_templates
107*b1e83836Smrg   template<typename _Tp>
108*b1e83836Smrg     requires (!is_array_v<_Tp>)
109*b1e83836Smrg     using _NonArray = _Tp;
110*b1e83836Smrg #else
111*b1e83836Smrg   template<typename _Tp>
112*b1e83836Smrg     using _NonArray = __enable_if_t<!is_array<_Tp>::value, _Tp>;
113*b1e83836Smrg #endif
114*b1e83836Smrg 
115*b1e83836Smrg #if __cpp_lib_shared_ptr_arrays >= 201707L
116*b1e83836Smrg   // Constraint for overloads taking array types with unknown bound, U[].
117*b1e83836Smrg #if __cpp_concepts
118*b1e83836Smrg   template<typename _Tp>
119*b1e83836Smrg     requires is_array_v<_Tp> && (extent_v<_Tp> == 0)
120*b1e83836Smrg     using _UnboundedArray = _Tp;
121*b1e83836Smrg #else
122*b1e83836Smrg   template<typename _Tp>
123*b1e83836Smrg     using _UnboundedArray
124*b1e83836Smrg       = __enable_if_t<__is_array_unknown_bounds<_Tp>::value, _Tp>;
125*b1e83836Smrg #endif
126*b1e83836Smrg 
127*b1e83836Smrg   // Constraint for overloads taking array types with known bound, U[N].
128*b1e83836Smrg #if __cpp_concepts
129*b1e83836Smrg   template<typename _Tp>
130*b1e83836Smrg     requires (extent_v<_Tp> != 0)
131*b1e83836Smrg     using _BoundedArray = _Tp;
132*b1e83836Smrg #else
133*b1e83836Smrg   template<typename _Tp>
134*b1e83836Smrg     using _BoundedArray
135*b1e83836Smrg       = __enable_if_t<__is_array_known_bounds<_Tp>::value, _Tp>;
136*b1e83836Smrg #endif
137*b1e83836Smrg 
138*b1e83836Smrg #if __cpp_lib_smart_ptr_for_overwrite
139*b1e83836Smrg   // Constraint for overloads taking either non-array or bounded array, U[N].
140*b1e83836Smrg #if __cpp_concepts
141*b1e83836Smrg   template<typename _Tp>
142*b1e83836Smrg     requires (!is_array_v<_Tp>) || (extent_v<_Tp> != 0)
143*b1e83836Smrg     using _NotUnboundedArray = _Tp;
144*b1e83836Smrg #else
145*b1e83836Smrg   template<typename _Tp>
146*b1e83836Smrg     using _NotUnboundedArray
147*b1e83836Smrg       = __enable_if_t<!__is_array_unknown_bounds<_Tp>::value, _Tp>;
148*b1e83836Smrg #endif
149*b1e83836Smrg #endif // smart_ptr_for_overwrite
150*b1e83836Smrg #endif // shared_ptr_arrays
151*b1e83836Smrg 
152*b1e83836Smrg   /// @endcond
153*b1e83836Smrg 
1544fee23f9Smrg   /**
1554fee23f9Smrg    *  @brief  A smart pointer with reference-counted copy semantics.
156*b1e83836Smrg    *  @headerfile memory
157*b1e83836Smrg    *  @since C++11
1584fee23f9Smrg    *
159fb8a8121Smrg    * A `shared_ptr` object is either empty or _owns_ a pointer passed
160fb8a8121Smrg    * to the constructor. Copies of a `shared_ptr` share ownership of
161fb8a8121Smrg    * the same pointer. When the last `shared_ptr` that owns the pointer
162fb8a8121Smrg    * is destroyed or reset, the owned pointer is freed (either by `delete`
163fb8a8121Smrg    * or by invoking a custom deleter that was passed to the constructor).
164fb8a8121Smrg    *
165fb8a8121Smrg    * A `shared_ptr` also stores another pointer, which is usually
166fb8a8121Smrg    * (but not always) the same pointer as it owns. The stored pointer
167fb8a8121Smrg    * can be retrieved by calling the `get()` member function.
168fb8a8121Smrg    *
169fb8a8121Smrg    * The equality and relational operators for `shared_ptr` only compare
170fb8a8121Smrg    * the stored pointer returned by `get()`, not the owned pointer.
171fb8a8121Smrg    * To test whether two `shared_ptr` objects share ownership of the same
172fb8a8121Smrg    * pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
1734fee23f9Smrg   */
1744fee23f9Smrg   template<typename _Tp>
1754fee23f9Smrg     class shared_ptr : public __shared_ptr<_Tp>
1764fee23f9Smrg     {
177b17d1066Smrg       template<typename... _Args>
178b17d1066Smrg 	using _Constructible = typename enable_if<
179b17d1066Smrg 	  is_constructible<__shared_ptr<_Tp>, _Args...>::value
180b17d1066Smrg 	>::type;
181b17d1066Smrg 
182b17d1066Smrg       template<typename _Arg>
183b17d1066Smrg 	using _Assignable = typename enable_if<
184b17d1066Smrg 	  is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
185b17d1066Smrg 	>::type;
1864d5abbe8Smrg 
1874fee23f9Smrg     public:
188b17d1066Smrg 
189fb8a8121Smrg       /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
190b17d1066Smrg       using element_type = typename __shared_ptr<_Tp>::element_type;
191b17d1066Smrg 
192fb8a8121Smrg #if __cplusplus >= 201703L
193*b1e83836Smrg # define __cpp_lib_shared_ptr_weak_type 201606L
194fb8a8121Smrg       /// The corresponding weak_ptr type for this shared_ptr
195*b1e83836Smrg       /// @since C++17
196b17d1066Smrg       using weak_type = weak_ptr<_Tp>;
197b17d1066Smrg #endif
1984fee23f9Smrg       /**
1994fee23f9Smrg        *  @brief  Construct an empty %shared_ptr.
2004fee23f9Smrg        *  @post   use_count()==0 && get()==0
2014fee23f9Smrg        */
202b17d1066Smrg       constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
20348fb7bfaSmrg 
204fb8a8121Smrg       shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
2054fee23f9Smrg 
2064fee23f9Smrg       /**
2074fee23f9Smrg        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
2084fee23f9Smrg        *  @param  __p  A pointer that is convertible to element_type*.
2094fee23f9Smrg        *  @post   use_count() == 1 && get() == __p
2104fee23f9Smrg        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
2114fee23f9Smrg        */
212b17d1066Smrg       template<typename _Yp, typename = _Constructible<_Yp*>>
213b17d1066Smrg 	explicit
214b17d1066Smrg 	shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
2154fee23f9Smrg 
2164fee23f9Smrg       /**
2174fee23f9Smrg        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
2184fee23f9Smrg        *          and the deleter @a __d.
2194fee23f9Smrg        *  @param  __p  A pointer.
2204fee23f9Smrg        *  @param  __d  A deleter.
2214fee23f9Smrg        *  @post   use_count() == 1 && get() == __p
2224fee23f9Smrg        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
2234fee23f9Smrg        *
2244fee23f9Smrg        *  Requirements: _Deleter's copy constructor and destructor must
2254fee23f9Smrg        *  not throw
2264fee23f9Smrg        *
2274fee23f9Smrg        *  __shared_ptr will release __p by calling __d(__p)
2284fee23f9Smrg        */
229b17d1066Smrg       template<typename _Yp, typename _Deleter,
230b17d1066Smrg 	       typename = _Constructible<_Yp*, _Deleter>>
231b17d1066Smrg 	shared_ptr(_Yp* __p, _Deleter __d)
232b17d1066Smrg         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
23348fb7bfaSmrg 
23448fb7bfaSmrg       /**
23548fb7bfaSmrg        *  @brief  Construct a %shared_ptr that owns a null pointer
23648fb7bfaSmrg        *          and the deleter @a __d.
23748fb7bfaSmrg        *  @param  __p  A null pointer constant.
23848fb7bfaSmrg        *  @param  __d  A deleter.
23948fb7bfaSmrg        *  @post   use_count() == 1 && get() == __p
24048fb7bfaSmrg        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
24148fb7bfaSmrg        *
24248fb7bfaSmrg        *  Requirements: _Deleter's copy constructor and destructor must
24348fb7bfaSmrg        *  not throw
24448fb7bfaSmrg        *
24548fb7bfaSmrg        *  The last owner will call __d(__p)
24648fb7bfaSmrg        */
24748fb7bfaSmrg       template<typename _Deleter>
24848fb7bfaSmrg 	shared_ptr(nullptr_t __p, _Deleter __d)
249b17d1066Smrg         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
2504fee23f9Smrg 
2514fee23f9Smrg       /**
2524fee23f9Smrg        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
2534fee23f9Smrg        *          and the deleter @a __d.
2544fee23f9Smrg        *  @param  __p  A pointer.
2554fee23f9Smrg        *  @param  __d  A deleter.
2564fee23f9Smrg        *  @param  __a  An allocator.
2574fee23f9Smrg        *  @post   use_count() == 1 && get() == __p
2584fee23f9Smrg        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
2594fee23f9Smrg        *
2604fee23f9Smrg        *  Requirements: _Deleter's copy constructor and destructor must
2614fee23f9Smrg        *  not throw _Alloc's copy constructor and destructor must not
2624fee23f9Smrg        *  throw.
2634fee23f9Smrg        *
2644fee23f9Smrg        *  __shared_ptr will release __p by calling __d(__p)
2654fee23f9Smrg        */
266b17d1066Smrg       template<typename _Yp, typename _Deleter, typename _Alloc,
267b17d1066Smrg 	       typename = _Constructible<_Yp*, _Deleter, _Alloc>>
268b17d1066Smrg 	shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
269b17d1066Smrg 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
27048fb7bfaSmrg 
27148fb7bfaSmrg       /**
27248fb7bfaSmrg        *  @brief  Construct a %shared_ptr that owns a null pointer
27348fb7bfaSmrg        *          and the deleter @a __d.
27448fb7bfaSmrg        *  @param  __p  A null pointer constant.
27548fb7bfaSmrg        *  @param  __d  A deleter.
27648fb7bfaSmrg        *  @param  __a  An allocator.
27748fb7bfaSmrg        *  @post   use_count() == 1 && get() == __p
27848fb7bfaSmrg        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
27948fb7bfaSmrg        *
28048fb7bfaSmrg        *  Requirements: _Deleter's copy constructor and destructor must
28148fb7bfaSmrg        *  not throw _Alloc's copy constructor and destructor must not
28248fb7bfaSmrg        *  throw.
28348fb7bfaSmrg        *
28448fb7bfaSmrg        *  The last owner will call __d(__p)
28548fb7bfaSmrg        */
28648fb7bfaSmrg       template<typename _Deleter, typename _Alloc>
28748fb7bfaSmrg 	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
288b17d1066Smrg 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
2894fee23f9Smrg 
2904fee23f9Smrg       // Aliasing constructor
2914fee23f9Smrg 
2924fee23f9Smrg       /**
293fb8a8121Smrg        *  @brief  Constructs a `shared_ptr` instance that stores `__p`
294fb8a8121Smrg        *          and shares ownership with `__r`.
295fb8a8121Smrg        *  @param  __r  A `shared_ptr`.
296fb8a8121Smrg        *  @param  __p  A pointer that will remain valid while `*__r` is valid.
297fb8a8121Smrg        *  @post   `get() == __p && use_count() == __r.use_count()`
2984fee23f9Smrg        *
299fb8a8121Smrg        *  This can be used to construct a `shared_ptr` to a sub-object
300fb8a8121Smrg        *  of an object managed by an existing `shared_ptr`. The complete
301fb8a8121Smrg        *  object will remain valid while any `shared_ptr` owns it, even
302fb8a8121Smrg        *  if they don't store a pointer to the complete object.
3034fee23f9Smrg        *
3044fee23f9Smrg        * @code
3054fee23f9Smrg        * shared_ptr<pair<int,int>> pii(new pair<int,int>());
3064fee23f9Smrg        * shared_ptr<int> pi(pii, &pii->first);
3074fee23f9Smrg        * assert(pii.use_count() == 2);
3084fee23f9Smrg        * @endcode
3094fee23f9Smrg        */
310b17d1066Smrg       template<typename _Yp>
311b17d1066Smrg 	shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
3124fee23f9Smrg 	: __shared_ptr<_Tp>(__r, __p) { }
3134fee23f9Smrg 
314fb8a8121Smrg #if __cplusplus > 201703L
315fb8a8121Smrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
316fb8a8121Smrg       // 2996. Missing rvalue overloads for shared_ptr operations
317fb8a8121Smrg       /**
318fb8a8121Smrg        *  @brief  Constructs a `shared_ptr` instance that stores `__p`
319fb8a8121Smrg        *          and shares ownership with `__r`.
320fb8a8121Smrg        *  @param  __r  A `shared_ptr`.
321fb8a8121Smrg        *  @param  __p  A pointer that will remain valid while `*__r` is valid.
322fb8a8121Smrg        *  @post   `get() == __p && !__r.use_count() && !__r.get()`
323*b1e83836Smrg        *  @since C++17
324fb8a8121Smrg        *
325fb8a8121Smrg        *  This can be used to construct a `shared_ptr` to a sub-object
326fb8a8121Smrg        *  of an object managed by an existing `shared_ptr`. The complete
327fb8a8121Smrg        *  object will remain valid while any `shared_ptr` owns it, even
328fb8a8121Smrg        *  if they don't store a pointer to the complete object.
329fb8a8121Smrg        *
330fb8a8121Smrg        * @code
331fb8a8121Smrg        * shared_ptr<pair<int,int>> pii(new pair<int,int>());
332fb8a8121Smrg        * shared_ptr<int> pi1(pii, &pii->first);
333fb8a8121Smrg        * assert(pii.use_count() == 2);
334fb8a8121Smrg        * shared_ptr<int> pi2(std::move(pii), &pii->second);
335fb8a8121Smrg        * assert(pii.use_count() == 0);
336fb8a8121Smrg        * @endcode
337fb8a8121Smrg        */
338fb8a8121Smrg       template<typename _Yp>
339fb8a8121Smrg 	shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
340fb8a8121Smrg 	: __shared_ptr<_Tp>(std::move(__r), __p) { }
341fb8a8121Smrg #endif
3424fee23f9Smrg       /**
3434fee23f9Smrg        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
3444fee23f9Smrg        *          otherwise construct a %shared_ptr that shares ownership
3454fee23f9Smrg        *          with @a __r.
3464fee23f9Smrg        *  @param  __r  A %shared_ptr.
3474fee23f9Smrg        *  @post   get() == __r.get() && use_count() == __r.use_count()
3484fee23f9Smrg        */
349b17d1066Smrg       template<typename _Yp,
350b17d1066Smrg 	       typename = _Constructible<const shared_ptr<_Yp>&>>
351b17d1066Smrg 	shared_ptr(const shared_ptr<_Yp>& __r) noexcept
35248fb7bfaSmrg         : __shared_ptr<_Tp>(__r) { }
3534fee23f9Smrg 
3544fee23f9Smrg       /**
3554fee23f9Smrg        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
3564fee23f9Smrg        *  @param  __r  A %shared_ptr rvalue.
3574fee23f9Smrg        *  @post   *this contains the old value of @a __r, @a __r is empty.
3584fee23f9Smrg        */
35948fb7bfaSmrg       shared_ptr(shared_ptr&& __r) noexcept
3604fee23f9Smrg       : __shared_ptr<_Tp>(std::move(__r)) { }
3614fee23f9Smrg 
3624fee23f9Smrg       /**
3634fee23f9Smrg        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
3644fee23f9Smrg        *  @param  __r  A %shared_ptr rvalue.
3654fee23f9Smrg        *  @post   *this contains the old value of @a __r, @a __r is empty.
3664fee23f9Smrg        */
367b17d1066Smrg       template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
368b17d1066Smrg 	shared_ptr(shared_ptr<_Yp>&& __r) noexcept
3694fee23f9Smrg 	: __shared_ptr<_Tp>(std::move(__r)) { }
3704fee23f9Smrg 
3714fee23f9Smrg       /**
3724fee23f9Smrg        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
3734fee23f9Smrg        *          and stores a copy of the pointer stored in @a __r.
3744fee23f9Smrg        *  @param  __r  A weak_ptr.
3754fee23f9Smrg        *  @post   use_count() == __r.use_count()
3764fee23f9Smrg        *  @throw  bad_weak_ptr when __r.expired(),
3774fee23f9Smrg        *          in which case the constructor has no effect.
3784fee23f9Smrg        */
379b17d1066Smrg       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
380b17d1066Smrg 	explicit shared_ptr(const weak_ptr<_Yp>& __r)
3814fee23f9Smrg 	: __shared_ptr<_Tp>(__r) { }
3824fee23f9Smrg 
38348fb7bfaSmrg #if _GLIBCXX_USE_DEPRECATED
384a3e9eb18Smrg #pragma GCC diagnostic push
385a3e9eb18Smrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
386b17d1066Smrg       template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
387b17d1066Smrg 	shared_ptr(auto_ptr<_Yp>&& __r);
388a3e9eb18Smrg #pragma GCC diagnostic pop
3894fee23f9Smrg #endif
3904fee23f9Smrg 
3914d5abbe8Smrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
3924d5abbe8Smrg       // 2399. shared_ptr's constructor from unique_ptr should be constrained
393b17d1066Smrg       template<typename _Yp, typename _Del,
394b17d1066Smrg 	       typename = _Constructible<unique_ptr<_Yp, _Del>>>
395b17d1066Smrg 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
3964fee23f9Smrg 	: __shared_ptr<_Tp>(std::move(__r)) { }
3974fee23f9Smrg 
398b17d1066Smrg #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
399b17d1066Smrg       // This non-standard constructor exists to support conversions that
400b17d1066Smrg       // were possible in C++11 and C++14 but are ill-formed in C++17.
401b17d1066Smrg       // If an exception is thrown this constructor has no effect.
402b17d1066Smrg       template<typename _Yp, typename _Del,
403b17d1066Smrg 		_Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
404b17d1066Smrg 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
405b17d1066Smrg 	: __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
406b17d1066Smrg #endif
407b17d1066Smrg 
40848fb7bfaSmrg       /**
40948fb7bfaSmrg        *  @brief  Construct an empty %shared_ptr.
41048fb7bfaSmrg        *  @post   use_count() == 0 && get() == nullptr
41148fb7bfaSmrg        */
4124d5abbe8Smrg       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
41348fb7bfaSmrg 
41448fb7bfaSmrg       shared_ptr& operator=(const shared_ptr&) noexcept = default;
41548fb7bfaSmrg 
416b17d1066Smrg       template<typename _Yp>
417b17d1066Smrg 	_Assignable<const shared_ptr<_Yp>&>
418b17d1066Smrg 	operator=(const shared_ptr<_Yp>& __r) noexcept
4194fee23f9Smrg 	{
4204fee23f9Smrg 	  this->__shared_ptr<_Tp>::operator=(__r);
4214fee23f9Smrg 	  return *this;
4224fee23f9Smrg 	}
4234fee23f9Smrg 
42448fb7bfaSmrg #if _GLIBCXX_USE_DEPRECATED
425a3e9eb18Smrg #pragma GCC diagnostic push
426a3e9eb18Smrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
427b17d1066Smrg       template<typename _Yp>
428b17d1066Smrg 	_Assignable<auto_ptr<_Yp>>
429b17d1066Smrg 	operator=(auto_ptr<_Yp>&& __r)
4304fee23f9Smrg 	{
4314fee23f9Smrg 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
4324fee23f9Smrg 	  return *this;
4334fee23f9Smrg 	}
434a3e9eb18Smrg #pragma GCC diagnostic pop
4354fee23f9Smrg #endif
4364fee23f9Smrg 
4374fee23f9Smrg       shared_ptr&
43848fb7bfaSmrg       operator=(shared_ptr&& __r) noexcept
4394fee23f9Smrg       {
4404fee23f9Smrg 	this->__shared_ptr<_Tp>::operator=(std::move(__r));
4414fee23f9Smrg 	return *this;
4424fee23f9Smrg       }
4434fee23f9Smrg 
444b17d1066Smrg       template<class _Yp>
445b17d1066Smrg 	_Assignable<shared_ptr<_Yp>>
446b17d1066Smrg 	operator=(shared_ptr<_Yp>&& __r) noexcept
4474fee23f9Smrg 	{
4484fee23f9Smrg 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
4494fee23f9Smrg 	  return *this;
4504fee23f9Smrg 	}
4514fee23f9Smrg 
452b17d1066Smrg       template<typename _Yp, typename _Del>
453b17d1066Smrg 	_Assignable<unique_ptr<_Yp, _Del>>
454b17d1066Smrg 	operator=(unique_ptr<_Yp, _Del>&& __r)
4554fee23f9Smrg 	{
4564fee23f9Smrg 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
4574fee23f9Smrg 	  return *this;
4584fee23f9Smrg 	}
4594fee23f9Smrg 
4604fee23f9Smrg     private:
4614fee23f9Smrg       // This constructor is non-standard, it is used by allocate_shared.
4624fee23f9Smrg       template<typename _Alloc, typename... _Args>
463a3e9eb18Smrg 	shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
464a3e9eb18Smrg 	: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
4654fee23f9Smrg 	{ }
4664fee23f9Smrg 
467b17d1066Smrg       template<typename _Yp, typename _Alloc, typename... _Args>
468*b1e83836Smrg 	friend shared_ptr<_NonArray<_Yp>>
469*b1e83836Smrg 	allocate_shared(const _Alloc&, _Args&&...);
470*b1e83836Smrg 
471*b1e83836Smrg       template<typename _Yp, typename... _Args>
472*b1e83836Smrg 	friend shared_ptr<_NonArray<_Yp>>
473*b1e83836Smrg 	make_shared(_Args&&...);
474*b1e83836Smrg 
475*b1e83836Smrg #if __cpp_lib_shared_ptr_arrays >= 201707L
476*b1e83836Smrg       // This constructor is non-standard, it is used by allocate_shared<T[]>.
477*b1e83836Smrg       template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>
478*b1e83836Smrg 	shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,
479*b1e83836Smrg 		   _Init __init = nullptr)
480*b1e83836Smrg 	: __shared_ptr<_Tp>(__a, __init)
481*b1e83836Smrg 	{ }
482*b1e83836Smrg 
483*b1e83836Smrg       template<typename _Yp, typename _Alloc>
484*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
485*b1e83836Smrg 	allocate_shared(const _Alloc&, size_t);
486*b1e83836Smrg 
487*b1e83836Smrg       template<typename _Yp>
488*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
489*b1e83836Smrg 	make_shared(size_t);
490*b1e83836Smrg 
491*b1e83836Smrg       template<typename _Yp, typename _Alloc>
492*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
493*b1e83836Smrg 	allocate_shared(const _Alloc&, size_t, const remove_extent_t<_Yp>&);
494*b1e83836Smrg 
495*b1e83836Smrg       template<typename _Yp>
496*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
497*b1e83836Smrg 	make_shared(size_t, const remove_extent_t<_Yp>&);
498*b1e83836Smrg 
499*b1e83836Smrg       template<typename _Yp, typename _Alloc>
500*b1e83836Smrg 	friend shared_ptr<_BoundedArray<_Yp>>
501*b1e83836Smrg 	allocate_shared(const _Alloc&);
502*b1e83836Smrg 
503*b1e83836Smrg       template<typename _Yp>
504*b1e83836Smrg 	friend shared_ptr<_BoundedArray<_Yp>>
505*b1e83836Smrg 	make_shared();
506*b1e83836Smrg 
507*b1e83836Smrg       template<typename _Yp, typename _Alloc>
508*b1e83836Smrg 	friend shared_ptr<_BoundedArray<_Yp>>
509*b1e83836Smrg 	allocate_shared(const _Alloc&, const remove_extent_t<_Yp>&);
510*b1e83836Smrg 
511*b1e83836Smrg       template<typename _Yp>
512*b1e83836Smrg 	friend shared_ptr<_BoundedArray<_Yp>>
513*b1e83836Smrg 	make_shared(const remove_extent_t<_Yp>&);
514*b1e83836Smrg 
515*b1e83836Smrg #if __cpp_lib_smart_ptr_for_overwrite
516*b1e83836Smrg       template<typename _Yp, typename _Alloc>
517*b1e83836Smrg 	friend shared_ptr<_NotUnboundedArray<_Yp>>
518*b1e83836Smrg 	allocate_shared_for_overwrite(const _Alloc&);
519*b1e83836Smrg 
520*b1e83836Smrg       template<typename _Yp>
521*b1e83836Smrg 	friend shared_ptr<_NotUnboundedArray<_Yp>>
522*b1e83836Smrg 	make_shared_for_overwrite();
523*b1e83836Smrg 
524*b1e83836Smrg       template<typename _Yp, typename _Alloc>
525*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
526*b1e83836Smrg 	allocate_shared_for_overwrite(const _Alloc&, size_t);
527*b1e83836Smrg 
528*b1e83836Smrg       template<typename _Yp>
529*b1e83836Smrg 	friend shared_ptr<_UnboundedArray<_Yp>>
530*b1e83836Smrg 	make_shared_for_overwrite(size_t);
531*b1e83836Smrg #endif
532*b1e83836Smrg #endif
5334d5abbe8Smrg 
5344d5abbe8Smrg       // This constructor is non-standard, it is used by weak_ptr::lock().
535*b1e83836Smrg       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
5364d5abbe8Smrg       : __shared_ptr<_Tp>(__r, std::nothrow) { }
5374d5abbe8Smrg 
5384d5abbe8Smrg       friend class weak_ptr<_Tp>;
5394fee23f9Smrg     };
5404fee23f9Smrg 
541b17d1066Smrg #if __cpp_deduction_guides >= 201606
542b17d1066Smrg   template<typename _Tp>
543b17d1066Smrg     shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;
544b17d1066Smrg   template<typename _Tp, typename _Del>
545b17d1066Smrg     shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;
546b17d1066Smrg #endif
547b17d1066Smrg 
54848fb7bfaSmrg   // 20.7.2.2.7 shared_ptr comparisons
549fb8a8121Smrg 
550fb8a8121Smrg   /// @relates shared_ptr @{
551fb8a8121Smrg 
552fb8a8121Smrg   /// Equality operator for shared_ptr objects, compares the stored pointers
553b17d1066Smrg   template<typename _Tp, typename _Up>
554181254a7Smrg     _GLIBCXX_NODISCARD inline bool
555b17d1066Smrg     operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
5564fee23f9Smrg     { return __a.get() == __b.get(); }
5574fee23f9Smrg 
558fb8a8121Smrg   /// shared_ptr comparison with nullptr
55948fb7bfaSmrg   template<typename _Tp>
560181254a7Smrg     _GLIBCXX_NODISCARD inline bool
56148fb7bfaSmrg     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
56248fb7bfaSmrg     { return !__a; }
56348fb7bfaSmrg 
564fb8a8121Smrg #ifdef __cpp_lib_three_way_comparison
565fb8a8121Smrg   template<typename _Tp, typename _Up>
566fb8a8121Smrg     inline strong_ordering
567fb8a8121Smrg     operator<=>(const shared_ptr<_Tp>& __a,
568fb8a8121Smrg 		const shared_ptr<_Up>& __b) noexcept
569fb8a8121Smrg     { return compare_three_way()(__a.get(), __b.get()); }
570fb8a8121Smrg 
571fb8a8121Smrg   template<typename _Tp>
572fb8a8121Smrg     inline strong_ordering
573fb8a8121Smrg     operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
574fb8a8121Smrg     {
575fb8a8121Smrg       using pointer = typename shared_ptr<_Tp>::element_type*;
576fb8a8121Smrg       return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
577fb8a8121Smrg     }
578fb8a8121Smrg #else
579fb8a8121Smrg   /// shared_ptr comparison with nullptr
58048fb7bfaSmrg   template<typename _Tp>
581181254a7Smrg     _GLIBCXX_NODISCARD inline bool
58248fb7bfaSmrg     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
58348fb7bfaSmrg     { return !__a; }
5844fee23f9Smrg 
585fb8a8121Smrg   /// Inequality operator for shared_ptr objects, compares the stored pointers
586b17d1066Smrg   template<typename _Tp, typename _Up>
587181254a7Smrg     _GLIBCXX_NODISCARD inline bool
588b17d1066Smrg     operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
58948fb7bfaSmrg     { return __a.get() != __b.get(); }
59048fb7bfaSmrg 
591fb8a8121Smrg   /// shared_ptr comparison with nullptr
59248fb7bfaSmrg   template<typename _Tp>
593181254a7Smrg     _GLIBCXX_NODISCARD inline bool
59448fb7bfaSmrg     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
59548fb7bfaSmrg     { return (bool)__a; }
59648fb7bfaSmrg 
597fb8a8121Smrg   /// shared_ptr comparison with nullptr
59848fb7bfaSmrg   template<typename _Tp>
599181254a7Smrg     _GLIBCXX_NODISCARD inline bool
60048fb7bfaSmrg     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
60148fb7bfaSmrg     { return (bool)__a; }
60248fb7bfaSmrg 
603fb8a8121Smrg   /// Relational operator for shared_ptr objects, compares the stored pointers
604b17d1066Smrg   template<typename _Tp, typename _Up>
605181254a7Smrg     _GLIBCXX_NODISCARD inline bool
606b17d1066Smrg     operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
60748fb7bfaSmrg     {
608b17d1066Smrg       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
609b17d1066Smrg       using _Up_elt = typename shared_ptr<_Up>::element_type;
610b17d1066Smrg       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
611b17d1066Smrg       return less<_Vp>()(__a.get(), __b.get());
61248fb7bfaSmrg     }
61348fb7bfaSmrg 
614fb8a8121Smrg   /// shared_ptr comparison with nullptr
61548fb7bfaSmrg   template<typename _Tp>
616181254a7Smrg     _GLIBCXX_NODISCARD inline bool
61748fb7bfaSmrg     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
618b17d1066Smrg     {
619b17d1066Smrg       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
620b17d1066Smrg       return less<_Tp_elt*>()(__a.get(), nullptr);
621b17d1066Smrg     }
62248fb7bfaSmrg 
623fb8a8121Smrg   /// shared_ptr comparison with nullptr
62448fb7bfaSmrg   template<typename _Tp>
625181254a7Smrg     _GLIBCXX_NODISCARD inline bool
62648fb7bfaSmrg     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
627b17d1066Smrg     {
628b17d1066Smrg       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
629b17d1066Smrg       return less<_Tp_elt*>()(nullptr, __a.get());
630b17d1066Smrg     }
63148fb7bfaSmrg 
632fb8a8121Smrg   /// Relational operator for shared_ptr objects, compares the stored pointers
633b17d1066Smrg   template<typename _Tp, typename _Up>
634181254a7Smrg     _GLIBCXX_NODISCARD inline bool
635b17d1066Smrg     operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
63648fb7bfaSmrg     { return !(__b < __a); }
63748fb7bfaSmrg 
638fb8a8121Smrg   /// shared_ptr comparison with nullptr
63948fb7bfaSmrg   template<typename _Tp>
640181254a7Smrg     _GLIBCXX_NODISCARD inline bool
64148fb7bfaSmrg     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
64248fb7bfaSmrg     { return !(nullptr < __a); }
64348fb7bfaSmrg 
644fb8a8121Smrg   /// shared_ptr comparison with nullptr
64548fb7bfaSmrg   template<typename _Tp>
646181254a7Smrg     _GLIBCXX_NODISCARD inline bool
64748fb7bfaSmrg     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
64848fb7bfaSmrg     { return !(__a < nullptr); }
64948fb7bfaSmrg 
650fb8a8121Smrg   /// Relational operator for shared_ptr objects, compares the stored pointers
651b17d1066Smrg   template<typename _Tp, typename _Up>
652181254a7Smrg     _GLIBCXX_NODISCARD inline bool
653b17d1066Smrg     operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
65448fb7bfaSmrg     { return (__b < __a); }
65548fb7bfaSmrg 
656fb8a8121Smrg   /// shared_ptr comparison with nullptr
65748fb7bfaSmrg   template<typename _Tp>
658181254a7Smrg     _GLIBCXX_NODISCARD inline bool
65948fb7bfaSmrg     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
660b17d1066Smrg     { return nullptr < __a; }
66148fb7bfaSmrg 
662fb8a8121Smrg   /// shared_ptr comparison with nullptr
66348fb7bfaSmrg   template<typename _Tp>
664181254a7Smrg     _GLIBCXX_NODISCARD inline bool
66548fb7bfaSmrg     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
666b17d1066Smrg     { return __a < nullptr; }
66748fb7bfaSmrg 
668fb8a8121Smrg   /// Relational operator for shared_ptr objects, compares the stored pointers
669b17d1066Smrg   template<typename _Tp, typename _Up>
670181254a7Smrg     _GLIBCXX_NODISCARD inline bool
671b17d1066Smrg     operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
67248fb7bfaSmrg     { return !(__a < __b); }
67348fb7bfaSmrg 
674fb8a8121Smrg   /// shared_ptr comparison with nullptr
67548fb7bfaSmrg   template<typename _Tp>
676181254a7Smrg     _GLIBCXX_NODISCARD inline bool
67748fb7bfaSmrg     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
67848fb7bfaSmrg     { return !(__a < nullptr); }
67948fb7bfaSmrg 
680fb8a8121Smrg   /// shared_ptr comparison with nullptr
68148fb7bfaSmrg   template<typename _Tp>
682181254a7Smrg     _GLIBCXX_NODISCARD inline bool
68348fb7bfaSmrg     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
68448fb7bfaSmrg     { return !(nullptr < __a); }
685fb8a8121Smrg #endif
6864fee23f9Smrg 
68748fb7bfaSmrg   // 20.7.2.2.8 shared_ptr specialized algorithms.
688fb8a8121Smrg 
689fb8a8121Smrg   /// Swap overload for shared_ptr
6904fee23f9Smrg   template<typename _Tp>
6914fee23f9Smrg     inline void
69248fb7bfaSmrg     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
6934fee23f9Smrg     { __a.swap(__b); }
6944fee23f9Smrg 
69548fb7bfaSmrg   // 20.7.2.2.9 shared_ptr casts.
696fb8a8121Smrg 
697fb8a8121Smrg   /// Convert type of `shared_ptr`, via `static_cast`
698b17d1066Smrg   template<typename _Tp, typename _Up>
6994fee23f9Smrg     inline shared_ptr<_Tp>
700b17d1066Smrg     static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
7014fee23f9Smrg     {
702b17d1066Smrg       using _Sp = shared_ptr<_Tp>;
703b17d1066Smrg       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
7044fee23f9Smrg     }
7054fee23f9Smrg 
706fb8a8121Smrg   /// Convert type of `shared_ptr`, via `const_cast`
707b17d1066Smrg   template<typename _Tp, typename _Up>
708b17d1066Smrg     inline shared_ptr<_Tp>
709b17d1066Smrg     const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
710b17d1066Smrg     {
711b17d1066Smrg       using _Sp = shared_ptr<_Tp>;
712b17d1066Smrg       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
713b17d1066Smrg     }
714b17d1066Smrg 
715fb8a8121Smrg   /// Convert type of `shared_ptr`, via `dynamic_cast`
716b17d1066Smrg   template<typename _Tp, typename _Up>
717b17d1066Smrg     inline shared_ptr<_Tp>
718b17d1066Smrg     dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
719b17d1066Smrg     {
720b17d1066Smrg       using _Sp = shared_ptr<_Tp>;
721b17d1066Smrg       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
722b17d1066Smrg 	return _Sp(__r, __p);
723b17d1066Smrg       return _Sp();
724b17d1066Smrg     }
725b17d1066Smrg 
726fb8a8121Smrg #if __cplusplus >= 201703L
727fb8a8121Smrg   /// Convert type of `shared_ptr`, via `reinterpret_cast`
728*b1e83836Smrg   /// @since C++17
729b17d1066Smrg   template<typename _Tp, typename _Up>
730b17d1066Smrg     inline shared_ptr<_Tp>
731b17d1066Smrg     reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
732b17d1066Smrg     {
733b17d1066Smrg       using _Sp = shared_ptr<_Tp>;
734b17d1066Smrg       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
735b17d1066Smrg     }
736fb8a8121Smrg 
737fb8a8121Smrg #if __cplusplus > 201703L
738fb8a8121Smrg   // _GLIBCXX_RESOLVE_LIB_DEFECTS
739fb8a8121Smrg   // 2996. Missing rvalue overloads for shared_ptr operations
740fb8a8121Smrg 
741fb8a8121Smrg   /// Convert type of `shared_ptr` rvalue, via `static_cast`
742*b1e83836Smrg   /// @since C++20
743fb8a8121Smrg   template<typename _Tp, typename _Up>
744fb8a8121Smrg     inline shared_ptr<_Tp>
745fb8a8121Smrg     static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
746fb8a8121Smrg     {
747fb8a8121Smrg       using _Sp = shared_ptr<_Tp>;
748fb8a8121Smrg       return _Sp(std::move(__r),
749fb8a8121Smrg 		 static_cast<typename _Sp::element_type*>(__r.get()));
750fb8a8121Smrg     }
751fb8a8121Smrg 
752fb8a8121Smrg   /// Convert type of `shared_ptr` rvalue, via `const_cast`
753*b1e83836Smrg   /// @since C++20
754fb8a8121Smrg   template<typename _Tp, typename _Up>
755fb8a8121Smrg     inline shared_ptr<_Tp>
756fb8a8121Smrg     const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
757fb8a8121Smrg     {
758fb8a8121Smrg       using _Sp = shared_ptr<_Tp>;
759fb8a8121Smrg       return _Sp(std::move(__r),
760fb8a8121Smrg 		 const_cast<typename _Sp::element_type*>(__r.get()));
761fb8a8121Smrg     }
762fb8a8121Smrg 
763fb8a8121Smrg   /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
764*b1e83836Smrg   /// @since C++20
765fb8a8121Smrg   template<typename _Tp, typename _Up>
766fb8a8121Smrg     inline shared_ptr<_Tp>
767fb8a8121Smrg     dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
768fb8a8121Smrg     {
769fb8a8121Smrg       using _Sp = shared_ptr<_Tp>;
770fb8a8121Smrg       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
771fb8a8121Smrg 	return _Sp(std::move(__r), __p);
772fb8a8121Smrg       return _Sp();
773fb8a8121Smrg     }
774fb8a8121Smrg 
775fb8a8121Smrg   /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
776*b1e83836Smrg   /// @since C++20
777fb8a8121Smrg   template<typename _Tp, typename _Up>
778fb8a8121Smrg     inline shared_ptr<_Tp>
779fb8a8121Smrg     reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
780fb8a8121Smrg     {
781fb8a8121Smrg       using _Sp = shared_ptr<_Tp>;
782fb8a8121Smrg       return _Sp(std::move(__r),
783fb8a8121Smrg 		 reinterpret_cast<typename _Sp::element_type*>(__r.get()));
784fb8a8121Smrg     }
785fb8a8121Smrg #endif // C++20
786fb8a8121Smrg #endif // C++17
787fb8a8121Smrg 
788a448f87cSmrg   /// @}
7894fee23f9Smrg 
7904fee23f9Smrg   /**
791fb8a8121Smrg    * @brief  A non-owning observer for a pointer owned by a shared_ptr
792*b1e83836Smrg    * @headerfile memory
793*b1e83836Smrg    * @since C++11
7944fee23f9Smrg    *
795fb8a8121Smrg    * A weak_ptr provides a safe alternative to a raw pointer when you want
796fb8a8121Smrg    * a non-owning reference to an object that is managed by a shared_ptr.
797fb8a8121Smrg    *
798fb8a8121Smrg    * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
799fb8a8121Smrg    * that shares ownership with every other shared_ptr that already owns
800fb8a8121Smrg    * the pointer. In other words you can upgrade from a non-owning "weak"
801fb8a8121Smrg    * reference to an owning shared_ptr, without having access to any of
802fb8a8121Smrg    * the existing shared_ptr objects.
803fb8a8121Smrg    *
804fb8a8121Smrg    * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
805fb8a8121Smrg    * the object it points to has been destroyed. Instead, a weak_ptr
806fb8a8121Smrg    * becomes _expired_ and can no longer be converted to a shared_ptr that
807fb8a8121Smrg    * owns the freed pointer, so you cannot accidentally access the pointed-to
808fb8a8121Smrg    * object after it has been destroyed.
8094fee23f9Smrg    */
8104fee23f9Smrg   template<typename _Tp>
8114fee23f9Smrg     class weak_ptr : public __weak_ptr<_Tp>
8124fee23f9Smrg     {
813b17d1066Smrg       template<typename _Arg>
814b17d1066Smrg 	using _Constructible = typename enable_if<
815b17d1066Smrg 	  is_constructible<__weak_ptr<_Tp>, _Arg>::value
816b17d1066Smrg 	>::type;
817b17d1066Smrg 
818b17d1066Smrg       template<typename _Arg>
819b17d1066Smrg 	using _Assignable = typename enable_if<
820b17d1066Smrg 	  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
821b17d1066Smrg 	>::type;
8224fee23f9Smrg 
8234d5abbe8Smrg     public:
8244d5abbe8Smrg       constexpr weak_ptr() noexcept = default;
8254d5abbe8Smrg 
826b17d1066Smrg       template<typename _Yp,
827b17d1066Smrg 	       typename = _Constructible<const shared_ptr<_Yp>&>>
828b17d1066Smrg 	weak_ptr(const shared_ptr<_Yp>& __r) noexcept
8294d5abbe8Smrg 	: __weak_ptr<_Tp>(__r) { }
8304d5abbe8Smrg 
8314d5abbe8Smrg       weak_ptr(const weak_ptr&) noexcept = default;
8324d5abbe8Smrg 
833b17d1066Smrg       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
834b17d1066Smrg 	weak_ptr(const weak_ptr<_Yp>& __r) noexcept
8354fee23f9Smrg 	: __weak_ptr<_Tp>(__r) { }
8364fee23f9Smrg 
8374d5abbe8Smrg       weak_ptr(weak_ptr&&) noexcept = default;
8384d5abbe8Smrg 
839b17d1066Smrg       template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
840b17d1066Smrg 	weak_ptr(weak_ptr<_Yp>&& __r) noexcept
8414d5abbe8Smrg 	: __weak_ptr<_Tp>(std::move(__r)) { }
8424d5abbe8Smrg 
8434d5abbe8Smrg       weak_ptr&
8444d5abbe8Smrg       operator=(const weak_ptr& __r) noexcept = default;
8454fee23f9Smrg 
846b17d1066Smrg       template<typename _Yp>
847b17d1066Smrg 	_Assignable<const weak_ptr<_Yp>&>
848b17d1066Smrg 	operator=(const weak_ptr<_Yp>& __r) noexcept
8494fee23f9Smrg 	{
8504fee23f9Smrg 	  this->__weak_ptr<_Tp>::operator=(__r);
8514fee23f9Smrg 	  return *this;
8524fee23f9Smrg 	}
8534fee23f9Smrg 
854b17d1066Smrg       template<typename _Yp>
855b17d1066Smrg 	_Assignable<const shared_ptr<_Yp>&>
856b17d1066Smrg 	operator=(const shared_ptr<_Yp>& __r) noexcept
8574fee23f9Smrg 	{
8584fee23f9Smrg 	  this->__weak_ptr<_Tp>::operator=(__r);
8594fee23f9Smrg 	  return *this;
8604fee23f9Smrg 	}
8614fee23f9Smrg 
8624d5abbe8Smrg       weak_ptr&
8634d5abbe8Smrg       operator=(weak_ptr&& __r) noexcept = default;
8644d5abbe8Smrg 
865b17d1066Smrg       template<typename _Yp>
866b17d1066Smrg 	_Assignable<weak_ptr<_Yp>>
867b17d1066Smrg 	operator=(weak_ptr<_Yp>&& __r) noexcept
8684d5abbe8Smrg 	{
8694d5abbe8Smrg 	  this->__weak_ptr<_Tp>::operator=(std::move(__r));
8704d5abbe8Smrg 	  return *this;
8714d5abbe8Smrg 	}
8724d5abbe8Smrg 
8734fee23f9Smrg       shared_ptr<_Tp>
87448fb7bfaSmrg       lock() const noexcept
8754d5abbe8Smrg       { return shared_ptr<_Tp>(*this, std::nothrow); }
8764fee23f9Smrg     };
8774fee23f9Smrg 
878b17d1066Smrg #if __cpp_deduction_guides >= 201606
879b17d1066Smrg   template<typename _Tp>
880b17d1066Smrg     weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;
881b17d1066Smrg #endif
882b17d1066Smrg 
88348fb7bfaSmrg   // 20.7.2.3.6 weak_ptr specialized algorithms.
884fb8a8121Smrg   /// Swap overload for weak_ptr
885fb8a8121Smrg   /// @relates weak_ptr
8864fee23f9Smrg   template<typename _Tp>
8874fee23f9Smrg     inline void
88848fb7bfaSmrg     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
8894fee23f9Smrg     { __a.swap(__b); }
8904fee23f9Smrg 
8914fee23f9Smrg 
8924fee23f9Smrg   /// Primary template owner_less
893b17d1066Smrg   template<typename _Tp = void>
8944fee23f9Smrg     struct owner_less;
8954fee23f9Smrg 
896fb8a8121Smrg   /// Void specialization of owner_less compares either shared_ptr or weak_ptr
897b17d1066Smrg   template<>
898b17d1066Smrg     struct owner_less<void> : _Sp_owner_less<void, void>
899b17d1066Smrg     { };
900b17d1066Smrg 
9014fee23f9Smrg   /// Partial specialization of owner_less for shared_ptr.
9024fee23f9Smrg   template<typename _Tp>
9034fee23f9Smrg     struct owner_less<shared_ptr<_Tp>>
9044fee23f9Smrg     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
9054fee23f9Smrg     { };
9064fee23f9Smrg 
9074fee23f9Smrg   /// Partial specialization of owner_less for weak_ptr.
9084fee23f9Smrg   template<typename _Tp>
9094fee23f9Smrg     struct owner_less<weak_ptr<_Tp>>
9104fee23f9Smrg     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
9114fee23f9Smrg     { };
9124fee23f9Smrg 
9134fee23f9Smrg   /**
914*b1e83836Smrg    * @brief Base class allowing use of the member function `shared_from_this`.
915*b1e83836Smrg    * @headerfile memory
916*b1e83836Smrg    * @since C++11
9174fee23f9Smrg    */
9184fee23f9Smrg   template<typename _Tp>
9194fee23f9Smrg     class enable_shared_from_this
9204fee23f9Smrg     {
9214fee23f9Smrg     protected:
92248fb7bfaSmrg       constexpr enable_shared_from_this() noexcept { }
9234fee23f9Smrg 
92448fb7bfaSmrg       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
9254fee23f9Smrg 
9264fee23f9Smrg       enable_shared_from_this&
92748fb7bfaSmrg       operator=(const enable_shared_from_this&) noexcept
9284fee23f9Smrg       { return *this; }
9294fee23f9Smrg 
9304fee23f9Smrg       ~enable_shared_from_this() { }
9314fee23f9Smrg 
9324fee23f9Smrg     public:
9334fee23f9Smrg       shared_ptr<_Tp>
9344fee23f9Smrg       shared_from_this()
9354fee23f9Smrg       { return shared_ptr<_Tp>(this->_M_weak_this); }
9364fee23f9Smrg 
9374fee23f9Smrg       shared_ptr<const _Tp>
9384fee23f9Smrg       shared_from_this() const
9394fee23f9Smrg       { return shared_ptr<const _Tp>(this->_M_weak_this); }
9404fee23f9Smrg 
941b17d1066Smrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
942*b1e83836Smrg #define __cpp_lib_enable_shared_from_this 201603L
943*b1e83836Smrg       /** @{
944*b1e83836Smrg        * Get a `weak_ptr` referring to the object that has `*this` as its base.
945*b1e83836Smrg        * @since C++17
946*b1e83836Smrg        */
947b17d1066Smrg       weak_ptr<_Tp>
948b17d1066Smrg       weak_from_this() noexcept
949b17d1066Smrg       { return this->_M_weak_this; }
950b17d1066Smrg 
951b17d1066Smrg       weak_ptr<const _Tp>
952b17d1066Smrg       weak_from_this() const noexcept
953b17d1066Smrg       { return this->_M_weak_this; }
954*b1e83836Smrg       /// @}
955b17d1066Smrg #endif
956b17d1066Smrg 
9574fee23f9Smrg     private:
9584fee23f9Smrg       template<typename _Tp1>
9594fee23f9Smrg 	void
96048fb7bfaSmrg 	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
9614fee23f9Smrg 	{ _M_weak_this._M_assign(__p, __n); }
9624fee23f9Smrg 
963b17d1066Smrg       // Found by ADL when this is an associated class.
964b17d1066Smrg       friend const enable_shared_from_this*
965b17d1066Smrg       __enable_shared_from_this_base(const __shared_count<>&,
966b17d1066Smrg 				     const enable_shared_from_this* __p)
967b17d1066Smrg       { return __p; }
968b17d1066Smrg 
969b17d1066Smrg       template<typename, _Lock_policy>
970b17d1066Smrg 	friend class __shared_ptr;
9714fee23f9Smrg 
9724fee23f9Smrg       mutable weak_ptr<_Tp>  _M_weak_this;
9734fee23f9Smrg     };
9744fee23f9Smrg 
975fb8a8121Smrg   /// @relates shared_ptr @{
976fb8a8121Smrg 
9774fee23f9Smrg   /**
9784fee23f9Smrg    *  @brief  Create an object that is owned by a shared_ptr.
9794fee23f9Smrg    *  @param  __a     An allocator.
9804fee23f9Smrg    *  @param  __args  Arguments for the @a _Tp object's constructor.
9814fee23f9Smrg    *  @return A shared_ptr that owns the newly created object.
9824fee23f9Smrg    *  @throw  An exception thrown from @a _Alloc::allocate or from the
9834fee23f9Smrg    *          constructor of @a _Tp.
9844fee23f9Smrg    *
9854fee23f9Smrg    *  A copy of @a __a will be used to allocate memory for the shared_ptr
9864fee23f9Smrg    *  and the new object.
9874fee23f9Smrg    */
9884fee23f9Smrg   template<typename _Tp, typename _Alloc, typename... _Args>
989*b1e83836Smrg     inline shared_ptr<_NonArray<_Tp>>
99048fb7bfaSmrg     allocate_shared(const _Alloc& __a, _Args&&... __args)
9914fee23f9Smrg     {
992a3e9eb18Smrg       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
9934fee23f9Smrg 			     std::forward<_Args>(__args)...);
9944fee23f9Smrg     }
9954fee23f9Smrg 
9964fee23f9Smrg   /**
9974fee23f9Smrg    *  @brief  Create an object that is owned by a shared_ptr.
9984fee23f9Smrg    *  @param  __args  Arguments for the @a _Tp object's constructor.
9994fee23f9Smrg    *  @return A shared_ptr that owns the newly created object.
10004fee23f9Smrg    *  @throw  std::bad_alloc, or an exception thrown from the
10014fee23f9Smrg    *          constructor of @a _Tp.
10024fee23f9Smrg    */
10034fee23f9Smrg   template<typename _Tp, typename... _Args>
1004*b1e83836Smrg     inline shared_ptr<_NonArray<_Tp>>
10054fee23f9Smrg     make_shared(_Args&&... __args)
10064fee23f9Smrg     {
1007*b1e83836Smrg       using _Alloc = allocator<void>;
1008*b1e83836Smrg       _Alloc __a;
1009*b1e83836Smrg       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
10104fee23f9Smrg 			     std::forward<_Args>(__args)...);
10114fee23f9Smrg     }
10124fee23f9Smrg 
1013*b1e83836Smrg #if __cpp_lib_shared_ptr_arrays >= 201707L
1014*b1e83836Smrg   /// @cond undocumented
1015*b1e83836Smrg   template<typename _Tp, typename _Alloc = allocator<void>>
1016*b1e83836Smrg     auto
1017*b1e83836Smrg     __make_shared_arr_tag(size_t __n, const _Alloc& __a = _Alloc()) noexcept
1018*b1e83836Smrg     {
1019*b1e83836Smrg       using _Up = remove_all_extents_t<_Tp>;
1020*b1e83836Smrg       using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1021*b1e83836Smrg       size_t __s = sizeof(remove_extent_t<_Tp>) / sizeof(_Up);
1022*b1e83836Smrg       if (__builtin_mul_overflow(__s, __n, &__n))
1023*b1e83836Smrg 	std::__throw_bad_array_new_length();
1024*b1e83836Smrg       return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1025*b1e83836Smrg     }
1026*b1e83836Smrg   /// @endcond
1027*b1e83836Smrg 
1028*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1029*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1030*b1e83836Smrg     allocate_shared(const _Alloc& __a, size_t __n)
1031*b1e83836Smrg     {
1032*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a));
1033*b1e83836Smrg     }
1034*b1e83836Smrg 
1035*b1e83836Smrg   template<typename _Tp>
1036*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1037*b1e83836Smrg     make_shared(size_t __n)
1038*b1e83836Smrg     {
1039*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n));
1040*b1e83836Smrg     }
1041*b1e83836Smrg 
1042*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1043*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1044*b1e83836Smrg     allocate_shared(const _Alloc& __a, size_t __n,
1045*b1e83836Smrg 		    const remove_extent_t<_Tp>& __u)
1046*b1e83836Smrg     {
1047*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1048*b1e83836Smrg 			     std::__addressof(__u));
1049*b1e83836Smrg     }
1050*b1e83836Smrg 
1051*b1e83836Smrg   template<typename _Tp>
1052*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1053*b1e83836Smrg     make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
1054*b1e83836Smrg     {
1055*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1056*b1e83836Smrg 			     std::__addressof(__u));
1057*b1e83836Smrg     }
1058*b1e83836Smrg 
1059*b1e83836Smrg   /// @cond undocumented
1060*b1e83836Smrg   template<typename _Tp, typename _Alloc = allocator<void>>
1061*b1e83836Smrg     auto
1062*b1e83836Smrg     __make_shared_arrN_tag(const _Alloc& __a = _Alloc()) noexcept
1063*b1e83836Smrg     {
1064*b1e83836Smrg       using _Up = remove_all_extents_t<_Tp>;
1065*b1e83836Smrg       using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1066*b1e83836Smrg       size_t __n = sizeof(_Tp) / sizeof(_Up);
1067*b1e83836Smrg       return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1068*b1e83836Smrg     }
1069*b1e83836Smrg   /// @endcond
1070*b1e83836Smrg 
1071*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1072*b1e83836Smrg     inline shared_ptr<_BoundedArray<_Tp>>
1073*b1e83836Smrg     allocate_shared(const _Alloc& __a)
1074*b1e83836Smrg     {
1075*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a));
1076*b1e83836Smrg     }
1077*b1e83836Smrg 
1078*b1e83836Smrg   template<typename _Tp>
1079*b1e83836Smrg     inline shared_ptr<_BoundedArray<_Tp>>
1080*b1e83836Smrg     make_shared()
1081*b1e83836Smrg     {
1082*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>());
1083*b1e83836Smrg     }
1084*b1e83836Smrg 
1085*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1086*b1e83836Smrg     inline shared_ptr<_BoundedArray<_Tp>>
1087*b1e83836Smrg     allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u)
1088*b1e83836Smrg     {
1089*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1090*b1e83836Smrg 			     std::__addressof(__u));
1091*b1e83836Smrg     }
1092*b1e83836Smrg 
1093*b1e83836Smrg   template<typename _Tp>
1094*b1e83836Smrg     inline shared_ptr<_BoundedArray<_Tp>>
1095*b1e83836Smrg     make_shared(const remove_extent_t<_Tp>& __u)
1096*b1e83836Smrg     {
1097*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1098*b1e83836Smrg 			     std::__addressof(__u));
1099*b1e83836Smrg     }
1100*b1e83836Smrg 
1101*b1e83836Smrg #if __cpp_lib_smart_ptr_for_overwrite
1102*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1103*b1e83836Smrg     inline shared_ptr<_NotUnboundedArray<_Tp>>
1104*b1e83836Smrg     allocate_shared_for_overwrite(const _Alloc& __a)
1105*b1e83836Smrg     {
1106*b1e83836Smrg       if constexpr (is_array_v<_Tp>)
1107*b1e83836Smrg 	return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1108*b1e83836Smrg 			       _Sp_overwrite_tag{});
1109*b1e83836Smrg       else
1110*b1e83836Smrg 	{
1111*b1e83836Smrg 	  // Rebind the allocator to _Sp_overwrite_tag, so that the
1112*b1e83836Smrg 	  // relevant _Sp_counted_ptr_inplace specialization is used.
1113*b1e83836Smrg 	  using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;
1114*b1e83836Smrg 	  _Alloc2 __a2 = __a;
1115*b1e83836Smrg 	  return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc2>{__a2});
1116*b1e83836Smrg 	}
1117*b1e83836Smrg     }
1118*b1e83836Smrg 
1119*b1e83836Smrg   template<typename _Tp>
1120*b1e83836Smrg     inline shared_ptr<_NotUnboundedArray<_Tp>>
1121*b1e83836Smrg     make_shared_for_overwrite()
1122*b1e83836Smrg     {
1123*b1e83836Smrg       if constexpr (is_array_v<_Tp>)
1124*b1e83836Smrg 	return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1125*b1e83836Smrg 			       _Sp_overwrite_tag{});
1126*b1e83836Smrg       else
1127*b1e83836Smrg 	{
1128*b1e83836Smrg 	  using _Alloc = allocator<_Sp_overwrite_tag>;
1129*b1e83836Smrg 	  return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{{}});
1130*b1e83836Smrg 	}
1131*b1e83836Smrg     }
1132*b1e83836Smrg 
1133*b1e83836Smrg   template<typename _Tp, typename _Alloc>
1134*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1135*b1e83836Smrg     allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
1136*b1e83836Smrg     {
1137*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1138*b1e83836Smrg 			     _Sp_overwrite_tag{});
1139*b1e83836Smrg     }
1140*b1e83836Smrg 
1141*b1e83836Smrg   template<typename _Tp>
1142*b1e83836Smrg     inline shared_ptr<_UnboundedArray<_Tp>>
1143*b1e83836Smrg     make_shared_for_overwrite(size_t __n)
1144*b1e83836Smrg     {
1145*b1e83836Smrg       return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1146*b1e83836Smrg 			     _Sp_overwrite_tag{});
1147*b1e83836Smrg     }
1148*b1e83836Smrg #endif // smart_ptr_for_overwrite
1149*b1e83836Smrg #endif // shared_ptr_arrays
1150*b1e83836Smrg 
115148fb7bfaSmrg   /// std::hash specialization for shared_ptr.
115248fb7bfaSmrg   template<typename _Tp>
115348fb7bfaSmrg     struct hash<shared_ptr<_Tp>>
115448fb7bfaSmrg     : public __hash_base<size_t, shared_ptr<_Tp>>
115548fb7bfaSmrg     {
115648fb7bfaSmrg       size_t
115748fb7bfaSmrg       operator()(const shared_ptr<_Tp>& __s) const noexcept
1158b17d1066Smrg       {
1159b17d1066Smrg 	return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
1160b17d1066Smrg       }
116148fb7bfaSmrg     };
116248fb7bfaSmrg 
1163a448f87cSmrg   /// @} relates shared_ptr
1164a448f87cSmrg   /// @} group pointer_abstractions
11654fee23f9Smrg 
1166181254a7Smrg #if __cplusplus >= 201703L
1167181254a7Smrg   namespace __detail::__variant
1168181254a7Smrg   {
1169181254a7Smrg     template<typename> struct _Never_valueless_alt; // see <variant>
1170181254a7Smrg 
1171181254a7Smrg     // Provide the strong exception-safety guarantee when emplacing a
1172181254a7Smrg     // shared_ptr into a variant.
1173181254a7Smrg     template<typename _Tp>
1174181254a7Smrg       struct _Never_valueless_alt<std::shared_ptr<_Tp>>
1175181254a7Smrg       : std::true_type
1176181254a7Smrg       { };
1177181254a7Smrg 
1178181254a7Smrg     // Provide the strong exception-safety guarantee when emplacing a
1179181254a7Smrg     // weak_ptr into a variant.
1180181254a7Smrg     template<typename _Tp>
1181181254a7Smrg       struct _Never_valueless_alt<std::weak_ptr<_Tp>>
1182181254a7Smrg       : std::true_type
1183181254a7Smrg       { };
1184181254a7Smrg   }  // namespace __detail::__variant
1185181254a7Smrg #endif // C++17
1186181254a7Smrg 
118748fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION
118848fb7bfaSmrg } // namespace
11894fee23f9Smrg 
11904fee23f9Smrg #endif // _SHARED_PTR_H
1191