LCOV - code coverage report
Current view: top level - 11/bits - shared_ptr.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 76 84 90.5 %
Date: 2025-08-24 09:11:10 Functions: 1348 1621 83.2 %

          Line data    Source code
       1             : // shared_ptr and weak_ptr implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2021 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 <iosfwd>                   // std::basic_ostream
      53             : #include <bits/shared_ptr_base.h>
      54             : 
      55             : namespace std _GLIBCXX_VISIBILITY(default)
      56             : {
      57             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      58             : 
      59             :   /**
      60             :    * @addtogroup pointer_abstractions
      61             :    * @{
      62             :    */
      63             : 
      64             :   // 20.7.2.2.11 shared_ptr I/O
      65             : 
      66             :   /// Write the stored pointer to an ostream.
      67             :   /// @relates shared_ptr
      68             :   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
      69             :     inline std::basic_ostream<_Ch, _Tr>&
      70             :     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
      71             :                const __shared_ptr<_Tp, _Lp>& __p)
      72             :     {
      73             :       __os << __p.get();
      74             :       return __os;
      75             :     }
      76             : 
      77             :   template<typename _Del, typename _Tp, _Lock_policy _Lp>
      78             :     inline _Del*
      79             :     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
      80             :     {
      81             : #if __cpp_rtti
      82             :       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
      83             : #else
      84             :       return 0;
      85             : #endif
      86             :     }
      87             : 
      88             :   /// 20.7.2.2.10 shared_ptr get_deleter
      89             : 
      90             :   /// If `__p` has a deleter of type `_Del`, return a pointer to it.
      91             :   /// @relates shared_ptr
      92             :   template<typename _Del, typename _Tp>
      93             :     inline _Del*
      94             :     get_deleter(const shared_ptr<_Tp>& __p) noexcept
      95             :     {
      96             : #if __cpp_rtti
      97             :       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
      98             : #else
      99             :       return 0;
     100             : #endif
     101             :     }
     102             : 
     103             :   /**
     104             :    *  @brief  A smart pointer with reference-counted copy semantics.
     105             :    *
     106             :    * A `shared_ptr` object is either empty or _owns_ a pointer passed
     107             :    * to the constructor. Copies of a `shared_ptr` share ownership of
     108             :    * the same pointer. When the last `shared_ptr` that owns the pointer
     109             :    * is destroyed or reset, the owned pointer is freed (either by `delete`
     110             :    * or by invoking a custom deleter that was passed to the constructor).
     111             :    *
     112             :    * A `shared_ptr` also stores another pointer, which is usually
     113             :    * (but not always) the same pointer as it owns. The stored pointer
     114             :    * can be retrieved by calling the `get()` member function.
     115             :    *
     116             :    * The equality and relational operators for `shared_ptr` only compare
     117             :    * the stored pointer returned by `get()`, not the owned pointer.
     118             :    * To test whether two `shared_ptr` objects share ownership of the same
     119             :    * pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
     120             :   */
     121             :   template<typename _Tp>
     122             :     class shared_ptr : public __shared_ptr<_Tp>
     123             :     {
     124             :       template<typename... _Args>
     125             :         using _Constructible = typename enable_if<
     126             :           is_constructible<__shared_ptr<_Tp>, _Args...>::value
     127             :         >::type;
     128             : 
     129             :       template<typename _Arg>
     130             :         using _Assignable = typename enable_if<
     131             :           is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
     132             :         >::type;
     133             : 
     134             :     public:
     135             : 
     136             :       /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
     137             :       using element_type = typename __shared_ptr<_Tp>::element_type;
     138             : 
     139             : #if __cplusplus >= 201703L
     140             : # define __cpp_lib_shared_ptr_weak_type 201606
     141             :       /// The corresponding weak_ptr type for this shared_ptr
     142             :       using weak_type = weak_ptr<_Tp>;
     143             : #endif
     144             :       /**
     145             :        *  @brief  Construct an empty %shared_ptr.
     146             :        *  @post   use_count()==0 && get()==0
     147             :        */
     148      247304 :       constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
     149             : 
     150      877902 :       shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
     151             : 
     152             :       /**
     153             :        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
     154             :        *  @param  __p  A pointer that is convertible to element_type*.
     155             :        *  @post   use_count() == 1 && get() == __p
     156             :        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
     157             :        */
     158             :       template<typename _Yp, typename = _Constructible<_Yp*>>
     159             :         explicit
     160       19760 :         shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
     161             : 
     162             :       /**
     163             :        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
     164             :        *          and the deleter @a __d.
     165             :        *  @param  __p  A pointer.
     166             :        *  @param  __d  A deleter.
     167             :        *  @post   use_count() == 1 && get() == __p
     168             :        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
     169             :        *
     170             :        *  Requirements: _Deleter's copy constructor and destructor must
     171             :        *  not throw
     172             :        *
     173             :        *  __shared_ptr will release __p by calling __d(__p)
     174             :        */
     175             :       template<typename _Yp, typename _Deleter,
     176             :                typename = _Constructible<_Yp*, _Deleter>>
     177           0 :         shared_ptr(_Yp* __p, _Deleter __d)
     178           0 :         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
     179             : 
     180             :       /**
     181             :        *  @brief  Construct a %shared_ptr that owns a null pointer
     182             :        *          and the deleter @a __d.
     183             :        *  @param  __p  A null pointer constant.
     184             :        *  @param  __d  A deleter.
     185             :        *  @post   use_count() == 1 && get() == __p
     186             :        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
     187             :        *
     188             :        *  Requirements: _Deleter's copy constructor and destructor must
     189             :        *  not throw
     190             :        *
     191             :        *  The last owner will call __d(__p)
     192             :        */
     193             :       template<typename _Deleter>
     194             :         shared_ptr(nullptr_t __p, _Deleter __d)
     195             :         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
     196             : 
     197             :       /**
     198             :        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
     199             :        *          and the deleter @a __d.
     200             :        *  @param  __p  A pointer.
     201             :        *  @param  __d  A deleter.
     202             :        *  @param  __a  An allocator.
     203             :        *  @post   use_count() == 1 && get() == __p
     204             :        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
     205             :        *
     206             :        *  Requirements: _Deleter's copy constructor and destructor must
     207             :        *  not throw _Alloc's copy constructor and destructor must not
     208             :        *  throw.
     209             :        *
     210             :        *  __shared_ptr will release __p by calling __d(__p)
     211             :        */
     212             :       template<typename _Yp, typename _Deleter, typename _Alloc,
     213             :                typename = _Constructible<_Yp*, _Deleter, _Alloc>>
     214             :         shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
     215             :         : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
     216             : 
     217             :       /**
     218             :        *  @brief  Construct a %shared_ptr that owns a null pointer
     219             :        *          and the deleter @a __d.
     220             :        *  @param  __p  A null pointer constant.
     221             :        *  @param  __d  A deleter.
     222             :        *  @param  __a  An allocator.
     223             :        *  @post   use_count() == 1 && get() == __p
     224             :        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
     225             :        *
     226             :        *  Requirements: _Deleter's copy constructor and destructor must
     227             :        *  not throw _Alloc's copy constructor and destructor must not
     228             :        *  throw.
     229             :        *
     230             :        *  The last owner will call __d(__p)
     231             :        */
     232             :       template<typename _Deleter, typename _Alloc>
     233             :         shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
     234             :         : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
     235             : 
     236             :       // Aliasing constructor
     237             : 
     238             :       /**
     239             :        *  @brief  Constructs a `shared_ptr` instance that stores `__p`
     240             :        *          and shares ownership with `__r`.
     241             :        *  @param  __r  A `shared_ptr`.
     242             :        *  @param  __p  A pointer that will remain valid while `*__r` is valid.
     243             :        *  @post   `get() == __p && use_count() == __r.use_count()`
     244             :        *
     245             :        *  This can be used to construct a `shared_ptr` to a sub-object
     246             :        *  of an object managed by an existing `shared_ptr`. The complete
     247             :        *  object will remain valid while any `shared_ptr` owns it, even
     248             :        *  if they don't store a pointer to the complete object.
     249             :        *
     250             :        * @code
     251             :        * shared_ptr<pair<int,int>> pii(new pair<int,int>());
     252             :        * shared_ptr<int> pi(pii, &pii->first);
     253             :        * assert(pii.use_count() == 2);
     254             :        * @endcode
     255             :        */
     256             :       template<typename _Yp>
     257      143232 :         shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
     258      143232 :         : __shared_ptr<_Tp>(__r, __p) { }
     259             : 
     260             : #if __cplusplus > 201703L
     261             :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     262             :       // 2996. Missing rvalue overloads for shared_ptr operations
     263             :       /**
     264             :        *  @brief  Constructs a `shared_ptr` instance that stores `__p`
     265             :        *          and shares ownership with `__r`.
     266             :        *  @param  __r  A `shared_ptr`.
     267             :        *  @param  __p  A pointer that will remain valid while `*__r` is valid.
     268             :        *  @post   `get() == __p && !__r.use_count() && !__r.get()`
     269             :        *
     270             :        *  This can be used to construct a `shared_ptr` to a sub-object
     271             :        *  of an object managed by an existing `shared_ptr`. The complete
     272             :        *  object will remain valid while any `shared_ptr` owns it, even
     273             :        *  if they don't store a pointer to the complete object.
     274             :        *
     275             :        * @code
     276             :        * shared_ptr<pair<int,int>> pii(new pair<int,int>());
     277             :        * shared_ptr<int> pi1(pii, &pii->first);
     278             :        * assert(pii.use_count() == 2);
     279             :        * shared_ptr<int> pi2(std::move(pii), &pii->second);
     280             :        * assert(pii.use_count() == 0);
     281             :        * @endcode
     282             :        */
     283             :       template<typename _Yp>
     284             :         shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
     285             :         : __shared_ptr<_Tp>(std::move(__r), __p) { }
     286             : #endif
     287             :       /**
     288             :        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
     289             :        *          otherwise construct a %shared_ptr that shares ownership
     290             :        *          with @a __r.
     291             :        *  @param  __r  A %shared_ptr.
     292             :        *  @post   get() == __r.get() && use_count() == __r.use_count()
     293             :        */
     294             :       template<typename _Yp,
     295             :                typename = _Constructible<const shared_ptr<_Yp>&>>
     296        3080 :         shared_ptr(const shared_ptr<_Yp>& __r) noexcept
     297        3080 :         : __shared_ptr<_Tp>(__r) { }
     298             : 
     299             :       /**
     300             :        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
     301             :        *  @param  __r  A %shared_ptr rvalue.
     302             :        *  @post   *this contains the old value of @a __r, @a __r is empty.
     303             :        */
     304      163541 :       shared_ptr(shared_ptr&& __r) noexcept
     305      163541 :       : __shared_ptr<_Tp>(std::move(__r)) { }
     306             : 
     307             :       /**
     308             :        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
     309             :        *  @param  __r  A %shared_ptr rvalue.
     310             :        *  @post   *this contains the old value of @a __r, @a __r is empty.
     311             :        */
     312             :       template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
     313       19688 :         shared_ptr(shared_ptr<_Yp>&& __r) noexcept
     314       19688 :         : __shared_ptr<_Tp>(std::move(__r)) { }
     315             : 
     316             :       /**
     317             :        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
     318             :        *          and stores a copy of the pointer stored in @a __r.
     319             :        *  @param  __r  A weak_ptr.
     320             :        *  @post   use_count() == __r.use_count()
     321             :        *  @throw  bad_weak_ptr when __r.expired(),
     322             :        *          in which case the constructor has no effect.
     323             :        */
     324             :       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
     325       81111 :         explicit shared_ptr(const weak_ptr<_Yp>& __r)
     326       81111 :         : __shared_ptr<_Tp>(__r) { }
     327             : 
     328             : #if _GLIBCXX_USE_DEPRECATED
     329             : #pragma GCC diagnostic push
     330             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     331             :       template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
     332             :         shared_ptr(auto_ptr<_Yp>&& __r);
     333             : #pragma GCC diagnostic pop
     334             : #endif
     335             : 
     336             :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     337             :       // 2399. shared_ptr's constructor from unique_ptr should be constrained
     338             :       template<typename _Yp, typename _Del,
     339             :                typename = _Constructible<unique_ptr<_Yp, _Del>>>
     340        1211 :         shared_ptr(unique_ptr<_Yp, _Del>&& __r)
     341        1211 :         : __shared_ptr<_Tp>(std::move(__r)) { }
     342             : 
     343             : #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
     344             :       // This non-standard constructor exists to support conversions that
     345             :       // were possible in C++11 and C++14 but are ill-formed in C++17.
     346             :       // If an exception is thrown this constructor has no effect.
     347             :       template<typename _Yp, typename _Del,
     348             :                 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
     349             :         shared_ptr(unique_ptr<_Yp, _Del>&& __r)
     350             :         : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
     351             : #endif
     352             : 
     353             :       /**
     354             :        *  @brief  Construct an empty %shared_ptr.
     355             :        *  @post   use_count() == 0 && get() == nullptr
     356             :        */
     357       18914 :       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
     358             : 
     359       44529 :       shared_ptr& operator=(const shared_ptr&) noexcept = default;
     360             : 
     361             :       template<typename _Yp>
     362             :         _Assignable<const shared_ptr<_Yp>&>
     363          28 :         operator=(const shared_ptr<_Yp>& __r) noexcept
     364             :         {
     365          28 :           this->__shared_ptr<_Tp>::operator=(__r);
     366          28 :           return *this;
     367             :         }
     368             : 
     369             : #if _GLIBCXX_USE_DEPRECATED
     370             : #pragma GCC diagnostic push
     371             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     372             :       template<typename _Yp>
     373             :         _Assignable<auto_ptr<_Yp>>
     374             :         operator=(auto_ptr<_Yp>&& __r)
     375             :         {
     376             :           this->__shared_ptr<_Tp>::operator=(std::move(__r));
     377             :           return *this;
     378             :         }
     379             : #pragma GCC diagnostic pop
     380             : #endif
     381             : 
     382             :       shared_ptr&
     383      116347 :       operator=(shared_ptr&& __r) noexcept
     384             :       {
     385      116347 :         this->__shared_ptr<_Tp>::operator=(std::move(__r));
     386      116347 :         return *this;
     387             :       }
     388             : 
     389             :       template<class _Yp>
     390             :         _Assignable<shared_ptr<_Yp>>
     391        1359 :         operator=(shared_ptr<_Yp>&& __r) noexcept
     392             :         {
     393        1359 :           this->__shared_ptr<_Tp>::operator=(std::move(__r));
     394        1359 :           return *this;
     395             :         }
     396             : 
     397             :       template<typename _Yp, typename _Del>
     398             :         _Assignable<unique_ptr<_Yp, _Del>>
     399           0 :         operator=(unique_ptr<_Yp, _Del>&& __r)
     400             :         {
     401           0 :           this->__shared_ptr<_Tp>::operator=(std::move(__r));
     402           0 :           return *this;
     403             :         }
     404             : 
     405             :     private:
     406             :       // This constructor is non-standard, it is used by allocate_shared.
     407             :       template<typename _Alloc, typename... _Args>
     408      122198 :         shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
     409      122198 :         : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
     410      122197 :         { }
     411             : 
     412             :       template<typename _Yp, typename _Alloc, typename... _Args>
     413             :         friend shared_ptr<_Yp>
     414             :         allocate_shared(const _Alloc& __a, _Args&&... __args);
     415             : 
     416             :       // This constructor is non-standard, it is used by weak_ptr::lock().
     417      133928 :       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
     418      133928 :       : __shared_ptr<_Tp>(__r, std::nothrow) { }
     419             : 
     420             :       friend class weak_ptr<_Tp>;
     421             :     };
     422             : 
     423             : #if __cpp_deduction_guides >= 201606
     424             :   template<typename _Tp>
     425             :     shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;
     426             :   template<typename _Tp, typename _Del>
     427             :     shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;
     428             : #endif
     429             : 
     430             :   // 20.7.2.2.7 shared_ptr comparisons
     431             : 
     432             :   /// @relates shared_ptr @{
     433             : 
     434             :   /// Equality operator for shared_ptr objects, compares the stored pointers
     435             :   template<typename _Tp, typename _Up>
     436             :     _GLIBCXX_NODISCARD inline bool
     437       18033 :     operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     438       18033 :     { return __a.get() == __b.get(); }
     439             : 
     440             :   /// shared_ptr comparison with nullptr
     441             :   template<typename _Tp>
     442             :     _GLIBCXX_NODISCARD inline bool
     443       23138 :     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     444       23138 :     { return !__a; }
     445             : 
     446             : #ifdef __cpp_lib_three_way_comparison
     447             :   template<typename _Tp, typename _Up>
     448             :     inline strong_ordering
     449             :     operator<=>(const shared_ptr<_Tp>& __a,
     450             :                 const shared_ptr<_Up>& __b) noexcept
     451             :     { return compare_three_way()(__a.get(), __b.get()); }
     452             : 
     453             :   template<typename _Tp>
     454             :     inline strong_ordering
     455             :     operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     456             :     {
     457             :       using pointer = typename shared_ptr<_Tp>::element_type*;
     458             :       return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
     459             :     }
     460             : #else
     461             :   /// shared_ptr comparison with nullptr
     462             :   template<typename _Tp>
     463             :     _GLIBCXX_NODISCARD inline bool
     464             :     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     465             :     { return !__a; }
     466             : 
     467             :   /// Inequality operator for shared_ptr objects, compares the stored pointers
     468             :   template<typename _Tp, typename _Up>
     469             :     _GLIBCXX_NODISCARD inline bool
     470        1108 :     operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     471        1108 :     { return __a.get() != __b.get(); }
     472             : 
     473             :   /// shared_ptr comparison with nullptr
     474             :   template<typename _Tp>
     475             :     _GLIBCXX_NODISCARD inline bool
     476        4451 :     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     477        4451 :     { return (bool)__a; }
     478             : 
     479             :   /// shared_ptr comparison with nullptr
     480             :   template<typename _Tp>
     481             :     _GLIBCXX_NODISCARD inline bool
     482             :     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     483             :     { return (bool)__a; }
     484             : 
     485             :   /// Relational operator for shared_ptr objects, compares the stored pointers
     486             :   template<typename _Tp, typename _Up>
     487             :     _GLIBCXX_NODISCARD inline bool
     488        1656 :     operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     489             :     {
     490             :       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
     491             :       using _Up_elt = typename shared_ptr<_Up>::element_type;
     492             :       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
     493        1656 :       return less<_Vp>()(__a.get(), __b.get());
     494             :     }
     495             : 
     496             :   /// shared_ptr comparison with nullptr
     497             :   template<typename _Tp>
     498             :     _GLIBCXX_NODISCARD inline bool
     499             :     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     500             :     {
     501             :       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
     502             :       return less<_Tp_elt*>()(__a.get(), nullptr);
     503             :     }
     504             : 
     505             :   /// shared_ptr comparison with nullptr
     506             :   template<typename _Tp>
     507             :     _GLIBCXX_NODISCARD inline bool
     508             :     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     509             :     {
     510             :       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
     511             :       return less<_Tp_elt*>()(nullptr, __a.get());
     512             :     }
     513             : 
     514             :   /// Relational operator for shared_ptr objects, compares the stored pointers
     515             :   template<typename _Tp, typename _Up>
     516             :     _GLIBCXX_NODISCARD inline bool
     517             :     operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     518             :     { return !(__b < __a); }
     519             : 
     520             :   /// shared_ptr comparison with nullptr
     521             :   template<typename _Tp>
     522             :     _GLIBCXX_NODISCARD inline bool
     523             :     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     524             :     { return !(nullptr < __a); }
     525             : 
     526             :   /// shared_ptr comparison with nullptr
     527             :   template<typename _Tp>
     528             :     _GLIBCXX_NODISCARD inline bool
     529             :     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     530             :     { return !(__a < nullptr); }
     531             : 
     532             :   /// Relational operator for shared_ptr objects, compares the stored pointers
     533             :   template<typename _Tp, typename _Up>
     534             :     _GLIBCXX_NODISCARD inline bool
     535             :     operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     536             :     { return (__b < __a); }
     537             : 
     538             :   /// shared_ptr comparison with nullptr
     539             :   template<typename _Tp>
     540             :     _GLIBCXX_NODISCARD inline bool
     541             :     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     542             :     { return nullptr < __a; }
     543             : 
     544             :   /// shared_ptr comparison with nullptr
     545             :   template<typename _Tp>
     546             :     _GLIBCXX_NODISCARD inline bool
     547             :     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     548             :     { return __a < nullptr; }
     549             : 
     550             :   /// Relational operator for shared_ptr objects, compares the stored pointers
     551             :   template<typename _Tp, typename _Up>
     552             :     _GLIBCXX_NODISCARD inline bool
     553             :     operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
     554             :     { return !(__a < __b); }
     555             : 
     556             :   /// shared_ptr comparison with nullptr
     557             :   template<typename _Tp>
     558             :     _GLIBCXX_NODISCARD inline bool
     559             :     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     560             :     { return !(__a < nullptr); }
     561             : 
     562             :   /// shared_ptr comparison with nullptr
     563             :   template<typename _Tp>
     564             :     _GLIBCXX_NODISCARD inline bool
     565             :     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     566             :     { return !(nullptr < __a); }
     567             : #endif
     568             : 
     569             :   // 20.7.2.2.8 shared_ptr specialized algorithms.
     570             : 
     571             :   /// Swap overload for shared_ptr
     572             :   template<typename _Tp>
     573             :     inline void
     574          20 :     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
     575          20 :     { __a.swap(__b); }
     576             : 
     577             :   // 20.7.2.2.9 shared_ptr casts.
     578             : 
     579             :   /// Convert type of `shared_ptr`, via `static_cast`
     580             :   template<typename _Tp, typename _Up>
     581             :     inline shared_ptr<_Tp>
     582      131898 :     static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
     583             :     {
     584             :       using _Sp = shared_ptr<_Tp>;
     585      131898 :       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
     586             :     }
     587             : 
     588             :   /// Convert type of `shared_ptr`, via `const_cast`
     589             :   template<typename _Tp, typename _Up>
     590             :     inline shared_ptr<_Tp>
     591             :     const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
     592             :     {
     593             :       using _Sp = shared_ptr<_Tp>;
     594             :       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
     595             :     }
     596             : 
     597             :   /// Convert type of `shared_ptr`, via `dynamic_cast`
     598             :   template<typename _Tp, typename _Up>
     599             :     inline shared_ptr<_Tp>
     600       11701 :     dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
     601             :     {
     602             :       using _Sp = shared_ptr<_Tp>;
     603       11701 :       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
     604       11340 :         return _Sp(__r, __p);
     605         361 :       return _Sp();
     606             :     }
     607             : 
     608             : #if __cplusplus >= 201703L
     609             :   /// Convert type of `shared_ptr`, via `reinterpret_cast`
     610             :   template<typename _Tp, typename _Up>
     611             :     inline shared_ptr<_Tp>
     612             :     reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
     613             :     {
     614             :       using _Sp = shared_ptr<_Tp>;
     615             :       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
     616             :     }
     617             : 
     618             : #if __cplusplus > 201703L
     619             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     620             :   // 2996. Missing rvalue overloads for shared_ptr operations
     621             : 
     622             :   /// Convert type of `shared_ptr` rvalue, via `static_cast`
     623             :   template<typename _Tp, typename _Up>
     624             :     inline shared_ptr<_Tp>
     625             :     static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
     626             :     {
     627             :       using _Sp = shared_ptr<_Tp>;
     628             :       return _Sp(std::move(__r),
     629             :                  static_cast<typename _Sp::element_type*>(__r.get()));
     630             :     }
     631             : 
     632             :   /// Convert type of `shared_ptr` rvalue, via `const_cast`
     633             :   template<typename _Tp, typename _Up>
     634             :     inline shared_ptr<_Tp>
     635             :     const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
     636             :     {
     637             :       using _Sp = shared_ptr<_Tp>;
     638             :       return _Sp(std::move(__r),
     639             :                  const_cast<typename _Sp::element_type*>(__r.get()));
     640             :     }
     641             : 
     642             :   /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
     643             :   template<typename _Tp, typename _Up>
     644             :     inline shared_ptr<_Tp>
     645             :     dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
     646             :     {
     647             :       using _Sp = shared_ptr<_Tp>;
     648             :       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
     649             :         return _Sp(std::move(__r), __p);
     650             :       return _Sp();
     651             :     }
     652             : 
     653             :   /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
     654             :   template<typename _Tp, typename _Up>
     655             :     inline shared_ptr<_Tp>
     656             :     reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
     657             :     {
     658             :       using _Sp = shared_ptr<_Tp>;
     659             :       return _Sp(std::move(__r),
     660             :                  reinterpret_cast<typename _Sp::element_type*>(__r.get()));
     661             :     }
     662             : #endif // C++20
     663             : #endif // C++17
     664             : 
     665             :   /// @}
     666             : 
     667             :   /**
     668             :    * @brief  A non-owning observer for a pointer owned by a shared_ptr
     669             :    *
     670             :    * A weak_ptr provides a safe alternative to a raw pointer when you want
     671             :    * a non-owning reference to an object that is managed by a shared_ptr.
     672             :    *
     673             :    * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
     674             :    * that shares ownership with every other shared_ptr that already owns
     675             :    * the pointer. In other words you can upgrade from a non-owning "weak"
     676             :    * reference to an owning shared_ptr, without having access to any of
     677             :    * the existing shared_ptr objects.
     678             :    *
     679             :    * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
     680             :    * the object it points to has been destroyed. Instead, a weak_ptr
     681             :    * becomes _expired_ and can no longer be converted to a shared_ptr that
     682             :    * owns the freed pointer, so you cannot accidentally access the pointed-to
     683             :    * object after it has been destroyed.
     684             :    */
     685             :   template<typename _Tp>
     686             :     class weak_ptr : public __weak_ptr<_Tp>
     687             :     {
     688             :       template<typename _Arg>
     689             :         using _Constructible = typename enable_if<
     690             :           is_constructible<__weak_ptr<_Tp>, _Arg>::value
     691             :         >::type;
     692             : 
     693             :       template<typename _Arg>
     694             :         using _Assignable = typename enable_if<
     695             :           is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
     696             :         >::type;
     697             : 
     698             :     public:
     699       11265 :       constexpr weak_ptr() noexcept = default;
     700             : 
     701             :       template<typename _Yp,
     702             :                typename = _Constructible<const shared_ptr<_Yp>&>>
     703       80674 :         weak_ptr(const shared_ptr<_Yp>& __r) noexcept
     704       80674 :         : __weak_ptr<_Tp>(__r) { }
     705             : 
     706      108216 :       weak_ptr(const weak_ptr&) noexcept = default;
     707             : 
     708             :       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
     709             :         weak_ptr(const weak_ptr<_Yp>& __r) noexcept
     710             :         : __weak_ptr<_Tp>(__r) { }
     711             : 
     712      145194 :       weak_ptr(weak_ptr&&) noexcept = default;
     713             : 
     714             :       template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
     715             :         weak_ptr(weak_ptr<_Yp>&& __r) noexcept
     716             :         : __weak_ptr<_Tp>(std::move(__r)) { }
     717             : 
     718             :       weak_ptr&
     719             :       operator=(const weak_ptr& __r) noexcept = default;
     720             : 
     721             :       template<typename _Yp>
     722             :         _Assignable<const weak_ptr<_Yp>&>
     723             :         operator=(const weak_ptr<_Yp>& __r) noexcept
     724             :         {
     725             :           this->__weak_ptr<_Tp>::operator=(__r);
     726             :           return *this;
     727             :         }
     728             : 
     729             :       template<typename _Yp>
     730             :         _Assignable<const shared_ptr<_Yp>&>
     731        2828 :         operator=(const shared_ptr<_Yp>& __r) noexcept
     732             :         {
     733        2828 :           this->__weak_ptr<_Tp>::operator=(__r);
     734        2828 :           return *this;
     735             :         }
     736             : 
     737             :       weak_ptr&
     738           0 :       operator=(weak_ptr&& __r) noexcept = default;
     739             : 
     740             :       template<typename _Yp>
     741             :         _Assignable<weak_ptr<_Yp>>
     742             :         operator=(weak_ptr<_Yp>&& __r) noexcept
     743             :         {
     744             :           this->__weak_ptr<_Tp>::operator=(std::move(__r));
     745             :           return *this;
     746             :         }
     747             : 
     748             :       shared_ptr<_Tp>
     749      133928 :       lock() const noexcept
     750      133928 :       { return shared_ptr<_Tp>(*this, std::nothrow); }
     751             :     };
     752             : 
     753             : #if __cpp_deduction_guides >= 201606
     754             :   template<typename _Tp>
     755             :     weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;
     756             : #endif
     757             : 
     758             :   // 20.7.2.3.6 weak_ptr specialized algorithms.
     759             :   /// Swap overload for weak_ptr
     760             :   /// @relates weak_ptr
     761             :   template<typename _Tp>
     762             :     inline void
     763           2 :     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
     764           2 :     { __a.swap(__b); }
     765             : 
     766             : 
     767             :   /// Primary template owner_less
     768             :   template<typename _Tp = void>
     769             :     struct owner_less;
     770             : 
     771             :   /// Void specialization of owner_less compares either shared_ptr or weak_ptr
     772             :   template<>
     773             :     struct owner_less<void> : _Sp_owner_less<void, void>
     774             :     { };
     775             : 
     776             :   /// Partial specialization of owner_less for shared_ptr.
     777             :   template<typename _Tp>
     778             :     struct owner_less<shared_ptr<_Tp>>
     779             :     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
     780             :     { };
     781             : 
     782             :   /// Partial specialization of owner_less for weak_ptr.
     783             :   template<typename _Tp>
     784             :     struct owner_less<weak_ptr<_Tp>>
     785             :     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
     786             :     { };
     787             : 
     788             :   /**
     789             :    *  @brief Base class allowing use of member function shared_from_this.
     790             :    */
     791             :   template<typename _Tp>
     792             :     class enable_shared_from_this
     793             :     {
     794             :     protected:
     795        6566 :       constexpr enable_shared_from_this() noexcept { }
     796             : 
     797             :       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
     798             : 
     799             :       enable_shared_from_this&
     800             :       operator=(const enable_shared_from_this&) noexcept
     801             :       { return *this; }
     802             : 
     803        6556 :       ~enable_shared_from_this() { }
     804             : 
     805             :     public:
     806             :       shared_ptr<_Tp>
     807       81111 :       shared_from_this()
     808       81111 :       { return shared_ptr<_Tp>(this->_M_weak_this); }
     809             : 
     810             :       shared_ptr<const _Tp>
     811           0 :       shared_from_this() const
     812           0 :       { return shared_ptr<const _Tp>(this->_M_weak_this); }
     813             : 
     814             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     815             : #define __cpp_lib_enable_shared_from_this 201603
     816             :       weak_ptr<_Tp>
     817       37358 :       weak_from_this() noexcept
     818       37358 :       { return this->_M_weak_this; }
     819             : 
     820             :       weak_ptr<const _Tp>
     821             :       weak_from_this() const noexcept
     822             :       { return this->_M_weak_this; }
     823             : #endif
     824             : 
     825             :     private:
     826             :       template<typename _Tp1>
     827             :         void
     828        7897 :         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
     829        7897 :         { _M_weak_this._M_assign(__p, __n); }
     830             : 
     831             :       // Found by ADL when this is an associated class.
     832             :       friend const enable_shared_from_this*
     833        7897 :       __enable_shared_from_this_base(const __shared_count<>&,
     834             :                                      const enable_shared_from_this* __p)
     835        7897 :       { return __p; }
     836             : 
     837             :       template<typename, _Lock_policy>
     838             :         friend class __shared_ptr;
     839             : 
     840             :       mutable weak_ptr<_Tp>  _M_weak_this;
     841             :     };
     842             : 
     843             :   /// @relates shared_ptr @{
     844             : 
     845             :   /**
     846             :    *  @brief  Create an object that is owned by a shared_ptr.
     847             :    *  @param  __a     An allocator.
     848             :    *  @param  __args  Arguments for the @a _Tp object's constructor.
     849             :    *  @return A shared_ptr that owns the newly created object.
     850             :    *  @throw  An exception thrown from @a _Alloc::allocate or from the
     851             :    *          constructor of @a _Tp.
     852             :    *
     853             :    *  A copy of @a __a will be used to allocate memory for the shared_ptr
     854             :    *  and the new object.
     855             :    */
     856             :   template<typename _Tp, typename _Alloc, typename... _Args>
     857             :     inline shared_ptr<_Tp>
     858      122198 :     allocate_shared(const _Alloc& __a, _Args&&... __args)
     859             :     {
     860             :       static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
     861             : 
     862             :       return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
     863      122198 :                              std::forward<_Args>(__args)...);
     864             :     }
     865             : 
     866             :   /**
     867             :    *  @brief  Create an object that is owned by a shared_ptr.
     868             :    *  @param  __args  Arguments for the @a _Tp object's constructor.
     869             :    *  @return A shared_ptr that owns the newly created object.
     870             :    *  @throw  std::bad_alloc, or an exception thrown from the
     871             :    *          constructor of @a _Tp.
     872             :    */
     873             :   template<typename _Tp, typename... _Args>
     874             :     inline shared_ptr<_Tp>
     875      122198 :     make_shared(_Args&&... __args)
     876             :     {
     877             :       typedef typename std::remove_cv<_Tp>::type _Tp_nc;
     878      244396 :       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
     879      307228 :                                        std::forward<_Args>(__args)...);
     880             :     }
     881             : 
     882             :   /// std::hash specialization for shared_ptr.
     883             :   template<typename _Tp>
     884             :     struct hash<shared_ptr<_Tp>>
     885             :     : public __hash_base<size_t, shared_ptr<_Tp>>
     886             :     {
     887             :       size_t
     888             :       operator()(const shared_ptr<_Tp>& __s) const noexcept
     889             :       {
     890             :         return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
     891             :       }
     892             :     };
     893             : 
     894             :   /// @} relates shared_ptr
     895             :   /// @} group pointer_abstractions
     896             : 
     897             : #if __cplusplus >= 201703L
     898             :   namespace __detail::__variant
     899             :   {
     900             :     template<typename> struct _Never_valueless_alt; // see <variant>
     901             : 
     902             :     // Provide the strong exception-safety guarantee when emplacing a
     903             :     // shared_ptr into a variant.
     904             :     template<typename _Tp>
     905             :       struct _Never_valueless_alt<std::shared_ptr<_Tp>>
     906             :       : std::true_type
     907             :       { };
     908             : 
     909             :     // Provide the strong exception-safety guarantee when emplacing a
     910             :     // weak_ptr into a variant.
     911             :     template<typename _Tp>
     912             :       struct _Never_valueless_alt<std::weak_ptr<_Tp>>
     913             :       : std::true_type
     914             :       { };
     915             :   }  // namespace __detail::__variant
     916             : #endif // C++17
     917             : 
     918             : _GLIBCXX_END_NAMESPACE_VERSION
     919             : } // namespace
     920             : 
     921             : #endif // _SHARED_PTR_H

Generated by: LCOV version 1.14