| 1 | // shared_ptr and weak_ptr implementation -*- C++ -*-  | 
| 2 |   | 
| 3 | // Copyright (C) 2007-2019 Free Software Foundation, Inc.  | 
| 4 | //  | 
| 5 | // This file is part of the GNU ISO C++ Library.  This library is free  | 
| 6 | // software; you can redistribute it and/or modify it under the  | 
| 7 | // terms of the GNU General Public License as published by the  | 
| 8 | // Free Software Foundation; either version 3, or (at your option)  | 
| 9 | // any later version.  | 
| 10 |   | 
| 11 | // This library is distributed in the hope that it will be useful,  | 
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  | 
| 14 | // GNU General Public License for more details.  | 
| 15 |   | 
| 16 | // Under Section 7 of GPL version 3, you are granted additional  | 
| 17 | // permissions described in the GCC Runtime Library Exception, version  | 
| 18 | // 3.1, as published by the Free Software Foundation.  | 
| 19 |   | 
| 20 | // You should have received a copy of the GNU General Public License and  | 
| 21 | // a copy of the GCC Runtime Library Exception along with this program;  | 
| 22 | // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see  | 
| 23 | // <http://www.gnu.org/licenses/>.  | 
| 24 |   | 
| 25 | // GCC Note: Based on files from version 1.32.0 of the Boost library.  | 
| 26 |   | 
| 27 | //  shared_count.hpp  | 
| 28 | //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.  | 
| 29 |   | 
| 30 | //  shared_ptr.hpp  | 
| 31 | //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.  | 
| 32 | //  Copyright (C) 2001, 2002, 2003 Peter Dimov  | 
| 33 |   | 
| 34 | //  weak_ptr.hpp  | 
| 35 | //  Copyright (C) 2001, 2002, 2003 Peter Dimov  | 
| 36 |   | 
| 37 | //  enable_shared_from_this.hpp  | 
| 38 | //  Copyright (C) 2002 Peter Dimov  | 
| 39 |   | 
| 40 | // Distributed under the Boost Software License, Version 1.0. (See  | 
| 41 | // accompanying file LICENSE_1_0.txt or copy at  | 
| 42 | // http://www.boost.org/LICENSE_1_0.txt)  | 
| 43 |   | 
| 44 | /** @file  | 
| 45 |  *  This is an internal header file, included by other library headers.  | 
| 46 |  *  Do not attempt to use it directly. @headername{memory}  | 
| 47 |  */  | 
| 48 |   | 
| 49 | #ifndef _SHARED_PTR_H  | 
| 50 | #define _SHARED_PTR_H 1  | 
| 51 |   | 
| 52 | #include <bits/shared_ptr_base.h>  | 
| 53 |   | 
| 54 | namespace std _GLIBCXX_VISIBILITY(default)  | 
| 55 | {  | 
| 56 | _GLIBCXX_BEGIN_NAMESPACE_VERSION  | 
| 57 |   | 
| 58 |   /**  | 
| 59 |    * @addtogroup pointer_abstractions  | 
| 60 |    * @{  | 
| 61 |    */  | 
| 62 |   | 
| 63 |   /// 20.7.2.2.11 shared_ptr I/O  | 
| 64 |   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>  | 
| 65 |     inline std::basic_ostream<_Ch, _Tr>&  | 
| 66 |     operator<<(std::basic_ostream<_Ch, _Tr>& __os,  | 
| 67 | 	       const __shared_ptr<_Tp, _Lp>& __p)  | 
| 68 |     {  | 
| 69 |       __os << __p.get();  | 
| 70 |       return __os;  | 
| 71 |     }  | 
| 72 |   | 
| 73 |   template<typename _Del, typename _Tp, _Lock_policy _Lp>  | 
| 74 |     inline _Del*  | 
| 75 |     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept  | 
| 76 |     {  | 
| 77 | #if __cpp_rtti  | 
| 78 |       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));  | 
| 79 | #else  | 
| 80 |       return 0;  | 
| 81 | #endif  | 
| 82 |     }  | 
| 83 |   | 
| 84 |   /// 20.7.2.2.10 shared_ptr get_deleter  | 
| 85 |   template<typename _Del, typename _Tp>  | 
| 86 |     inline _Del*  | 
| 87 |     get_deleter(const shared_ptr<_Tp>& __p) noexcept  | 
| 88 |     {  | 
| 89 | #if __cpp_rtti  | 
| 90 |       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));  | 
| 91 | #else  | 
| 92 |       return 0;  | 
| 93 | #endif  | 
| 94 |     }  | 
| 95 |   | 
| 96 |   /**  | 
| 97 |    *  @brief  A smart pointer with reference-counted copy semantics.  | 
| 98 |    *  | 
| 99 |    *  The object pointed to is deleted when the last shared_ptr pointing to  | 
| 100 |    *  it is destroyed or reset.  | 
| 101 |   */  | 
| 102 |   template<typename _Tp>  | 
| 103 |     class shared_ptr : public __shared_ptr<_Tp>  | 
| 104 |     {  | 
| 105 |       template<typename... _Args>  | 
| 106 | 	using _Constructible = typename enable_if<  | 
| 107 | 	  is_constructible<__shared_ptr<_Tp>, _Args...>::value  | 
| 108 | 	>::type;  | 
| 109 |   | 
| 110 |       template<typename _Arg>  | 
| 111 | 	using _Assignable = typename enable_if<  | 
| 112 | 	  is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&  | 
| 113 | 	>::type;  | 
| 114 |   | 
| 115 |     public:  | 
| 116 |   | 
| 117 |       using element_type = typename __shared_ptr<_Tp>::element_type;  | 
| 118 |   | 
| 119 | #if __cplusplus > 201402L  | 
| 120 | # define __cpp_lib_shared_ptr_weak_type 201606  | 
| 121 |       using weak_type = weak_ptr<_Tp>;  | 
| 122 | #endif  | 
| 123 |       /**  | 
| 124 |        *  @brief  Construct an empty %shared_ptr.  | 
| 125 |        *  @post   use_count()==0 && get()==0  | 
| 126 |        */  | 
| 127 |       constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }  | 
| 128 |   | 
| 129 |       shared_ptr(const shared_ptr&) noexcept = default;  | 
| 130 |   | 
| 131 |       /**  | 
| 132 |        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.  | 
| 133 |        *  @param  __p  A pointer that is convertible to element_type*.  | 
| 134 |        *  @post   use_count() == 1 && get() == __p  | 
| 135 |        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.  | 
| 136 |        */  | 
| 137 |       template<typename _Yp, typename = _Constructible<_Yp*>>  | 
| 138 | 	explicit  | 
| 139 | 	shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }  | 
| 140 |   | 
| 141 |       /**  | 
| 142 |        *  @brief  Construct a %shared_ptr that owns the pointer @a __p  | 
| 143 |        *          and the deleter @a __d.  | 
| 144 |        *  @param  __p  A pointer.  | 
| 145 |        *  @param  __d  A deleter.  | 
| 146 |        *  @post   use_count() == 1 && get() == __p  | 
| 147 |        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.  | 
| 148 |        *  | 
| 149 |        *  Requirements: _Deleter's copy constructor and destructor must  | 
| 150 |        *  not throw  | 
| 151 |        *  | 
| 152 |        *  __shared_ptr will release __p by calling __d(__p)  | 
| 153 |        */  | 
| 154 |       template<typename _Yp, typename _Deleter,  | 
| 155 | 	       typename = _Constructible<_Yp*, _Deleter>>  | 
| 156 | 	shared_ptr(_Yp* __p, _Deleter __d)  | 
| 157 |         : __shared_ptr<_Tp>(__p, std::move(__d)) { }  | 
| 158 |   | 
| 159 |       /**  | 
| 160 |        *  @brief  Construct a %shared_ptr that owns a null pointer  | 
| 161 |        *          and the deleter @a __d.  | 
| 162 |        *  @param  __p  A null pointer constant.  | 
| 163 |        *  @param  __d  A deleter.  | 
| 164 |        *  @post   use_count() == 1 && get() == __p  | 
| 165 |        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.  | 
| 166 |        *  | 
| 167 |        *  Requirements: _Deleter's copy constructor and destructor must  | 
| 168 |        *  not throw  | 
| 169 |        *  | 
| 170 |        *  The last owner will call __d(__p)  | 
| 171 |        */  | 
| 172 |       template<typename _Deleter>  | 
| 173 | 	shared_ptr(nullptr_t __p, _Deleter __d)  | 
| 174 |         : __shared_ptr<_Tp>(__p, std::move(__d)) { }  | 
| 175 |   | 
| 176 |       /**  | 
| 177 |        *  @brief  Construct a %shared_ptr that owns the pointer @a __p  | 
| 178 |        *          and the deleter @a __d.  | 
| 179 |        *  @param  __p  A pointer.  | 
| 180 |        *  @param  __d  A deleter.  | 
| 181 |        *  @param  __a  An allocator.  | 
| 182 |        *  @post   use_count() == 1 && get() == __p  | 
| 183 |        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.  | 
| 184 |        *  | 
| 185 |        *  Requirements: _Deleter's copy constructor and destructor must  | 
| 186 |        *  not throw _Alloc's copy constructor and destructor must not  | 
| 187 |        *  throw.  | 
| 188 |        *  | 
| 189 |        *  __shared_ptr will release __p by calling __d(__p)  | 
| 190 |        */  | 
| 191 |       template<typename _Yp, typename _Deleter, typename _Alloc,  | 
| 192 | 	       typename = _Constructible<_Yp*, _Deleter, _Alloc>>  | 
| 193 | 	shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)  | 
| 194 | 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }  | 
| 195 |   | 
| 196 |       /**  | 
| 197 |        *  @brief  Construct a %shared_ptr that owns a null pointer  | 
| 198 |        *          and the deleter @a __d.  | 
| 199 |        *  @param  __p  A null pointer constant.  | 
| 200 |        *  @param  __d  A deleter.  | 
| 201 |        *  @param  __a  An allocator.  | 
| 202 |        *  @post   use_count() == 1 && get() == __p  | 
| 203 |        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.  | 
| 204 |        *  | 
| 205 |        *  Requirements: _Deleter's copy constructor and destructor must  | 
| 206 |        *  not throw _Alloc's copy constructor and destructor must not  | 
| 207 |        *  throw.  | 
| 208 |        *  | 
| 209 |        *  The last owner will call __d(__p)  | 
| 210 |        */  | 
| 211 |       template<typename _Deleter, typename _Alloc>  | 
| 212 | 	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)  | 
| 213 | 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }  | 
| 214 |   | 
| 215 |       // Aliasing constructor  | 
| 216 |   | 
| 217 |       /**  | 
| 218 |        *  @brief  Constructs a %shared_ptr instance that stores @a __p  | 
| 219 |        *          and shares ownership with @a __r.  | 
| 220 |        *  @param  __r  A %shared_ptr.  | 
| 221 |        *  @param  __p  A pointer that will remain valid while @a *__r is valid.  | 
| 222 |        *  @post   get() == __p && use_count() == __r.use_count()  | 
| 223 |        *  | 
| 224 |        *  This can be used to construct a @c shared_ptr to a sub-object  | 
| 225 |        *  of an object managed by an existing @c shared_ptr.  | 
| 226 |        *  | 
| 227 |        * @code  | 
| 228 |        * shared_ptr< pair<int,int> > pii(new pair<int,int>());  | 
| 229 |        * shared_ptr<int> pi(pii, &pii->first);  | 
| 230 |        * assert(pii.use_count() == 2);  | 
| 231 |        * @endcode  | 
| 232 |        */  | 
| 233 |       template<typename _Yp>  | 
| 234 | 	shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept  | 
| 235 | 	: __shared_ptr<_Tp>(__r, __p) { }  | 
| 236 |   | 
| 237 |       /**  | 
| 238 |        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;  | 
| 239 |        *          otherwise construct a %shared_ptr that shares ownership  | 
| 240 |        *          with @a __r.  | 
| 241 |        *  @param  __r  A %shared_ptr.  | 
| 242 |        *  @post   get() == __r.get() && use_count() == __r.use_count()  | 
| 243 |        */  | 
| 244 |       template<typename _Yp,  | 
| 245 | 	       typename = _Constructible<const shared_ptr<_Yp>&>>  | 
| 246 | 	shared_ptr(const shared_ptr<_Yp>& __r) noexcept  | 
| 247 |         : __shared_ptr<_Tp>(__r) { }  | 
| 248 |   | 
| 249 |       /**  | 
| 250 |        *  @brief  Move-constructs a %shared_ptr instance from @a __r.  | 
| 251 |        *  @param  __r  A %shared_ptr rvalue.  | 
| 252 |        *  @post   *this contains the old value of @a __r, @a __r is empty.  | 
| 253 |        */  | 
| 254 |       shared_ptr(shared_ptr&& __r) noexcept  | 
| 255 |       : __shared_ptr<_Tp>(std::move(__r)) { }  | 
| 256 |   | 
| 257 |       /**  | 
| 258 |        *  @brief  Move-constructs a %shared_ptr instance from @a __r.  | 
| 259 |        *  @param  __r  A %shared_ptr rvalue.  | 
| 260 |        *  @post   *this contains the old value of @a __r, @a __r is empty.  | 
| 261 |        */  | 
| 262 |       template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>  | 
| 263 | 	shared_ptr(shared_ptr<_Yp>&& __r) noexcept  | 
| 264 | 	: __shared_ptr<_Tp>(std::move(__r)) { }  | 
| 265 |   | 
| 266 |       /**  | 
| 267 |        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r  | 
| 268 |        *          and stores a copy of the pointer stored in @a __r.  | 
| 269 |        *  @param  __r  A weak_ptr.  | 
| 270 |        *  @post   use_count() == __r.use_count()  | 
| 271 |        *  @throw  bad_weak_ptr when __r.expired(),  | 
| 272 |        *          in which case the constructor has no effect.  | 
| 273 |        */  | 
| 274 |       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>  | 
| 275 | 	explicit shared_ptr(const weak_ptr<_Yp>& __r)  | 
| 276 | 	: __shared_ptr<_Tp>(__r) { }  | 
| 277 |   | 
| 278 | #if _GLIBCXX_USE_DEPRECATED  | 
| 279 | #pragma GCC diagnostic push  | 
| 280 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations"  | 
| 281 |       template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>  | 
| 282 | 	shared_ptr(auto_ptr<_Yp>&& __r);  | 
| 283 | #pragma GCC diagnostic pop  | 
| 284 | #endif  | 
| 285 |   | 
| 286 |       // _GLIBCXX_RESOLVE_LIB_DEFECTS  | 
| 287 |       // 2399. shared_ptr's constructor from unique_ptr should be constrained  | 
| 288 |       template<typename _Yp, typename _Del,  | 
| 289 | 	       typename = _Constructible<unique_ptr<_Yp, _Del>>>  | 
| 290 | 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)  | 
| 291 | 	: __shared_ptr<_Tp>(std::move(__r)) { }  | 
| 292 |   | 
| 293 | #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED  | 
| 294 |       // This non-standard constructor exists to support conversions that  | 
| 295 |       // were possible in C++11 and C++14 but are ill-formed in C++17.  | 
| 296 |       // If an exception is thrown this constructor has no effect.  | 
| 297 |       template<typename _Yp, typename _Del,  | 
| 298 | 		_Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>  | 
| 299 | 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)  | 
| 300 | 	: __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }  | 
| 301 | #endif  | 
| 302 |   | 
| 303 |       /**  | 
| 304 |        *  @brief  Construct an empty %shared_ptr.  | 
| 305 |        *  @post   use_count() == 0 && get() == nullptr  | 
| 306 |        */  | 
| 307 |       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }  | 
| 308 |   | 
| 309 |       shared_ptr& operator=(const shared_ptr&) noexcept = default;  | 
| 310 |   | 
| 311 |       template<typename _Yp>  | 
| 312 | 	_Assignable<const shared_ptr<_Yp>&>  | 
| 313 | 	operator=(const shared_ptr<_Yp>& __r) noexcept  | 
| 314 | 	{  | 
| 315 | 	  this->__shared_ptr<_Tp>::operator=(__r);  | 
| 316 | 	  return *this;  | 
| 317 | 	}  | 
| 318 |   | 
| 319 | #if _GLIBCXX_USE_DEPRECATED  | 
| 320 | #pragma GCC diagnostic push  | 
| 321 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations"  | 
| 322 |       template<typename _Yp>  | 
| 323 | 	_Assignable<auto_ptr<_Yp>>  | 
| 324 | 	operator=(auto_ptr<_Yp>&& __r)  | 
| 325 | 	{  | 
| 326 | 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));  | 
| 327 | 	  return *this;  | 
| 328 | 	}  | 
| 329 | #pragma GCC diagnostic pop  | 
| 330 | #endif  | 
| 331 |   | 
| 332 |       shared_ptr&  | 
| 333 |       operator=(shared_ptr&& __r) noexcept  | 
| 334 |       {  | 
| 335 | 	this->__shared_ptr<_Tp>::operator=(std::move(__r));  | 
| 336 | 	return *this;  | 
| 337 |       }  | 
| 338 |   | 
| 339 |       template<class _Yp>  | 
| 340 | 	_Assignable<shared_ptr<_Yp>>  | 
| 341 | 	operator=(shared_ptr<_Yp>&& __r) noexcept  | 
| 342 | 	{  | 
| 343 | 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));  | 
| 344 | 	  return *this;  | 
| 345 | 	}  | 
| 346 |   | 
| 347 |       template<typename _Yp, typename _Del>  | 
| 348 | 	_Assignable<unique_ptr<_Yp, _Del>>  | 
| 349 | 	operator=(unique_ptr<_Yp, _Del>&& __r)  | 
| 350 | 	{  | 
| 351 | 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));  | 
| 352 | 	  return *this;  | 
| 353 | 	}  | 
| 354 |   | 
| 355 |     private:  | 
| 356 |       // This constructor is non-standard, it is used by allocate_shared.  | 
| 357 |       template<typename _Alloc, typename... _Args>  | 
| 358 | 	shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)  | 
| 359 | 	: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)  | 
| 360 | 	{ }  | 
| 361 |   | 
| 362 |       template<typename _Yp, typename _Alloc, typename... _Args>  | 
| 363 | 	friend shared_ptr<_Yp>  | 
| 364 | 	allocate_shared(const _Alloc& __a, _Args&&... __args);  | 
| 365 |   | 
| 366 |       // This constructor is non-standard, it is used by weak_ptr::lock().  | 
| 367 |       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)  | 
| 368 |       : __shared_ptr<_Tp>(__r, std::nothrow) { }  | 
| 369 |   | 
| 370 |       friend class weak_ptr<_Tp>;  | 
| 371 |     };  | 
| 372 |   | 
| 373 | #if __cpp_deduction_guides >= 201606  | 
| 374 |   template<typename _Tp>  | 
| 375 |     shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;  | 
| 376 |   template<typename _Tp, typename _Del>  | 
| 377 |     shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;  | 
| 378 | #endif  | 
| 379 |   | 
| 380 |   // 20.7.2.2.7 shared_ptr comparisons  | 
| 381 |   template<typename _Tp, typename _Up>  | 
| 382 |     _GLIBCXX_NODISCARD inline bool  | 
| 383 |     operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 384 |     { return __a.get() == __b.get(); }  | 
| 385 |   | 
| 386 |   template<typename _Tp>  | 
| 387 |     _GLIBCXX_NODISCARD inline bool  | 
| 388 |     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 389 |     { return !__a; }  | 
| 390 |   | 
| 391 |   template<typename _Tp>  | 
| 392 |     _GLIBCXX_NODISCARD inline bool  | 
| 393 |     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 394 |     { return !__a; }  | 
| 395 |   | 
| 396 |   template<typename _Tp, typename _Up>  | 
| 397 |     _GLIBCXX_NODISCARD inline bool  | 
| 398 |     operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 399 |     { return __a.get() != __b.get(); }  | 
| 400 |   | 
| 401 |   template<typename _Tp>  | 
| 402 |     _GLIBCXX_NODISCARD inline bool  | 
| 403 |     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 404 |     { return (bool)__a; }  | 
| 405 |   | 
| 406 |   template<typename _Tp>  | 
| 407 |     _GLIBCXX_NODISCARD inline bool  | 
| 408 |     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 409 |     { return (bool)__a; }  | 
| 410 |   | 
| 411 |   template<typename _Tp, typename _Up>  | 
| 412 |     _GLIBCXX_NODISCARD inline bool  | 
| 413 |     operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 414 |     {  | 
| 415 |       using _Tp_elt = typename shared_ptr<_Tp>::element_type;  | 
| 416 |       using _Up_elt = typename shared_ptr<_Up>::element_type;  | 
| 417 |       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;  | 
| 418 |       return less<_Vp>()(__a.get(), __b.get());  | 
| 419 |     }  | 
| 420 |   | 
| 421 |   template<typename _Tp>  | 
| 422 |     _GLIBCXX_NODISCARD inline bool  | 
| 423 |     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 424 |     {  | 
| 425 |       using _Tp_elt = typename shared_ptr<_Tp>::element_type;  | 
| 426 |       return less<_Tp_elt*>()(__a.get(), nullptr);  | 
| 427 |     }  | 
| 428 |   | 
| 429 |   template<typename _Tp>  | 
| 430 |     _GLIBCXX_NODISCARD inline bool  | 
| 431 |     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 432 |     {  | 
| 433 |       using _Tp_elt = typename shared_ptr<_Tp>::element_type;  | 
| 434 |       return less<_Tp_elt*>()(nullptr, __a.get());  | 
| 435 |     }  | 
| 436 |   | 
| 437 |   template<typename _Tp, typename _Up>  | 
| 438 |     _GLIBCXX_NODISCARD inline bool  | 
| 439 |     operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 440 |     { return !(__b < __a); }  | 
| 441 |   | 
| 442 |   template<typename _Tp>  | 
| 443 |     _GLIBCXX_NODISCARD inline bool  | 
| 444 |     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 445 |     { return !(nullptr < __a); }  | 
| 446 |   | 
| 447 |   template<typename _Tp>  | 
| 448 |     _GLIBCXX_NODISCARD inline bool  | 
| 449 |     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 450 |     { return !(__a < nullptr); }  | 
| 451 |   | 
| 452 |   template<typename _Tp, typename _Up>  | 
| 453 |     _GLIBCXX_NODISCARD inline bool  | 
| 454 |     operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 455 |     { return (__b < __a); }  | 
| 456 |   | 
| 457 |   template<typename _Tp>  | 
| 458 |     _GLIBCXX_NODISCARD inline bool  | 
| 459 |     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 460 |     { return nullptr < __a; }  | 
| 461 |   | 
| 462 |   template<typename _Tp>  | 
| 463 |     _GLIBCXX_NODISCARD inline bool  | 
| 464 |     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 465 |     { return __a < nullptr; }  | 
| 466 |   | 
| 467 |   template<typename _Tp, typename _Up>  | 
| 468 |     _GLIBCXX_NODISCARD inline bool  | 
| 469 |     operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept  | 
| 470 |     { return !(__a < __b); }  | 
| 471 |   | 
| 472 |   template<typename _Tp>  | 
| 473 |     _GLIBCXX_NODISCARD inline bool  | 
| 474 |     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept  | 
| 475 |     { return !(__a < nullptr); }  | 
| 476 |   | 
| 477 |   template<typename _Tp>  | 
| 478 |     _GLIBCXX_NODISCARD inline bool  | 
| 479 |     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept  | 
| 480 |     { return !(nullptr < __a); }  | 
| 481 |   | 
| 482 |   // 20.7.2.2.8 shared_ptr specialized algorithms.  | 
| 483 |   template<typename _Tp>  | 
| 484 |     inline void  | 
| 485 |     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept  | 
| 486 |     { __a.swap(__b); }  | 
| 487 |   | 
| 488 |   // 20.7.2.2.9 shared_ptr casts.  | 
| 489 |   template<typename _Tp, typename _Up>  | 
| 490 |     inline shared_ptr<_Tp>  | 
| 491 |     static_pointer_cast(const shared_ptr<_Up>& __r) noexcept  | 
| 492 |     {  | 
| 493 |       using _Sp = shared_ptr<_Tp>;  | 
| 494 |       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));  | 
| 495 |     }  | 
| 496 |   | 
| 497 |   template<typename _Tp, typename _Up>  | 
| 498 |     inline shared_ptr<_Tp>  | 
| 499 |     const_pointer_cast(const shared_ptr<_Up>& __r) noexcept  | 
| 500 |     {  | 
| 501 |       using _Sp = shared_ptr<_Tp>;  | 
| 502 |       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));  | 
| 503 |     }  | 
| 504 |   | 
| 505 |   template<typename _Tp, typename _Up>  | 
| 506 |     inline shared_ptr<_Tp>  | 
| 507 |     dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept  | 
| 508 |     {  | 
| 509 |       using _Sp = shared_ptr<_Tp>;  | 
| 510 |       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))  | 
| 511 | 	return _Sp(__r, __p);  | 
| 512 |       return _Sp();  | 
| 513 |     }  | 
| 514 |   | 
| 515 | #if __cplusplus > 201402L  | 
| 516 |   template<typename _Tp, typename _Up>  | 
| 517 |     inline shared_ptr<_Tp>  | 
| 518 |     reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept  | 
| 519 |     {  | 
| 520 |       using _Sp = shared_ptr<_Tp>;  | 
| 521 |       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));  | 
| 522 |     }  | 
| 523 | #endif  | 
| 524 |   | 
| 525 |   /**  | 
| 526 |    *  @brief  A smart pointer with weak semantics.  | 
| 527 |    *  | 
| 528 |    *  With forwarding constructors and assignment operators.  | 
| 529 |    */  | 
| 530 |   template<typename _Tp>  | 
| 531 |     class weak_ptr : public __weak_ptr<_Tp>  | 
| 532 |     {  | 
| 533 |       template<typename _Arg>  | 
| 534 | 	using _Constructible = typename enable_if<  | 
| 535 | 	  is_constructible<__weak_ptr<_Tp>, _Arg>::value  | 
| 536 | 	>::type;  | 
| 537 |   | 
| 538 |       template<typename _Arg>  | 
| 539 | 	using _Assignable = typename enable_if<  | 
| 540 | 	  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&  | 
| 541 | 	>::type;  | 
| 542 |   | 
| 543 |     public:  | 
| 544 |       constexpr weak_ptr() noexcept = default;  | 
| 545 |   | 
| 546 |       template<typename _Yp,  | 
| 547 | 	       typename = _Constructible<const shared_ptr<_Yp>&>>  | 
| 548 | 	weak_ptr(const shared_ptr<_Yp>& __r) noexcept  | 
| 549 | 	: __weak_ptr<_Tp>(__r) { }  | 
| 550 |   | 
| 551 |       weak_ptr(const weak_ptr&) noexcept = default;  | 
| 552 |   | 
| 553 |       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>  | 
| 554 | 	weak_ptr(const weak_ptr<_Yp>& __r) noexcept  | 
| 555 | 	: __weak_ptr<_Tp>(__r) { }  | 
| 556 |   | 
| 557 |       weak_ptr(weak_ptr&&) noexcept = default;  | 
| 558 |   | 
| 559 |       template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>  | 
| 560 | 	weak_ptr(weak_ptr<_Yp>&& __r) noexcept  | 
| 561 | 	: __weak_ptr<_Tp>(std::move(__r)) { }  | 
| 562 |   | 
| 563 |       weak_ptr&  | 
| 564 |       operator=(const weak_ptr& __r) noexcept = default;  | 
| 565 |   | 
| 566 |       template<typename _Yp>  | 
| 567 | 	_Assignable<const weak_ptr<_Yp>&>  | 
| 568 | 	operator=(const weak_ptr<_Yp>& __r) noexcept  | 
| 569 | 	{  | 
| 570 | 	  this->__weak_ptr<_Tp>::operator=(__r);  | 
| 571 | 	  return *this;  | 
| 572 | 	}  | 
| 573 |   | 
| 574 |       template<typename _Yp>  | 
| 575 | 	_Assignable<const shared_ptr<_Yp>&>  | 
| 576 | 	operator=(const shared_ptr<_Yp>& __r) noexcept  | 
| 577 | 	{  | 
| 578 | 	  this->__weak_ptr<_Tp>::operator=(__r);  | 
| 579 | 	  return *this;  | 
| 580 | 	}  | 
| 581 |   | 
| 582 |       weak_ptr&  | 
| 583 |       operator=(weak_ptr&& __r) noexcept = default;  | 
| 584 |   | 
| 585 |       template<typename _Yp>  | 
| 586 | 	_Assignable<weak_ptr<_Yp>>  | 
| 587 | 	operator=(weak_ptr<_Yp>&& __r) noexcept  | 
| 588 | 	{  | 
| 589 | 	  this->__weak_ptr<_Tp>::operator=(std::move(__r));  | 
| 590 | 	  return *this;  | 
| 591 | 	}  | 
| 592 |   | 
| 593 |       shared_ptr<_Tp>  | 
| 594 |       lock() const noexcept  | 
| 595 |       { return shared_ptr<_Tp>(*this, std::nothrow); }  | 
| 596 |     };  | 
| 597 |   | 
| 598 | #if __cpp_deduction_guides >= 201606  | 
| 599 |   template<typename _Tp>  | 
| 600 |     weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;  | 
| 601 | #endif  | 
| 602 |   | 
| 603 |   // 20.7.2.3.6 weak_ptr specialized algorithms.  | 
| 604 |   template<typename _Tp>  | 
| 605 |     inline void  | 
| 606 |     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept  | 
| 607 |     { __a.swap(__b); }  | 
| 608 |   | 
| 609 |   | 
| 610 |   /// Primary template owner_less  | 
| 611 |   template<typename _Tp = void>  | 
| 612 |     struct owner_less;  | 
| 613 |   | 
| 614 |   /// Void specialization of owner_less  | 
| 615 |   template<>  | 
| 616 |     struct owner_less<void> : _Sp_owner_less<void, void>  | 
| 617 |     { };  | 
| 618 |   | 
| 619 |   /// Partial specialization of owner_less for shared_ptr.  | 
| 620 |   template<typename _Tp>  | 
| 621 |     struct owner_less<shared_ptr<_Tp>>  | 
| 622 |     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>  | 
| 623 |     { };  | 
| 624 |   | 
| 625 |   /// Partial specialization of owner_less for weak_ptr.  | 
| 626 |   template<typename _Tp>  | 
| 627 |     struct owner_less<weak_ptr<_Tp>>  | 
| 628 |     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>  | 
| 629 |     { };  | 
| 630 |   | 
| 631 |   /**  | 
| 632 |    *  @brief Base class allowing use of member function shared_from_this.  | 
| 633 |    */  | 
| 634 |   template<typename _Tp>  | 
| 635 |     class enable_shared_from_this  | 
| 636 |     {  | 
| 637 |     protected:  | 
| 638 |       constexpr enable_shared_from_this() noexcept { }  | 
| 639 |   | 
| 640 |       enable_shared_from_this(const enable_shared_from_this&) noexcept { }  | 
| 641 |   | 
| 642 |       enable_shared_from_this&  | 
| 643 |       operator=(const enable_shared_from_this&) noexcept  | 
| 644 |       { return *this; }  | 
| 645 |   | 
| 646 |       ~enable_shared_from_this() { }  | 
| 647 |   | 
| 648 |     public:  | 
| 649 |       shared_ptr<_Tp>  | 
| 650 |       shared_from_this()  | 
| 651 |       { return shared_ptr<_Tp>(this->_M_weak_this); }  | 
| 652 |   | 
| 653 |       shared_ptr<const _Tp>  | 
| 654 |       shared_from_this() const  | 
| 655 |       { return shared_ptr<const _Tp>(this->_M_weak_this); }  | 
| 656 |   | 
| 657 | #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11  | 
| 658 | #define __cpp_lib_enable_shared_from_this 201603  | 
| 659 |       weak_ptr<_Tp>  | 
| 660 |       weak_from_this() noexcept  | 
| 661 |       { return this->_M_weak_this; }  | 
| 662 |   | 
| 663 |       weak_ptr<const _Tp>  | 
| 664 |       weak_from_this() const noexcept  | 
| 665 |       { return this->_M_weak_this; }  | 
| 666 | #endif  | 
| 667 |   | 
| 668 |     private:  | 
| 669 |       template<typename _Tp1>  | 
| 670 | 	void  | 
| 671 | 	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept  | 
| 672 | 	{ _M_weak_this._M_assign(__p, __n); }  | 
| 673 |   | 
| 674 |       // Found by ADL when this is an associated class.  | 
| 675 |       friend const enable_shared_from_this*  | 
| 676 |       __enable_shared_from_this_base(const __shared_count<>&,  | 
| 677 | 				     const enable_shared_from_this* __p)  | 
| 678 |       { return __p; }  | 
| 679 |   | 
| 680 |       template<typename, _Lock_policy>  | 
| 681 | 	friend class __shared_ptr;  | 
| 682 |   | 
| 683 |       mutable weak_ptr<_Tp>  _M_weak_this;  | 
| 684 |     };  | 
| 685 |   | 
| 686 |   /**  | 
| 687 |    *  @brief  Create an object that is owned by a shared_ptr.  | 
| 688 |    *  @param  __a     An allocator.  | 
| 689 |    *  @param  __args  Arguments for the @a _Tp object's constructor.  | 
| 690 |    *  @return A shared_ptr that owns the newly created object.  | 
| 691 |    *  @throw  An exception thrown from @a _Alloc::allocate or from the  | 
| 692 |    *          constructor of @a _Tp.  | 
| 693 |    *  | 
| 694 |    *  A copy of @a __a will be used to allocate memory for the shared_ptr  | 
| 695 |    *  and the new object.  | 
| 696 |    */  | 
| 697 |   template<typename _Tp, typename _Alloc, typename... _Args>  | 
| 698 |     inline shared_ptr<_Tp>  | 
| 699 |     allocate_shared(const _Alloc& __a, _Args&&... __args)  | 
| 700 |     {  | 
| 701 |       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},  | 
| 702 | 			     std::forward<_Args>(__args)...);  | 
| 703 |     }  | 
| 704 |   | 
| 705 |   /**  | 
| 706 |    *  @brief  Create an object that is owned by a shared_ptr.  | 
| 707 |    *  @param  __args  Arguments for the @a _Tp object's constructor.  | 
| 708 |    *  @return A shared_ptr that owns the newly created object.  | 
| 709 |    *  @throw  std::bad_alloc, or an exception thrown from the  | 
| 710 |    *          constructor of @a _Tp.  | 
| 711 |    */  | 
| 712 |   template<typename _Tp, typename... _Args>  | 
| 713 |     inline shared_ptr<_Tp>  | 
| 714 |     make_shared(_Args&&... __args)  | 
| 715 |     {  | 
| 716 |       typedef typename std::remove_cv<_Tp>::type _Tp_nc;  | 
| 717 |       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),  | 
| 718 | 				       std::forward<_Args>(__args)...);  | 
| 719 |     }  | 
| 720 |   | 
| 721 |   /// std::hash specialization for shared_ptr.  | 
| 722 |   template<typename _Tp>  | 
| 723 |     struct hash<shared_ptr<_Tp>>  | 
| 724 |     : public __hash_base<size_t, shared_ptr<_Tp>>  | 
| 725 |     {  | 
| 726 |       size_t  | 
| 727 |       operator()(const shared_ptr<_Tp>& __s) const noexcept  | 
| 728 |       {  | 
| 729 | 	return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());  | 
| 730 |       }  | 
| 731 |     };  | 
| 732 |   | 
| 733 |   // @} group pointer_abstractions  | 
| 734 |   | 
| 735 | #if __cplusplus >= 201703L  | 
| 736 |   namespace __detail::__variant  | 
| 737 |   {  | 
| 738 |     template<typename> struct _Never_valueless_alt; // see <variant>  | 
| 739 |   | 
| 740 |     // Provide the strong exception-safety guarantee when emplacing a  | 
| 741 |     // shared_ptr into a variant.  | 
| 742 |     template<typename _Tp>  | 
| 743 |       struct _Never_valueless_alt<std::shared_ptr<_Tp>>  | 
| 744 |       : std::true_type  | 
| 745 |       { };  | 
| 746 |   | 
| 747 |     // Provide the strong exception-safety guarantee when emplacing a  | 
| 748 |     // weak_ptr into a variant.  | 
| 749 |     template<typename _Tp>  | 
| 750 |       struct _Never_valueless_alt<std::weak_ptr<_Tp>>  | 
| 751 |       : std::true_type  | 
| 752 |       { };  | 
| 753 |   }  // namespace __detail::__variant  | 
| 754 | #endif // C++17  | 
| 755 |   | 
| 756 | _GLIBCXX_END_NAMESPACE_VERSION  | 
| 757 | } // namespace  | 
| 758 |   | 
| 759 | #endif // _SHARED_PTR_H  | 
| 760 |  |