LCOV - code coverage report
Current view: top level - 11/bits - unique_ptr.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 108 117 92.3 %
Date: 2025-08-24 09:11:10 Functions: 1743 2068 84.3 %

          Line data    Source code
       1             : // unique_ptr implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2008-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             : /** @file bits/unique_ptr.h
      26             :  *  This is an internal header file, included by other library headers.
      27             :  *  Do not attempt to use it directly. @headername{memory}
      28             :  */
      29             : 
      30             : #ifndef _UNIQUE_PTR_H
      31             : #define _UNIQUE_PTR_H 1
      32             : 
      33             : #include <bits/c++config.h>
      34             : #include <debug/assertions.h>
      35             : #include <type_traits>
      36             : #include <utility>
      37             : #include <tuple>
      38             : #include <bits/stl_function.h>
      39             : #include <bits/functional_hash.h>
      40             : #if __cplusplus > 201703L
      41             : # include <compare>
      42             : # include <ostream>
      43             : #endif
      44             : 
      45             : namespace std _GLIBCXX_VISIBILITY(default)
      46             : {
      47             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      48             : 
      49             :   /**
      50             :    * @addtogroup pointer_abstractions
      51             :    * @{
      52             :    */
      53             : 
      54             : #if _GLIBCXX_USE_DEPRECATED
      55             : #pragma GCC diagnostic push
      56             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      57             :   template<typename> class auto_ptr;
      58             : #pragma GCC diagnostic pop
      59             : #endif
      60             : 
      61             :   /// Primary template of default_delete, used by unique_ptr for single objects
      62             :   template<typename _Tp>
      63             :     struct default_delete
      64             :     {
      65             :       /// Default constructor
      66             :       constexpr default_delete() noexcept = default;
      67             : 
      68             :       /** @brief Converting constructor.
      69             :        *
      70             :        * Allows conversion from a deleter for objects of another type, `_Up`,
      71             :        * only if `_Up*` is convertible to `_Tp*`.
      72             :        */
      73             :       template<typename _Up,
      74             :                typename = _Require<is_convertible<_Up*, _Tp*>>>
      75        4811 :         default_delete(const default_delete<_Up>&) noexcept { }
      76             : 
      77             :       /// Calls `delete __ptr`
      78             :       void
      79      102144 :       operator()(_Tp* __ptr) const
      80             :       {
      81             :         static_assert(!is_void<_Tp>::value,
      82             :                       "can't delete pointer to incomplete type");
      83             :         static_assert(sizeof(_Tp)>0,
      84             :                       "can't delete pointer to incomplete type");
      85      102144 :         delete __ptr;
      86      102144 :       }
      87             :     };
      88             : 
      89             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
      90             :   // DR 740 - omit specialization for array objects with a compile time length
      91             : 
      92             :   /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
      93             :   template<typename _Tp>
      94             :     struct default_delete<_Tp[]>
      95             :     {
      96             :     public:
      97             :       /// Default constructor
      98             :       constexpr default_delete() noexcept = default;
      99             : 
     100             :       /** @brief Converting constructor.
     101             :        *
     102             :        * Allows conversion from a deleter for arrays of another type, such as
     103             :        * a const-qualified version of `_Tp`.
     104             :        *
     105             :        * Conversions from types derived from `_Tp` are not allowed because
     106             :        * it is undefined to `delete[]` an array of derived types through a
     107             :        * pointer to the base type.
     108             :        */
     109             :       template<typename _Up,
     110             :                typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
     111             :         default_delete(const default_delete<_Up[]>&) noexcept { }
     112             : 
     113             :       /// Calls `delete[] __ptr`
     114             :       template<typename _Up>
     115             :         typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
     116          13 :         operator()(_Up* __ptr) const
     117             :         {
     118             :           static_assert(sizeof(_Tp)>0,
     119             :                         "can't delete pointer to incomplete type");
     120          13 :           delete [] __ptr;
     121          13 :         }
     122             :     };
     123             : 
     124             :   /// @cond undocumented
     125             : 
     126             :   // Manages the pointer and deleter of a unique_ptr
     127             :   template <typename _Tp, typename _Dp>
     128             :     class __uniq_ptr_impl
     129             :     {
     130             :       template <typename _Up, typename _Ep, typename = void>
     131             :         struct _Ptr
     132             :         {
     133             :           using type = _Up*;
     134             :         };
     135             : 
     136             :       template <typename _Up, typename _Ep>
     137             :         struct
     138             :         _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
     139             :         {
     140             :           using type = typename remove_reference<_Ep>::type::pointer;
     141             :         };
     142             : 
     143             :     public:
     144             :       using _DeleterConstraint = enable_if<
     145             :         __and_<__not_<is_pointer<_Dp>>,
     146             :                is_default_constructible<_Dp>>::value>;
     147             : 
     148             :       using pointer = typename _Ptr<_Tp, _Dp>::type;
     149             : 
     150             :       static_assert( !is_rvalue_reference<_Dp>::value,
     151             :                      "unique_ptr's deleter type must be a function object type"
     152             :                      " or an lvalue reference type" );
     153             : 
     154      111482 :       __uniq_ptr_impl() = default;
     155      138916 :       __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
     156             : 
     157             :       template<typename _Del>
     158    92062967 :       __uniq_ptr_impl(pointer __p, _Del&& __d)
     159    92062967 :         : _M_t(__p, std::forward<_Del>(__d)) { }
     160             : 
     161       30534 :       __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
     162       30534 :       : _M_t(std::move(__u._M_t))
     163       30534 :       { __u._M_ptr() = nullptr; }
     164             : 
     165       33515 :       __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
     166             :       {
     167       33515 :         reset(__u.release());
     168       33515 :         _M_deleter() = std::forward<_Dp>(__u._M_deleter());
     169       33515 :         return *this;
     170             :       }
     171             : 
     172    93358663 :       pointer&   _M_ptr() { return std::get<0>(_M_t); }
     173    94140898 :       pointer    _M_ptr() const { return std::get<0>(_M_t); }
     174    92742375 :       _Dp&       _M_deleter() { return std::get<1>(_M_t); }
     175             :       const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
     176             : 
     177      125554 :       void reset(pointer __p) noexcept
     178             :       {
     179      125554 :         const pointer __old_p = _M_ptr();
     180      125551 :         _M_ptr() = __p;
     181      125553 :         if (__old_p)
     182       28862 :           _M_deleter()(__old_p);
     183      125553 :       }
     184             : 
     185       66015 :       pointer release() noexcept
     186             :       {
     187       66015 :         pointer __p = _M_ptr();
     188       66014 :         _M_ptr() = nullptr;
     189       66015 :         return __p;
     190             :       }
     191             : 
     192             :       void
     193        9563 :       swap(__uniq_ptr_impl& __rhs) noexcept
     194             :       {
     195             :         using std::swap;
     196        9563 :         swap(this->_M_ptr(), __rhs._M_ptr());
     197        9563 :         swap(this->_M_deleter(), __rhs._M_deleter());
     198        9563 :       }
     199             : 
     200             :     private:
     201             :       tuple<pointer, _Dp> _M_t;
     202             :     };
     203             : 
     204             :   // Defines move construction + assignment as either defaulted or deleted.
     205             :   template <typename _Tp, typename _Dp,
     206             :             bool = is_move_constructible<_Dp>::value,
     207             :             bool = is_move_assignable<_Dp>::value>
     208             :     struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
     209             :     {
     210             :       using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
     211       30534 :       __uniq_ptr_data(__uniq_ptr_data&&) = default;
     212       33515 :       __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
     213             :     };
     214             : 
     215             :   template <typename _Tp, typename _Dp>
     216             :     struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
     217             :     {
     218             :       using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
     219             :       __uniq_ptr_data(__uniq_ptr_data&&) = default;
     220             :       __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
     221             :     };
     222             : 
     223             :   template <typename _Tp, typename _Dp>
     224             :     struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
     225             :     {
     226             :       using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
     227             :       __uniq_ptr_data(__uniq_ptr_data&&) = delete;
     228             :       __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
     229             :     };
     230             : 
     231             :   template <typename _Tp, typename _Dp>
     232             :     struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
     233             :     {
     234             :       using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
     235             :       __uniq_ptr_data(__uniq_ptr_data&&) = delete;
     236             :       __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
     237             :     };
     238             :   /// @endcond
     239             : 
     240             :   /// 20.7.1.2 unique_ptr for single objects.
     241             :   template <typename _Tp, typename _Dp = default_delete<_Tp>>
     242             :     class unique_ptr
     243             :     {
     244             :       template <typename _Up>
     245             :         using _DeleterConstraint =
     246             :           typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     247             : 
     248             :       __uniq_ptr_data<_Tp, _Dp> _M_t;
     249             : 
     250             :     public:
     251             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     252             :       using element_type  = _Tp;
     253             :       using deleter_type  = _Dp;
     254             : 
     255             :     private:
     256             :       // helper template for detecting a safe conversion from another
     257             :       // unique_ptr
     258             :       template<typename _Up, typename _Ep>
     259             :         using __safe_conversion_up = __and_<
     260             :           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
     261             :           __not_<is_array<_Up>>
     262             :         >;
     263             : 
     264             :     public:
     265             :       // Constructors.
     266             : 
     267             :       /// Default constructor, creates a unique_ptr that owns nothing.
     268             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     269      111306 :         constexpr unique_ptr() noexcept
     270      111306 :         : _M_t()
     271      111303 :         { }
     272             : 
     273             :       /** Takes ownership of a pointer.
     274             :        *
     275             :        * @param __p  A pointer to an object of @c element_type
     276             :        *
     277             :        * The deleter will be value-initialized.
     278             :        */
     279             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     280             :         explicit
     281      138916 :         unique_ptr(pointer __p) noexcept
     282      138916 :         : _M_t(__p)
     283      138916 :         { }
     284             : 
     285             :       /** Takes ownership of a pointer.
     286             :        *
     287             :        * @param __p  A pointer to an object of @c element_type
     288             :        * @param __d  A reference to a deleter.
     289             :        *
     290             :        * The deleter will be initialized with @p __d
     291             :        */
     292             :       template<typename _Del = deleter_type,
     293             :                typename = _Require<is_copy_constructible<_Del>>>
     294        1997 :         unique_ptr(pointer __p, const deleter_type& __d) noexcept
     295        1997 :         : _M_t(__p, __d) { }
     296             : 
     297             :       /** Takes ownership of a pointer.
     298             :        *
     299             :        * @param __p  A pointer to an object of @c element_type
     300             :        * @param __d  An rvalue reference to a (non-reference) deleter.
     301             :        *
     302             :        * The deleter will be initialized with @p std::move(__d)
     303             :        */
     304             :       template<typename _Del = deleter_type,
     305             :                typename = _Require<is_move_constructible<_Del>>>
     306    92056346 :         unique_ptr(pointer __p,
     307             :                    __enable_if_t<!is_lvalue_reference<_Del>::value,
     308             :                                  _Del&&> __d) noexcept
     309    92056346 :         : _M_t(__p, std::move(__d))
     310    92056345 :         { }
     311             : 
     312             :       template<typename _Del = deleter_type,
     313             :                typename _DelUnref = typename remove_reference<_Del>::type>
     314             :         unique_ptr(pointer,
     315             :                    __enable_if_t<is_lvalue_reference<_Del>::value,
     316             :                                  _DelUnref&&>) = delete;
     317             : 
     318             :       /// Creates a unique_ptr that owns nothing.
     319             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     320         150 :         constexpr unique_ptr(nullptr_t) noexcept
     321         150 :         : _M_t()
     322         150 :         { }
     323             : 
     324             :       // Move constructors.
     325             : 
     326             :       /// Move constructor.
     327       30404 :       unique_ptr(unique_ptr&&) = default;
     328             : 
     329             :       /** @brief Converting constructor from another type
     330             :        *
     331             :        * Requires that the pointer owned by @p __u is convertible to the
     332             :        * type of pointer owned by this object, @p __u does not own an array,
     333             :        * and @p __u has a compatible deleter type.
     334             :        */
     335             :       template<typename _Up, typename _Ep, typename = _Require<
     336             :                __safe_conversion_up<_Up, _Ep>,
     337             :                typename conditional<is_reference<_Dp>::value,
     338             :                                     is_same<_Ep, _Dp>,
     339             :                                     is_convertible<_Ep, _Dp>>::type>>
     340        4625 :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     341        4625 :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     342        4625 :         { }
     343             : 
     344             : #if _GLIBCXX_USE_DEPRECATED
     345             : #pragma GCC diagnostic push
     346             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     347             :       /// Converting constructor from @c auto_ptr
     348             :       template<typename _Up, typename = _Require<
     349             :                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
     350             :         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
     351             : #pragma GCC diagnostic pop
     352             : #endif
     353             : 
     354             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     355    92786919 :       ~unique_ptr() noexcept
     356             :       {
     357             :         static_assert(__is_invocable<deleter_type&, pointer>::value,
     358             :                       "unique_ptr's deleter must be invocable with a pointer");
     359    92786919 :         auto& __ptr = _M_t._M_ptr();
     360    92786660 :         if (__ptr != nullptr)
     361    92612564 :           get_deleter()(std::move(__ptr));
     362    92786718 :         __ptr = pointer();
     363    92786718 :       }
     364             : 
     365             :       // Assignment.
     366             : 
     367             :       /** @brief Move assignment operator.
     368             :        *
     369             :        * Invokes the deleter if this object owns a pointer.
     370             :        */
     371       33502 :       unique_ptr& operator=(unique_ptr&&) = default;
     372             : 
     373             :       /** @brief Assignment from another type.
     374             :        *
     375             :        * @param __u  The object to transfer ownership from, which owns a
     376             :        *             convertible pointer to a non-array object.
     377             :        *
     378             :        * Invokes the deleter if this object owns a pointer.
     379             :        */
     380             :       template<typename _Up, typename _Ep>
     381             :         typename enable_if< __and_<
     382             :           __safe_conversion_up<_Up, _Ep>,
     383             :           is_assignable<deleter_type&, _Ep&&>
     384             :           >::value,
     385             :           unique_ptr&>::type
     386        4527 :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     387             :         {
     388        4527 :           reset(__u.release());
     389        4527 :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     390        4527 :           return *this;
     391             :         }
     392             : 
     393             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     394             :       unique_ptr&
     395           0 :       operator=(nullptr_t) noexcept
     396             :       {
     397           0 :         reset();
     398           0 :         return *this;
     399             :       }
     400             : 
     401             :       // Observers.
     402             : 
     403             :       /// Dereference the stored pointer.
     404             :       typename add_lvalue_reference<element_type>::type
     405      170091 :       operator*() const
     406             :       {
     407      170091 :         __glibcxx_assert(get() != pointer());
     408      170091 :         return *get();
     409             :       }
     410             : 
     411             :       /// Return the stored pointer.
     412             :       pointer
     413      970141 :       operator->() const noexcept
     414             :       {
     415             :         _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
     416      970141 :         return get();
     417             :       }
     418             : 
     419             :       /// Return the stored pointer.
     420             :       pointer
     421    94140835 :       get() const noexcept
     422    94140835 :       { return _M_t._M_ptr(); }
     423             : 
     424             :       /// Return a reference to the stored deleter.
     425             :       deleter_type&
     426    92627397 :       get_deleter() noexcept
     427    92627397 :       { return _M_t._M_deleter(); }
     428             : 
     429             :       /// Return a reference to the stored deleter.
     430             :       const deleter_type&
     431             :       get_deleter() const noexcept
     432             :       { return _M_t._M_deleter(); }
     433             : 
     434             :       /// Return @c true if the stored pointer is not null.
     435      303456 :       explicit operator bool() const noexcept
     436      303456 :       { return get() == pointer() ? false : true; }
     437             : 
     438             :       // Modifiers.
     439             : 
     440             :       /// Release ownership of any stored pointer.
     441             :       pointer
     442       32500 :       release() noexcept
     443       32500 :       { return _M_t.release(); }
     444             : 
     445             :       /** @brief Replace the stored pointer.
     446             :        *
     447             :        * @param __p  The new pointer to store.
     448             :        *
     449             :        * The deleter will be invoked if a pointer is already owned.
     450             :        */
     451             :       void
     452       92026 :       reset(pointer __p = pointer()) noexcept
     453             :       {
     454             :         static_assert(__is_invocable<deleter_type&, pointer>::value,
     455             :                       "unique_ptr's deleter must be invocable with a pointer");
     456       92026 :         _M_t.reset(std::move(__p));
     457       92025 :       }
     458             : 
     459             :       /// Exchange the pointer and deleter with another object.
     460             :       void
     461        9563 :       swap(unique_ptr& __u) noexcept
     462             :       {
     463             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     464        9563 :         _M_t.swap(__u._M_t);
     465        9563 :       }
     466             : 
     467             :       // Disable copy from lvalue.
     468             :       unique_ptr(const unique_ptr&) = delete;
     469             :       unique_ptr& operator=(const unique_ptr&) = delete;
     470             :   };
     471             : 
     472             :   /// 20.7.1.3 unique_ptr for array objects with a runtime length
     473             :   // [unique.ptr.runtime]
     474             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     475             :   // DR 740 - omit specialization for array objects with a compile time length
     476             :   template<typename _Tp, typename _Dp>
     477             :     class unique_ptr<_Tp[], _Dp>
     478             :     {
     479             :       template <typename _Up>
     480             :       using _DeleterConstraint =
     481             :         typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     482             : 
     483             :       __uniq_ptr_data<_Tp, _Dp> _M_t;
     484             : 
     485             :       template<typename _Up>
     486             :         using __remove_cv = typename remove_cv<_Up>::type;
     487             : 
     488             :       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
     489             :       template<typename _Up>
     490             :         using __is_derived_Tp
     491             :           = __and_< is_base_of<_Tp, _Up>,
     492             :                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
     493             : 
     494             :     public:
     495             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     496             :       using element_type  = _Tp;
     497             :       using deleter_type  = _Dp;
     498             : 
     499             :       // helper template for detecting a safe conversion from another
     500             :       // unique_ptr
     501             :       template<typename _Up, typename _Ep,
     502             :                typename _UPtr = unique_ptr<_Up, _Ep>,
     503             :                typename _UP_pointer = typename _UPtr::pointer,
     504             :                typename _UP_element_type = typename _UPtr::element_type>
     505             :         using __safe_conversion_up = __and_<
     506             :           is_array<_Up>,
     507             :           is_same<pointer, element_type*>,
     508             :           is_same<_UP_pointer, _UP_element_type*>,
     509             :           is_convertible<_UP_element_type(*)[], element_type(*)[]>
     510             :         >;
     511             : 
     512             :       // helper template for detecting a safe conversion from a raw pointer
     513             :       template<typename _Up>
     514             :         using __safe_conversion_raw = __and_<
     515             :           __or_<__or_<is_same<_Up, pointer>,
     516             :                       is_same<_Up, nullptr_t>>,
     517             :                 __and_<is_pointer<_Up>,
     518             :                        is_same<pointer, element_type*>,
     519             :                        is_convertible<
     520             :                          typename remove_pointer<_Up>::type(*)[],
     521             :                          element_type(*)[]>
     522             :                 >
     523             :           >
     524             :         >;
     525             : 
     526             :       // Constructors.
     527             : 
     528             :       /// Default constructor, creates a unique_ptr that owns nothing.
     529             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     530          26 :         constexpr unique_ptr() noexcept
     531          26 :         : _M_t()
     532          26 :         { }
     533             : 
     534             :       /** Takes ownership of a pointer.
     535             :        *
     536             :        * @param __p  A pointer to an array of a type safely convertible
     537             :        * to an array of @c element_type
     538             :        *
     539             :        * The deleter will be value-initialized.
     540             :        */
     541             :       template<typename _Up,
     542             :                typename _Vp = _Dp,
     543             :                typename = _DeleterConstraint<_Vp>,
     544             :                typename = typename enable_if<
     545             :                  __safe_conversion_raw<_Up>::value, bool>::type>
     546             :         explicit
     547           0 :         unique_ptr(_Up __p) noexcept
     548           0 :         : _M_t(__p)
     549           0 :         { }
     550             : 
     551             :       /** Takes ownership of a pointer.
     552             :        *
     553             :        * @param __p  A pointer to an array of a type safely convertible
     554             :        * to an array of @c element_type
     555             :        * @param __d  A reference to a deleter.
     556             :        *
     557             :        * The deleter will be initialized with @p __d
     558             :        */
     559             :       template<typename _Up, typename _Del = deleter_type,
     560             :                typename = _Require<__safe_conversion_raw<_Up>,
     561             :                                    is_copy_constructible<_Del>>>
     562             :       unique_ptr(_Up __p, const deleter_type& __d) noexcept
     563             :       : _M_t(__p, __d) { }
     564             : 
     565             :       /** Takes ownership of a pointer.
     566             :        *
     567             :        * @param __p  A pointer to an array of a type safely convertible
     568             :        * to an array of @c element_type
     569             :        * @param __d  A reference to a deleter.
     570             :        *
     571             :        * The deleter will be initialized with @p std::move(__d)
     572             :        */
     573             :       template<typename _Up, typename _Del = deleter_type,
     574             :                typename = _Require<__safe_conversion_raw<_Up>,
     575             :                                    is_move_constructible<_Del>>>
     576             :         unique_ptr(_Up __p,
     577             :                    __enable_if_t<!is_lvalue_reference<_Del>::value,
     578             :                                  _Del&&> __d) noexcept
     579             :         : _M_t(std::move(__p), std::move(__d))
     580             :         { }
     581             : 
     582             :       template<typename _Up, typename _Del = deleter_type,
     583             :                typename _DelUnref = typename remove_reference<_Del>::type,
     584             :                typename = _Require<__safe_conversion_raw<_Up>>>
     585             :         unique_ptr(_Up,
     586             :                    __enable_if_t<is_lvalue_reference<_Del>::value,
     587             :                                  _DelUnref&&>) = delete;
     588             : 
     589             :       /// Move constructor.
     590         130 :       unique_ptr(unique_ptr&&) = default;
     591             : 
     592             :       /// Creates a unique_ptr that owns nothing.
     593             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     594             :         constexpr unique_ptr(nullptr_t) noexcept
     595             :         : _M_t()
     596             :         { }
     597             : 
     598             :       template<typename _Up, typename _Ep, typename = _Require<
     599             :                __safe_conversion_up<_Up, _Ep>,
     600             :                typename conditional<is_reference<_Dp>::value,
     601             :                                     is_same<_Ep, _Dp>,
     602             :                                     is_convertible<_Ep, _Dp>>::type>>
     603             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     604             :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     605             :         { }
     606             : 
     607             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     608         169 :       ~unique_ptr()
     609             :       {
     610         169 :         auto& __ptr = _M_t._M_ptr();
     611         169 :         if (__ptr != nullptr)
     612          13 :           get_deleter()(__ptr);
     613         169 :         __ptr = pointer();
     614         169 :       }
     615             : 
     616             :       // Assignment.
     617             : 
     618             :       /** @brief Move assignment operator.
     619             :        *
     620             :        * Invokes the deleter if this object owns a pointer.
     621             :        */
     622             :       unique_ptr&
     623          13 :       operator=(unique_ptr&&) = default;
     624             : 
     625             :       /** @brief Assignment from another type.
     626             :        *
     627             :        * @param __u  The object to transfer ownership from, which owns a
     628             :        *             convertible pointer to an array object.
     629             :        *
     630             :        * Invokes the deleter if this object owns a pointer.
     631             :        */
     632             :       template<typename _Up, typename _Ep>
     633             :         typename
     634             :         enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
     635             :                          is_assignable<deleter_type&, _Ep&&>
     636             :                   >::value,
     637             :                   unique_ptr&>::type
     638             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     639             :         {
     640             :           reset(__u.release());
     641             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     642             :           return *this;
     643             :         }
     644             : 
     645             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     646             :       unique_ptr&
     647             :       operator=(nullptr_t) noexcept
     648             :       {
     649             :         reset();
     650             :         return *this;
     651             :       }
     652             : 
     653             :       // Observers.
     654             : 
     655             :       /// Access an element of owned array.
     656             :       typename std::add_lvalue_reference<element_type>::type
     657           0 :       operator[](size_t __i) const
     658             :       {
     659           0 :         __glibcxx_assert(get() != pointer());
     660           0 :         return get()[__i];
     661             :       }
     662             : 
     663             :       /// Return the stored pointer.
     664             :       pointer
     665          61 :       get() const noexcept
     666          61 :       { return _M_t._M_ptr(); }
     667             : 
     668             :       /// Return a reference to the stored deleter.
     669             :       deleter_type&
     670          13 :       get_deleter() noexcept
     671          13 :       { return _M_t._M_deleter(); }
     672             : 
     673             :       /// Return a reference to the stored deleter.
     674             :       const deleter_type&
     675             :       get_deleter() const noexcept
     676             :       { return _M_t._M_deleter(); }
     677             : 
     678             :       /// Return @c true if the stored pointer is not null.
     679             :       explicit operator bool() const noexcept
     680             :       { return get() == pointer() ? false : true; }
     681             : 
     682             :       // Modifiers.
     683             : 
     684             :       /// Release ownership of any stored pointer.
     685             :       pointer
     686             :       release() noexcept
     687             :       { return _M_t.release(); }
     688             : 
     689             :       /** @brief Replace the stored pointer.
     690             :        *
     691             :        * @param __p  The new pointer to store.
     692             :        *
     693             :        * The deleter will be invoked if a pointer is already owned.
     694             :        */
     695             :       template <typename _Up,
     696             :                 typename = _Require<
     697             :                   __or_<is_same<_Up, pointer>,
     698             :                         __and_<is_same<pointer, element_type*>,
     699             :                                is_pointer<_Up>,
     700             :                                is_convertible<
     701             :                                  typename remove_pointer<_Up>::type(*)[],
     702             :                                  element_type(*)[]
     703             :                                >
     704             :                         >
     705             :                   >
     706             :                >>
     707             :       void
     708          13 :       reset(_Up __p) noexcept
     709          13 :       { _M_t.reset(std::move(__p)); }
     710             : 
     711             :       void reset(nullptr_t = nullptr) noexcept
     712             :       { reset(pointer()); }
     713             : 
     714             :       /// Exchange the pointer and deleter with another object.
     715             :       void
     716             :       swap(unique_ptr& __u) noexcept
     717             :       {
     718             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     719             :         _M_t.swap(__u._M_t);
     720             :       }
     721             : 
     722             :       // Disable copy from lvalue.
     723             :       unique_ptr(const unique_ptr&) = delete;
     724             :       unique_ptr& operator=(const unique_ptr&) = delete;
     725             :     };
     726             : 
     727             :   /// @relates unique_ptr @{
     728             : 
     729             :   /// Swap overload for unique_ptr
     730             :   template<typename _Tp, typename _Dp>
     731             :     inline
     732             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     733             :     // Constrained free swap overload, see p0185r1
     734             :     typename enable_if<__is_swappable<_Dp>::value>::type
     735             : #else
     736             :     void
     737             : #endif
     738             :     swap(unique_ptr<_Tp, _Dp>& __x,
     739             :          unique_ptr<_Tp, _Dp>& __y) noexcept
     740             :     { __x.swap(__y); }
     741             : 
     742             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     743             :   template<typename _Tp, typename _Dp>
     744             :     typename enable_if<!__is_swappable<_Dp>::value>::type
     745             :     swap(unique_ptr<_Tp, _Dp>&,
     746             :          unique_ptr<_Tp, _Dp>&) = delete;
     747             : #endif
     748             : 
     749             :   /// Equality operator for unique_ptr objects, compares the owned pointers
     750             :   template<typename _Tp, typename _Dp,
     751             :            typename _Up, typename _Ep>
     752             :     _GLIBCXX_NODISCARD inline bool
     753         179 :     operator==(const unique_ptr<_Tp, _Dp>& __x,
     754             :                const unique_ptr<_Up, _Ep>& __y)
     755         179 :     { return __x.get() == __y.get(); }
     756             : 
     757             :   /// unique_ptr comparison with nullptr
     758             :   template<typename _Tp, typename _Dp>
     759             :     _GLIBCXX_NODISCARD inline bool
     760             :     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     761             :     { return !__x; }
     762             : 
     763             : #ifndef __cpp_lib_three_way_comparison
     764             :   /// unique_ptr comparison with nullptr
     765             :   template<typename _Tp, typename _Dp>
     766             :     _GLIBCXX_NODISCARD inline bool
     767             :     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     768             :     { return !__x; }
     769             : 
     770             :   /// Inequality operator for unique_ptr objects, compares the owned pointers
     771             :   template<typename _Tp, typename _Dp,
     772             :            typename _Up, typename _Ep>
     773             :     _GLIBCXX_NODISCARD inline bool
     774             :     operator!=(const unique_ptr<_Tp, _Dp>& __x,
     775             :                const unique_ptr<_Up, _Ep>& __y)
     776             :     { return __x.get() != __y.get(); }
     777             : 
     778             :   /// unique_ptr comparison with nullptr
     779             :   template<typename _Tp, typename _Dp>
     780             :     _GLIBCXX_NODISCARD inline bool
     781           7 :     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     782           7 :     { return (bool)__x; }
     783             : 
     784             :   /// unique_ptr comparison with nullptr
     785             :   template<typename _Tp, typename _Dp>
     786             :     _GLIBCXX_NODISCARD inline bool
     787             :     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     788             :     { return (bool)__x; }
     789             : #endif // three way comparison
     790             : 
     791             :   /// Relational operator for unique_ptr objects, compares the owned pointers
     792             :   template<typename _Tp, typename _Dp,
     793             :            typename _Up, typename _Ep>
     794             :     _GLIBCXX_NODISCARD inline bool
     795             :     operator<(const unique_ptr<_Tp, _Dp>& __x,
     796             :               const unique_ptr<_Up, _Ep>& __y)
     797             :     {
     798             :       typedef typename
     799             :         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
     800             :                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
     801             :       return std::less<_CT>()(__x.get(), __y.get());
     802             :     }
     803             : 
     804             :   /// unique_ptr comparison with nullptr
     805             :   template<typename _Tp, typename _Dp>
     806             :     _GLIBCXX_NODISCARD inline bool
     807             :     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     808             :     {
     809             :       return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     810             :                                                                  nullptr);
     811             :     }
     812             : 
     813             :   /// unique_ptr comparison with nullptr
     814             :   template<typename _Tp, typename _Dp>
     815             :     _GLIBCXX_NODISCARD inline bool
     816             :     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     817             :     {
     818             :       return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     819             :                                                                  __x.get());
     820             :     }
     821             : 
     822             :   /// Relational operator for unique_ptr objects, compares the owned pointers
     823             :   template<typename _Tp, typename _Dp,
     824             :            typename _Up, typename _Ep>
     825             :     _GLIBCXX_NODISCARD inline bool
     826             :     operator<=(const unique_ptr<_Tp, _Dp>& __x,
     827             :                const unique_ptr<_Up, _Ep>& __y)
     828             :     { return !(__y < __x); }
     829             : 
     830             :   /// unique_ptr comparison with nullptr
     831             :   template<typename _Tp, typename _Dp>
     832             :     _GLIBCXX_NODISCARD inline bool
     833             :     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     834             :     { return !(nullptr < __x); }
     835             : 
     836             :   /// unique_ptr comparison with nullptr
     837             :   template<typename _Tp, typename _Dp>
     838             :     _GLIBCXX_NODISCARD inline bool
     839             :     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     840             :     { return !(__x < nullptr); }
     841             : 
     842             :   /// Relational operator for unique_ptr objects, compares the owned pointers
     843             :   template<typename _Tp, typename _Dp,
     844             :            typename _Up, typename _Ep>
     845             :     _GLIBCXX_NODISCARD inline bool
     846             :     operator>(const unique_ptr<_Tp, _Dp>& __x,
     847             :               const unique_ptr<_Up, _Ep>& __y)
     848             :     { return (__y < __x); }
     849             : 
     850             :   /// unique_ptr comparison with nullptr
     851             :   template<typename _Tp, typename _Dp>
     852             :     _GLIBCXX_NODISCARD inline bool
     853             :     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     854             :     {
     855             :       return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     856             :                                                                  __x.get());
     857             :     }
     858             : 
     859             :   /// unique_ptr comparison with nullptr
     860             :   template<typename _Tp, typename _Dp>
     861             :     _GLIBCXX_NODISCARD inline bool
     862             :     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     863             :     {
     864             :       return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     865             :                                                                  nullptr);
     866             :     }
     867             : 
     868             :   /// Relational operator for unique_ptr objects, compares the owned pointers
     869             :   template<typename _Tp, typename _Dp,
     870             :            typename _Up, typename _Ep>
     871             :     _GLIBCXX_NODISCARD inline bool
     872             :     operator>=(const unique_ptr<_Tp, _Dp>& __x,
     873             :                const unique_ptr<_Up, _Ep>& __y)
     874             :     { return !(__x < __y); }
     875             : 
     876             :   /// unique_ptr comparison with nullptr
     877             :   template<typename _Tp, typename _Dp>
     878             :     _GLIBCXX_NODISCARD inline bool
     879             :     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     880             :     { return !(__x < nullptr); }
     881             : 
     882             :   /// unique_ptr comparison with nullptr
     883             :   template<typename _Tp, typename _Dp>
     884             :     _GLIBCXX_NODISCARD inline bool
     885             :     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     886             :     { return !(nullptr < __x); }
     887             : 
     888             : #ifdef __cpp_lib_three_way_comparison
     889             :   template<typename _Tp, typename _Dp, typename _Up, typename _Ep>
     890             :     requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
     891             :                                        typename unique_ptr<_Up, _Ep>::pointer>
     892             :     inline
     893             :     compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
     894             :                                typename unique_ptr<_Up, _Ep>::pointer>
     895             :     operator<=>(const unique_ptr<_Tp, _Dp>& __x,
     896             :                 const unique_ptr<_Up, _Ep>& __y)
     897             :     { return compare_three_way()(__x.get(), __y.get()); }
     898             : 
     899             :   template<typename _Tp, typename _Dp>
     900             :     requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
     901             :     inline
     902             :     compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
     903             :     operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     904             :     {
     905             :       using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
     906             :       return compare_three_way()(__x.get(), static_cast<pointer>(nullptr));
     907             :     }
     908             : #endif
     909             :   /// @} relates unique_ptr
     910             : 
     911             :   /// @cond undocumented
     912             :   template<typename _Up, typename _Ptr = typename _Up::pointer,
     913             :            bool = __poison_hash<_Ptr>::__enable_hash_call>
     914             :     struct __uniq_ptr_hash
     915             : #if ! _GLIBCXX_INLINE_VERSION
     916             :     : private __poison_hash<_Ptr>
     917             : #endif
     918             :     {
     919             :       size_t
     920             :       operator()(const _Up& __u) const
     921             :       noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
     922             :       { return hash<_Ptr>()(__u.get()); }
     923             :     };
     924             : 
     925             :   template<typename _Up, typename _Ptr>
     926             :     struct __uniq_ptr_hash<_Up, _Ptr, false>
     927             :     : private __poison_hash<_Ptr>
     928             :     { };
     929             :   /// @endcond
     930             : 
     931             :   /// std::hash specialization for unique_ptr.
     932             :   template<typename _Tp, typename _Dp>
     933             :     struct hash<unique_ptr<_Tp, _Dp>>
     934             :     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
     935             :       public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
     936             :     { };
     937             : 
     938             : #if __cplusplus >= 201402L
     939             :   /// @relates unique_ptr @{
     940             : #define __cpp_lib_make_unique 201304
     941             : 
     942             :   /// @cond undocumented
     943             : 
     944             :   template<typename _Tp>
     945             :     struct _MakeUniq
     946             :     { typedef unique_ptr<_Tp> __single_object; };
     947             : 
     948             :   template<typename _Tp>
     949             :     struct _MakeUniq<_Tp[]>
     950             :     { typedef unique_ptr<_Tp[]> __array; };
     951             : 
     952             :   template<typename _Tp, size_t _Bound>
     953             :     struct _MakeUniq<_Tp[_Bound]>
     954             :     { struct __invalid_type { }; };
     955             : 
     956             :   /// @endcond
     957             : 
     958             :   /// std::make_unique for single objects
     959             :   template<typename _Tp, typename... _Args>
     960             :     inline typename _MakeUniq<_Tp>::__single_object
     961       28373 :     make_unique(_Args&&... __args)
     962       28375 :     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
     963             : 
     964             :   /// std::make_unique for arrays of unknown bound
     965             :   template<typename _Tp>
     966             :     inline typename _MakeUniq<_Tp>::__array
     967             :     make_unique(size_t __num)
     968             :     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
     969             : 
     970             :   /// Disable std::make_unique for arrays of known bound
     971             :   template<typename _Tp, typename... _Args>
     972             :     typename _MakeUniq<_Tp>::__invalid_type
     973             :     make_unique(_Args&&...) = delete;
     974             : 
     975             : #if __cplusplus > 201703L
     976             :   /// std::make_unique_for_overwrite for single objects
     977             :   template<typename _Tp>
     978             :     inline typename _MakeUniq<_Tp>::__single_object
     979             :     make_unique_for_overwrite()
     980             :     { return unique_ptr<_Tp>(new _Tp); }
     981             : 
     982             :   /// std::make_unique_for_overwrite for arrays of unknown bound
     983             :   template<typename _Tp>
     984             :     inline typename _MakeUniq<_Tp>::__array
     985             :     make_unique_for_overwrite(size_t __n)
     986             :     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__n]); }
     987             : 
     988             :   /// Disable std::make_unique_for_overwrite for arrays of known bound
     989             :   template<typename _Tp, typename... _Args>
     990             :     typename _MakeUniq<_Tp>::__invalid_type
     991             :     make_unique_for_overwrite(_Args&&...) = delete;
     992             : #endif // C++20
     993             : 
     994             :   /// @} relates unique_ptr
     995             : #endif // C++14
     996             : 
     997             : #if __cplusplus > 201703L && __cpp_concepts
     998             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     999             :   // 2948. unique_ptr does not define operator<< for stream output
    1000             :   /// Stream output operator for unique_ptr
    1001             :   template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
    1002             :     inline basic_ostream<_CharT, _Traits>&
    1003             :     operator<<(basic_ostream<_CharT, _Traits>& __os,
    1004             :                const unique_ptr<_Tp, _Dp>& __p)
    1005             :     requires requires { __os << __p.get(); }
    1006             :     {
    1007             :       __os << __p.get();
    1008             :       return __os;
    1009             :     }
    1010             : #endif // C++20
    1011             : 
    1012             :   /// @} group pointer_abstractions
    1013             : 
    1014             : #if __cplusplus >= 201703L
    1015             :   namespace __detail::__variant
    1016             :   {
    1017             :     template<typename> struct _Never_valueless_alt; // see <variant>
    1018             : 
    1019             :     // Provide the strong exception-safety guarantee when emplacing a
    1020             :     // unique_ptr into a variant.
    1021             :     template<typename _Tp, typename _Del>
    1022             :       struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
    1023             :       : std::true_type
    1024             :       { };
    1025             :   }  // namespace __detail::__variant
    1026             : #endif // C++17
    1027             : 
    1028             : _GLIBCXX_END_NAMESPACE_VERSION
    1029             : } // namespace
    1030             : 
    1031             : #endif /* _UNIQUE_PTR_H */

Generated by: LCOV version 1.14