LCOV - code coverage report
Current view: top level - usr/include/c++/9/bits - unique_ptr.h (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 43 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : // unique_ptr implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2008-2019 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @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             : 
      41             : namespace std _GLIBCXX_VISIBILITY(default)
      42             : {
      43             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      44             : 
      45             :   /**
      46             :    * @addtogroup pointer_abstractions
      47             :    * @{
      48             :    */
      49             : 
      50             : #if _GLIBCXX_USE_DEPRECATED
      51             : #pragma GCC diagnostic push
      52             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      53             :   template<typename> class auto_ptr;
      54             : #pragma GCC diagnostic pop
      55             : #endif
      56             : 
      57             :   /// Primary template of default_delete, used by unique_ptr
      58             :   template<typename _Tp>
      59             :     struct default_delete
      60             :     {
      61             :       /// Default constructor
      62             :       constexpr default_delete() noexcept = default;
      63             : 
      64             :       /** @brief Converting constructor.
      65             :        *
      66             :        * Allows conversion from a deleter for arrays of another type, @p _Up,
      67             :        * only if @p _Up* is convertible to @p _Tp*.
      68             :        */
      69             :       template<typename _Up, typename = typename
      70             :                enable_if<is_convertible<_Up*, _Tp*>::value>::type>
      71             :         default_delete(const default_delete<_Up>&) noexcept { }
      72             : 
      73             :       /// Calls @c delete @p __ptr
      74             :       void
      75           0 :       operator()(_Tp* __ptr) const
      76             :       {
      77             :         static_assert(!is_void<_Tp>::value,
      78             :                       "can't delete pointer to incomplete type");
      79             :         static_assert(sizeof(_Tp)>0,
      80             :                       "can't delete pointer to incomplete type");
      81           0 :         delete __ptr;
      82           0 :       }
      83             :     };
      84             : 
      85             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
      86             :   // DR 740 - omit specialization for array objects with a compile time length
      87             :   /// Specialization for arrays, default_delete.
      88             :   template<typename _Tp>
      89             :     struct default_delete<_Tp[]>
      90             :     {
      91             :     public:
      92             :       /// Default constructor
      93             :       constexpr default_delete() noexcept = default;
      94             : 
      95             :       /** @brief Converting constructor.
      96             :        *
      97             :        * Allows conversion from a deleter for arrays of another type, such as
      98             :        * a const-qualified version of @p _Tp.
      99             :        *
     100             :        * Conversions from types derived from @c _Tp are not allowed because
     101             :        * it is unsafe to @c delete[] an array of derived types through a
     102             :        * pointer to the base type.
     103             :        */
     104             :       template<typename _Up, typename = typename
     105             :                enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
     106             :         default_delete(const default_delete<_Up[]>&) noexcept { }
     107             : 
     108             :       /// Calls @c delete[] @p __ptr
     109             :       template<typename _Up>
     110             :       typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
     111           0 :         operator()(_Up* __ptr) const
     112             :       {
     113             :         static_assert(sizeof(_Tp)>0,
     114             :                       "can't delete pointer to incomplete type");
     115           0 :         delete [] __ptr;
     116             :       }
     117             :     };
     118             : 
     119             :   template <typename _Tp, typename _Dp>
     120             :     class __uniq_ptr_impl
     121             :     {
     122             :       template <typename _Up, typename _Ep, typename = void>
     123             :         struct _Ptr
     124             :         {
     125             :           using type = _Up*;
     126             :         };
     127             : 
     128             :       template <typename _Up, typename _Ep>
     129             :         struct
     130             :         _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
     131             :         {
     132             :           using type = typename remove_reference<_Ep>::type::pointer;
     133             :         };
     134             : 
     135             :     public:
     136             :       using _DeleterConstraint = enable_if<
     137             :         __and_<__not_<is_pointer<_Dp>>,
     138             :                is_default_constructible<_Dp>>::value>;
     139             : 
     140             :       using pointer = typename _Ptr<_Tp, _Dp>::type;
     141             : 
     142             :       static_assert( !is_rvalue_reference<_Dp>::value,
     143             :                      "unique_ptr's deleter type must be a function object type"
     144             :                      " or an lvalue reference type" );
     145             : 
     146             :       __uniq_ptr_impl() = default;
     147           0 :       __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
     148             : 
     149             :       template<typename _Del>
     150           0 :       __uniq_ptr_impl(pointer __p, _Del&& __d)
     151           0 :         : _M_t(__p, std::forward<_Del>(__d)) { }
     152             : 
     153           0 :       pointer&   _M_ptr() { return std::get<0>(_M_t); }
     154           0 :       pointer    _M_ptr() const { return std::get<0>(_M_t); }
     155           0 :       _Dp&       _M_deleter() { return std::get<1>(_M_t); }
     156             :       const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
     157             : 
     158             :       void
     159             :       swap(__uniq_ptr_impl& __rhs) noexcept
     160             :       {
     161             :         using std::swap;
     162             :         swap(this->_M_ptr(), __rhs._M_ptr());
     163             :         swap(this->_M_deleter(), __rhs._M_deleter());
     164             :       }
     165             : 
     166             :     private:
     167             :       tuple<pointer, _Dp> _M_t;
     168             :     };
     169             : 
     170             :   /// 20.7.1.2 unique_ptr for single objects.
     171             :   template <typename _Tp, typename _Dp = default_delete<_Tp>>
     172             :     class unique_ptr
     173             :     {
     174             :       template <typename _Up>
     175             :         using _DeleterConstraint =
     176             :           typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     177             : 
     178             :       __uniq_ptr_impl<_Tp, _Dp> _M_t;
     179             : 
     180             :     public:
     181             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     182             :       using element_type  = _Tp;
     183             :       using deleter_type  = _Dp;
     184             : 
     185             :     private:
     186             :       // helper template for detecting a safe conversion from another
     187             :       // unique_ptr
     188             :       template<typename _Up, typename _Ep>
     189             :         using __safe_conversion_up = __and_<
     190             :           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
     191             :           __not_<is_array<_Up>>
     192             :         >;
     193             : 
     194             :     public:
     195             :       // Constructors.
     196             : 
     197             :       /// Default constructor, creates a unique_ptr that owns nothing.
     198             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     199             :         constexpr unique_ptr() noexcept
     200             :         : _M_t()
     201             :         { }
     202             : 
     203             :       /** Takes ownership of a pointer.
     204             :        *
     205             :        * @param __p  A pointer to an object of @c element_type
     206             :        *
     207             :        * The deleter will be value-initialized.
     208             :        */
     209             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     210             :         explicit
     211           0 :         unique_ptr(pointer __p) noexcept
     212           0 :         : _M_t(__p)
     213             :         { }
     214             : 
     215             :       /** Takes ownership of a pointer.
     216             :        *
     217             :        * @param __p  A pointer to an object of @c element_type
     218             :        * @param __d  A reference to a deleter.
     219             :        *
     220             :        * The deleter will be initialized with @p __d
     221             :        */
     222             :       template<typename _Del = deleter_type,
     223             :                typename = _Require<is_copy_constructible<_Del>>>
     224             :         unique_ptr(pointer __p, const deleter_type& __d) noexcept
     225             :         : _M_t(__p, __d) { }
     226             : 
     227             :       /** Takes ownership of a pointer.
     228             :        *
     229             :        * @param __p  A pointer to an object of @c element_type
     230             :        * @param __d  An rvalue reference to a (non-reference) deleter.
     231             :        *
     232             :        * The deleter will be initialized with @p std::move(__d)
     233             :        */
     234             :       template<typename _Del = deleter_type,
     235             :                typename = _Require<is_move_constructible<_Del>>>
     236             :         unique_ptr(pointer __p,
     237             :                    __enable_if_t<!is_lvalue_reference<_Del>::value,
     238             :                                  _Del&&> __d) noexcept
     239             :         : _M_t(__p, std::move(__d))
     240             :         { }
     241             : 
     242             :       template<typename _Del = deleter_type,
     243             :                typename _DelUnref = typename remove_reference<_Del>::type>
     244             :         unique_ptr(pointer,
     245             :                    __enable_if_t<is_lvalue_reference<_Del>::value,
     246             :                                  _DelUnref&&>) = delete;
     247             : 
     248             :       /// Creates a unique_ptr that owns nothing.
     249             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     250             :         constexpr unique_ptr(nullptr_t) noexcept
     251             :         : _M_t()
     252             :         { }
     253             : 
     254             :       // Move constructors.
     255             : 
     256             :       /// Move constructor.
     257           0 :       unique_ptr(unique_ptr&& __u) noexcept
     258           0 :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     259             : 
     260             :       /** @brief Converting constructor from another type
     261             :        *
     262             :        * Requires that the pointer owned by @p __u is convertible to the
     263             :        * type of pointer owned by this object, @p __u does not own an array,
     264             :        * and @p __u has a compatible deleter type.
     265             :        */
     266             :       template<typename _Up, typename _Ep, typename = _Require<
     267             :                __safe_conversion_up<_Up, _Ep>,
     268             :                typename conditional<is_reference<_Dp>::value,
     269             :                                     is_same<_Ep, _Dp>,
     270             :                                     is_convertible<_Ep, _Dp>>::type>>
     271             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     272             :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     273             :         { }
     274             : 
     275             : #if _GLIBCXX_USE_DEPRECATED
     276             : #pragma GCC diagnostic push
     277             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     278             :       /// Converting constructor from @c auto_ptr
     279             :       template<typename _Up, typename = _Require<
     280             :                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
     281             :         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
     282             : #pragma GCC diagnostic pop
     283             : #endif
     284             : 
     285             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     286           0 :       ~unique_ptr() noexcept
     287             :       {
     288             :         static_assert(__is_invocable<deleter_type&, pointer>::value,
     289             :                       "unique_ptr's deleter must be invocable with a pointer");
     290           0 :         auto& __ptr = _M_t._M_ptr();
     291           0 :         if (__ptr != nullptr)
     292           0 :           get_deleter()(std::move(__ptr));
     293             :         __ptr = pointer();
     294           0 :       }
     295             : 
     296             :       // Assignment.
     297             : 
     298             :       /** @brief Move assignment operator.
     299             :        *
     300             :        * @param __u  The object to transfer ownership from.
     301             :        *
     302             :        * Invokes the deleter first if this object owns a pointer.
     303             :        */
     304             :       unique_ptr&
     305             :       operator=(unique_ptr&& __u) noexcept
     306             :       {
     307             :         reset(__u.release());
     308             :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     309             :         return *this;
     310             :       }
     311             : 
     312             :       /** @brief Assignment from another type.
     313             :        *
     314             :        * @param __u  The object to transfer ownership from, which owns a
     315             :        *             convertible pointer to a non-array object.
     316             :        *
     317             :        * Invokes the deleter first if this object owns a pointer.
     318             :        */
     319             :       template<typename _Up, typename _Ep>
     320             :         typename enable_if< __and_<
     321             :           __safe_conversion_up<_Up, _Ep>,
     322             :           is_assignable<deleter_type&, _Ep&&>
     323             :           >::value,
     324             :           unique_ptr&>::type
     325             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     326             :         {
     327             :           reset(__u.release());
     328             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     329             :           return *this;
     330             :         }
     331             : 
     332             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     333             :       unique_ptr&
     334             :       operator=(nullptr_t) noexcept
     335             :       {
     336             :         reset();
     337             :         return *this;
     338             :       }
     339             : 
     340             :       // Observers.
     341             : 
     342             :       /// Dereference the stored pointer.
     343             :       typename add_lvalue_reference<element_type>::type
     344           0 :       operator*() const
     345             :       {
     346             :         __glibcxx_assert(get() != pointer());
     347           0 :         return *get();
     348             :       }
     349             : 
     350             :       /// Return the stored pointer.
     351             :       pointer
     352             :       operator->() const noexcept
     353             :       {
     354             :         _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
     355             :         return get();
     356             :       }
     357             : 
     358             :       /// Return the stored pointer.
     359             :       pointer
     360           0 :       get() const noexcept
     361           0 :       { return _M_t._M_ptr(); }
     362             : 
     363             :       /// Return a reference to the stored deleter.
     364             :       deleter_type&
     365           0 :       get_deleter() noexcept
     366           0 :       { return _M_t._M_deleter(); }
     367             : 
     368             :       /// Return a reference to the stored deleter.
     369             :       const deleter_type&
     370             :       get_deleter() const noexcept
     371             :       { return _M_t._M_deleter(); }
     372             : 
     373             :       /// Return @c true if the stored pointer is not null.
     374             :       explicit operator bool() const noexcept
     375             :       { return get() == pointer() ? false : true; }
     376             : 
     377             :       // Modifiers.
     378             : 
     379             :       /// Release ownership of any stored pointer.
     380             :       pointer
     381           0 :       release() noexcept
     382             :       {
     383           0 :         pointer __p = get();
     384           0 :         _M_t._M_ptr() = pointer();
     385             :         return __p;
     386             :       }
     387             : 
     388             :       /** @brief Replace the stored pointer.
     389             :        *
     390             :        * @param __p  The new pointer to store.
     391             :        *
     392             :        * The deleter will be invoked if a pointer is already owned.
     393             :        */
     394             :       void
     395             :       reset(pointer __p = pointer()) noexcept
     396             :       {
     397             :         static_assert(__is_invocable<deleter_type&, pointer>::value,
     398             :                       "unique_ptr's deleter must be invocable with a pointer");
     399             :         using std::swap;
     400             :         swap(_M_t._M_ptr(), __p);
     401             :         if (__p != pointer())
     402             :           get_deleter()(std::move(__p));
     403             :       }
     404             : 
     405             :       /// Exchange the pointer and deleter with another object.
     406             :       void
     407             :       swap(unique_ptr& __u) noexcept
     408             :       {
     409             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     410             :         _M_t.swap(__u._M_t);
     411             :       }
     412             : 
     413             :       // Disable copy from lvalue.
     414             :       unique_ptr(const unique_ptr&) = delete;
     415             :       unique_ptr& operator=(const unique_ptr&) = delete;
     416             :   };
     417             : 
     418             :   /// 20.7.1.3 unique_ptr for array objects with a runtime length
     419             :   // [unique.ptr.runtime]
     420             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     421             :   // DR 740 - omit specialization for array objects with a compile time length
     422             :   template<typename _Tp, typename _Dp>
     423             :     class unique_ptr<_Tp[], _Dp>
     424             :     {
     425             :       template <typename _Up>
     426             :       using _DeleterConstraint =
     427             :         typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     428             : 
     429             :       __uniq_ptr_impl<_Tp, _Dp> _M_t;
     430             : 
     431             :       template<typename _Up>
     432             :         using __remove_cv = typename remove_cv<_Up>::type;
     433             : 
     434             :       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
     435             :       template<typename _Up>
     436             :         using __is_derived_Tp
     437             :           = __and_< is_base_of<_Tp, _Up>,
     438             :                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
     439             : 
     440             :     public:
     441             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     442             :       using element_type  = _Tp;
     443             :       using deleter_type  = _Dp;
     444             : 
     445             :       // helper template for detecting a safe conversion from another
     446             :       // unique_ptr
     447             :       template<typename _Up, typename _Ep,
     448             :                typename _UPtr = unique_ptr<_Up, _Ep>,
     449             :                typename _UP_pointer = typename _UPtr::pointer,
     450             :                typename _UP_element_type = typename _UPtr::element_type>
     451             :         using __safe_conversion_up = __and_<
     452             :           is_array<_Up>,
     453             :           is_same<pointer, element_type*>,
     454             :           is_same<_UP_pointer, _UP_element_type*>,
     455             :           is_convertible<_UP_element_type(*)[], element_type(*)[]>
     456             :         >;
     457             : 
     458             :       // helper template for detecting a safe conversion from a raw pointer
     459             :       template<typename _Up>
     460             :         using __safe_conversion_raw = __and_<
     461             :           __or_<__or_<is_same<_Up, pointer>,
     462             :                       is_same<_Up, nullptr_t>>,
     463             :                 __and_<is_pointer<_Up>,
     464             :                        is_same<pointer, element_type*>,
     465             :                        is_convertible<
     466             :                          typename remove_pointer<_Up>::type(*)[],
     467             :                          element_type(*)[]>
     468             :                 >
     469             :           >
     470             :         >;
     471             : 
     472             :       // Constructors.
     473             : 
     474             :       /// Default constructor, creates a unique_ptr that owns nothing.
     475             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     476             :         constexpr unique_ptr() noexcept
     477             :         : _M_t()
     478             :         { }
     479             : 
     480             :       /** Takes ownership of a pointer.
     481             :        *
     482             :        * @param __p  A pointer to an array of a type safely convertible
     483             :        * to an array of @c element_type
     484             :        *
     485             :        * The deleter will be value-initialized.
     486             :        */
     487             :       template<typename _Up,
     488             :                typename _Vp = _Dp,
     489             :                typename = _DeleterConstraint<_Vp>,
     490             :                typename = typename enable_if<
     491             :                  __safe_conversion_raw<_Up>::value, bool>::type>
     492             :         explicit
     493           0 :         unique_ptr(_Up __p) noexcept
     494           0 :         : _M_t(__p)
     495             :         { }
     496             : 
     497             :       /** Takes ownership of a pointer.
     498             :        *
     499             :        * @param __p  A pointer to an array of a type safely convertible
     500             :        * to an array of @c element_type
     501             :        * @param __d  A reference to a deleter.
     502             :        *
     503             :        * The deleter will be initialized with @p __d
     504             :        */
     505             :       template<typename _Up, typename _Del = deleter_type,
     506             :                typename = _Require<__safe_conversion_raw<_Up>,
     507             :                                    is_copy_constructible<_Del>>>
     508             :       unique_ptr(_Up __p, const deleter_type& __d) noexcept
     509             :       : _M_t(__p, __d) { }
     510             : 
     511             :       /** Takes ownership of a pointer.
     512             :        *
     513             :        * @param __p  A pointer to an array of a type safely convertible
     514             :        * to an array of @c element_type
     515             :        * @param __d  A reference to a deleter.
     516             :        *
     517             :        * The deleter will be initialized with @p std::move(__d)
     518             :        */
     519             :       template<typename _Up, typename _Del = deleter_type,
     520             :                typename = _Require<__safe_conversion_raw<_Up>,
     521             :                                    is_move_constructible<_Del>>>
     522             :         unique_ptr(_Up __p,
     523             :                    __enable_if_t<!is_lvalue_reference<_Del>::value,
     524             :                                  _Del&&> __d) noexcept
     525             :         : _M_t(std::move(__p), std::move(__d))
     526             :         { }
     527             : 
     528             :       template<typename _Up, typename _Del = deleter_type,
     529             :                typename _DelUnref = typename remove_reference<_Del>::type,
     530             :                typename = _Require<__safe_conversion_raw<_Up>>>
     531             :         unique_ptr(_Up,
     532             :                    __enable_if_t<is_lvalue_reference<_Del>::value,
     533             :                                  _DelUnref&&>) = delete;
     534             : 
     535             :       /// Move constructor.
     536             :       unique_ptr(unique_ptr&& __u) noexcept
     537             :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     538             : 
     539             :       /// Creates a unique_ptr that owns nothing.
     540             :       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
     541             :         constexpr unique_ptr(nullptr_t) noexcept
     542             :         : _M_t()
     543             :         { }
     544             : 
     545             :       template<typename _Up, typename _Ep, typename = _Require<
     546             :                __safe_conversion_up<_Up, _Ep>,
     547             :                typename conditional<is_reference<_Dp>::value,
     548             :                                     is_same<_Ep, _Dp>,
     549             :                                     is_convertible<_Ep, _Dp>>::type>>
     550             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     551             :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     552             :         { }
     553             : 
     554             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     555           0 :       ~unique_ptr()
     556             :       {
     557           0 :         auto& __ptr = _M_t._M_ptr();
     558             :         if (__ptr != nullptr)
     559           0 :           get_deleter()(__ptr);
     560             :         __ptr = pointer();
     561           0 :       }
     562             : 
     563             :       // Assignment.
     564             : 
     565             :       /** @brief Move assignment operator.
     566             :        *
     567             :        * @param __u  The object to transfer ownership from.
     568             :        *
     569             :        * Invokes the deleter first if this object owns a pointer.
     570             :        */
     571             :       unique_ptr&
     572             :       operator=(unique_ptr&& __u) noexcept
     573             :       {
     574             :         reset(__u.release());
     575             :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     576             :         return *this;
     577             :       }
     578             : 
     579             :       /** @brief Assignment from another type.
     580             :        *
     581             :        * @param __u  The object to transfer ownership from, which owns a
     582             :        *             convertible pointer to an array object.
     583             :        *
     584             :        * Invokes the deleter first if this object owns a pointer.
     585             :        */
     586             :       template<typename _Up, typename _Ep>
     587             :         typename
     588             :         enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
     589             :                          is_assignable<deleter_type&, _Ep&&>
     590             :                   >::value,
     591             :                   unique_ptr&>::type
     592             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     593             :         {
     594             :           reset(__u.release());
     595             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     596             :           return *this;
     597             :         }
     598             : 
     599             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     600             :       unique_ptr&
     601             :       operator=(nullptr_t) noexcept
     602             :       {
     603             :         reset();
     604             :         return *this;
     605             :       }
     606             : 
     607             :       // Observers.
     608             : 
     609             :       /// Access an element of owned array.
     610             :       typename std::add_lvalue_reference<element_type>::type
     611           0 :       operator[](size_t __i) const
     612             :       {
     613             :         __glibcxx_assert(get() != pointer());
     614           0 :         return get()[__i];
     615             :       }
     616             : 
     617             :       /// Return the stored pointer.
     618             :       pointer
     619           0 :       get() const noexcept
     620           0 :       { return _M_t._M_ptr(); }
     621             : 
     622             :       /// Return a reference to the stored deleter.
     623             :       deleter_type&
     624           0 :       get_deleter() noexcept
     625           0 :       { return _M_t._M_deleter(); }
     626             : 
     627             :       /// Return a reference to the stored deleter.
     628             :       const deleter_type&
     629             :       get_deleter() const noexcept
     630             :       { return _M_t._M_deleter(); }
     631             : 
     632             :       /// Return @c true if the stored pointer is not null.
     633             :       explicit operator bool() const noexcept
     634             :       { return get() == pointer() ? false : true; }
     635             : 
     636             :       // Modifiers.
     637             : 
     638             :       /// Release ownership of any stored pointer.
     639             :       pointer
     640             :       release() noexcept
     641             :       {
     642             :         pointer __p = get();
     643             :         _M_t._M_ptr() = pointer();
     644             :         return __p;
     645             :       }
     646             : 
     647             :       /** @brief Replace the stored pointer.
     648             :        *
     649             :        * @param __p  The new pointer to store.
     650             :        *
     651             :        * The deleter will be invoked if a pointer is already owned.
     652             :        */
     653             :       template <typename _Up,
     654             :                 typename = _Require<
     655             :                   __or_<is_same<_Up, pointer>,
     656             :                         __and_<is_same<pointer, element_type*>,
     657             :                                is_pointer<_Up>,
     658             :                                is_convertible<
     659             :                                  typename remove_pointer<_Up>::type(*)[],
     660             :                                  element_type(*)[]
     661             :                                >
     662             :                         >
     663             :                   >
     664             :                >>
     665             :       void
     666             :       reset(_Up __p) noexcept
     667             :       {
     668             :         pointer __ptr = __p;
     669             :         using std::swap;
     670             :         swap(_M_t._M_ptr(), __ptr);
     671             :         if (__ptr != nullptr)
     672             :           get_deleter()(__ptr);
     673             :       }
     674             : 
     675             :       void reset(nullptr_t = nullptr) noexcept
     676             :       {
     677             :         reset(pointer());
     678             :       }
     679             : 
     680             :       /// Exchange the pointer and deleter with another object.
     681             :       void
     682             :       swap(unique_ptr& __u) noexcept
     683             :       {
     684             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     685             :         _M_t.swap(__u._M_t);
     686             :       }
     687             : 
     688             :       // Disable copy from lvalue.
     689             :       unique_ptr(const unique_ptr&) = delete;
     690             :       unique_ptr& operator=(const unique_ptr&) = delete;
     691             :     };
     692             : 
     693             :   template<typename _Tp, typename _Dp>
     694             :     inline
     695             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     696             :     // Constrained free swap overload, see p0185r1
     697             :     typename enable_if<__is_swappable<_Dp>::value>::type
     698             : #else
     699             :     void
     700             : #endif
     701             :     swap(unique_ptr<_Tp, _Dp>& __x,
     702             :          unique_ptr<_Tp, _Dp>& __y) noexcept
     703             :     { __x.swap(__y); }
     704             : 
     705             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     706             :   template<typename _Tp, typename _Dp>
     707             :     typename enable_if<!__is_swappable<_Dp>::value>::type
     708             :     swap(unique_ptr<_Tp, _Dp>&,
     709             :          unique_ptr<_Tp, _Dp>&) = delete;
     710             : #endif
     711             : 
     712             :   template<typename _Tp, typename _Dp,
     713             :            typename _Up, typename _Ep>
     714             :     _GLIBCXX_NODISCARD inline bool
     715             :     operator==(const unique_ptr<_Tp, _Dp>& __x,
     716             :                const unique_ptr<_Up, _Ep>& __y)
     717             :     { return __x.get() == __y.get(); }
     718             : 
     719             :   template<typename _Tp, typename _Dp>
     720             :     _GLIBCXX_NODISCARD inline bool
     721             :     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     722             :     { return !__x; }
     723             : 
     724             :   template<typename _Tp, typename _Dp>
     725             :     _GLIBCXX_NODISCARD inline bool
     726             :     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     727             :     { return !__x; }
     728             : 
     729             :   template<typename _Tp, typename _Dp,
     730             :            typename _Up, typename _Ep>
     731             :     _GLIBCXX_NODISCARD inline bool
     732             :     operator!=(const unique_ptr<_Tp, _Dp>& __x,
     733             :                const unique_ptr<_Up, _Ep>& __y)
     734             :     { return __x.get() != __y.get(); }
     735             : 
     736             :   template<typename _Tp, typename _Dp>
     737             :     _GLIBCXX_NODISCARD inline bool
     738             :     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     739             :     { return (bool)__x; }
     740             : 
     741             :   template<typename _Tp, typename _Dp>
     742             :     _GLIBCXX_NODISCARD inline bool
     743             :     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     744             :     { return (bool)__x; }
     745             : 
     746             :   template<typename _Tp, typename _Dp,
     747             :            typename _Up, typename _Ep>
     748             :     _GLIBCXX_NODISCARD inline bool
     749             :     operator<(const unique_ptr<_Tp, _Dp>& __x,
     750             :               const unique_ptr<_Up, _Ep>& __y)
     751             :     {
     752             :       typedef typename
     753             :         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
     754             :                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
     755             :       return std::less<_CT>()(__x.get(), __y.get());
     756             :     }
     757             : 
     758             :   template<typename _Tp, typename _Dp>
     759             :     _GLIBCXX_NODISCARD inline bool
     760             :     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     761             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     762             :                                                                  nullptr); }
     763             : 
     764             :   template<typename _Tp, typename _Dp>
     765             :     _GLIBCXX_NODISCARD inline bool
     766             :     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     767             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     768             :                                                                  __x.get()); }
     769             : 
     770             :   template<typename _Tp, typename _Dp,
     771             :            typename _Up, typename _Ep>
     772             :     _GLIBCXX_NODISCARD inline bool
     773             :     operator<=(const unique_ptr<_Tp, _Dp>& __x,
     774             :                const unique_ptr<_Up, _Ep>& __y)
     775             :     { return !(__y < __x); }
     776             : 
     777             :   template<typename _Tp, typename _Dp>
     778             :     _GLIBCXX_NODISCARD inline bool
     779             :     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     780             :     { return !(nullptr < __x); }
     781             : 
     782             :   template<typename _Tp, typename _Dp>
     783             :     _GLIBCXX_NODISCARD inline bool
     784             :     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     785             :     { return !(__x < nullptr); }
     786             : 
     787             :   template<typename _Tp, typename _Dp,
     788             :            typename _Up, typename _Ep>
     789             :     _GLIBCXX_NODISCARD inline bool
     790             :     operator>(const unique_ptr<_Tp, _Dp>& __x,
     791             :               const unique_ptr<_Up, _Ep>& __y)
     792             :     { return (__y < __x); }
     793             : 
     794             :   template<typename _Tp, typename _Dp>
     795             :     _GLIBCXX_NODISCARD inline bool
     796             :     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     797             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     798             :                                                                  __x.get()); }
     799             : 
     800             :   template<typename _Tp, typename _Dp>
     801             :     _GLIBCXX_NODISCARD inline bool
     802             :     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     803             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     804             :                                                                  nullptr); }
     805             : 
     806             :   template<typename _Tp, typename _Dp,
     807             :            typename _Up, typename _Ep>
     808             :     _GLIBCXX_NODISCARD inline bool
     809             :     operator>=(const unique_ptr<_Tp, _Dp>& __x,
     810             :                const unique_ptr<_Up, _Ep>& __y)
     811             :     { return !(__x < __y); }
     812             : 
     813             :   template<typename _Tp, typename _Dp>
     814             :     _GLIBCXX_NODISCARD inline bool
     815             :     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     816             :     { return !(__x < nullptr); }
     817             : 
     818             :   template<typename _Tp, typename _Dp>
     819             :     _GLIBCXX_NODISCARD inline bool
     820             :     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     821             :     { return !(nullptr < __x); }
     822             : 
     823             :   /// std::hash specialization for unique_ptr.
     824             :   template<typename _Tp, typename _Dp>
     825             :     struct hash<unique_ptr<_Tp, _Dp>>
     826             :     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
     827             :     private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
     828             :     {
     829             :       size_t
     830             :       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
     831             :       {
     832             :         typedef unique_ptr<_Tp, _Dp> _UP;
     833             :         return std::hash<typename _UP::pointer>()(__u.get());
     834             :       }
     835             :     };
     836             : 
     837             : #if __cplusplus > 201103L
     838             : 
     839             : #define __cpp_lib_make_unique 201304
     840             : 
     841             :   template<typename _Tp>
     842             :     struct _MakeUniq
     843             :     { typedef unique_ptr<_Tp> __single_object; };
     844             : 
     845             :   template<typename _Tp>
     846             :     struct _MakeUniq<_Tp[]>
     847             :     { typedef unique_ptr<_Tp[]> __array; };
     848             : 
     849             :   template<typename _Tp, size_t _Bound>
     850             :     struct _MakeUniq<_Tp[_Bound]>
     851             :     { struct __invalid_type { }; };
     852             : 
     853             :   /// std::make_unique for single objects
     854             :   template<typename _Tp, typename... _Args>
     855             :     inline typename _MakeUniq<_Tp>::__single_object
     856           0 :     make_unique(_Args&&... __args)
     857           0 :     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
     858             : 
     859             :   /// std::make_unique for arrays of unknown bound
     860             :   template<typename _Tp>
     861             :     inline typename _MakeUniq<_Tp>::__array
     862             :     make_unique(size_t __num)
     863             :     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
     864             : 
     865             :   /// Disable std::make_unique for arrays of known bound
     866             :   template<typename _Tp, typename... _Args>
     867             :     inline typename _MakeUniq<_Tp>::__invalid_type
     868             :     make_unique(_Args&&...) = delete;
     869             : #endif
     870             : 
     871             :   /// @} group pointer_abstractions
     872             : 
     873             : #if __cplusplus >= 201703L
     874             :   namespace __detail::__variant
     875             :   {
     876             :     template<typename> struct _Never_valueless_alt; // see <variant>
     877             : 
     878             :     // Provide the strong exception-safety guarantee when emplacing a
     879             :     // unique_ptr into a variant.
     880             :     template<typename _Tp, typename _Del>
     881             :       struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
     882             :       : std::true_type
     883             :       { };
     884             :   }  // namespace __detail::__variant
     885             : #endif // C++17
     886             : 
     887             : _GLIBCXX_END_NAMESPACE_VERSION
     888             : } // namespace
     889             : 
     890             : #endif /* _UNIQUE_PTR_H */

Generated by: LCOV version 1.14