LCOV - code coverage report
Current view: top level - usr/include/c++/8/bits - unique_ptr.h (source / functions) Hit Total Coverage
Test: Coverage example Lines: 56 59 94.9 %
Date: 2021-12-02 17:21:05 Functions: 133 138 96.4 %

          Line data    Source code
       1             : // unique_ptr implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2008-2018 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         985 :       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         985 :         delete __ptr;
      82         985 :       }
      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             :         operator()(_Up* __ptr) const
     112             :       {
     113             :         static_assert(sizeof(_Tp)>0,
     114             :                       "can't delete pointer to incomplete type");
     115             :         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         584 :       __uniq_ptr_impl() = default;
     143        1220 :       __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
     144             : 
     145             :       template<typename _Del>
     146         810 :       __uniq_ptr_impl(pointer __p, _Del&& __d)
     147         810 :         : _M_t(__p, std::forward<_Del>(__d)) { }
     148             : 
     149        5814 :       pointer&   _M_ptr() { return std::get<0>(_M_t); }
     150       14450 :       pointer    _M_ptr() const { return std::get<0>(_M_t); }
     151        3048 :       _Dp&       _M_deleter() { return std::get<1>(_M_t); }
     152             :       const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
     153             : 
     154             :       void
     155          83 :       swap(__uniq_ptr_impl& __rhs) noexcept
     156             :       {
     157             :         using std::swap;
     158          83 :         swap(this->_M_ptr(), __rhs._M_ptr());
     159          83 :         swap(this->_M_deleter(), __rhs._M_deleter());
     160          83 :       }
     161             : 
     162             :     private:
     163             :       tuple<pointer, _Dp> _M_t;
     164             :     };
     165             : 
     166             :   /// 20.7.1.2 unique_ptr for single objects.
     167             :   template <typename _Tp, typename _Dp = default_delete<_Tp>>
     168             :     class unique_ptr
     169             :     {
     170             :       template <class _Up>
     171             :       using _DeleterConstraint =
     172             :         typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     173             : 
     174             :       __uniq_ptr_impl<_Tp, _Dp> _M_t;
     175             : 
     176             :     public:
     177             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     178             :       using element_type  = _Tp;
     179             :       using deleter_type  = _Dp;
     180             : 
     181             :       // helper template for detecting a safe conversion from another
     182             :       // unique_ptr
     183             :       template<typename _Up, typename _Ep>
     184             :         using __safe_conversion_up = __and_<
     185             :           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
     186             :           __not_<is_array<_Up>>
     187             :         >;
     188             : 
     189             :       // Constructors.
     190             : 
     191             :       /// Default constructor, creates a unique_ptr that owns nothing.
     192             :       template <typename _Up = _Dp,
     193             :                 typename = _DeleterConstraint<_Up>>
     194         584 :         constexpr unique_ptr() noexcept
     195         584 :         : _M_t()
     196         584 :         { }
     197             : 
     198             :       /** Takes ownership of a pointer.
     199             :        *
     200             :        * @param __p  A pointer to an object of @c element_type
     201             :        *
     202             :        * The deleter will be value-initialized.
     203             :        */
     204             :       template <typename _Up = _Dp,
     205             :                 typename = _DeleterConstraint<_Up>>
     206             :         explicit
     207        1220 :         unique_ptr(pointer __p) noexcept
     208        1220 :         : _M_t(__p)
     209        1220 :         { }
     210             : 
     211             :       /** Takes ownership of a pointer.
     212             :        *
     213             :        * @param __p  A pointer to an object of @c element_type
     214             :        * @param __d  A reference to a deleter.
     215             :        *
     216             :        * The deleter will be initialized with @p __d
     217             :        */
     218             :       unique_ptr(pointer __p,
     219             :           typename conditional<is_reference<deleter_type>::value,
     220             :             deleter_type, const deleter_type&>::type __d) noexcept
     221             :       : _M_t(__p, __d) { }
     222             : 
     223             :       /** Takes ownership of a pointer.
     224             :        *
     225             :        * @param __p  A pointer to an object of @c element_type
     226             :        * @param __d  An rvalue reference to a deleter.
     227             :        *
     228             :        * The deleter will be initialized with @p std::move(__d)
     229             :        */
     230             :       unique_ptr(pointer __p,
     231             :           typename remove_reference<deleter_type>::type&& __d) noexcept
     232             :       : _M_t(std::move(__p), std::move(__d))
     233             :       { static_assert(!std::is_reference<deleter_type>::value,
     234             :                       "rvalue deleter bound to reference"); }
     235             : 
     236             :       /// Creates a unique_ptr that owns nothing.
     237             :       template <typename _Up = _Dp,
     238             :                 typename = _DeleterConstraint<_Up>>
     239             :         constexpr unique_ptr(nullptr_t) noexcept : _M_t() { }
     240             : 
     241             :       // Move constructors.
     242             : 
     243             :       /// Move constructor.
     244         727 :       unique_ptr(unique_ptr&& __u) noexcept
     245         727 :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     246             : 
     247             :       /** @brief Converting constructor from another type
     248             :        *
     249             :        * Requires that the pointer owned by @p __u is convertible to the
     250             :        * type of pointer owned by this object, @p __u does not own an array,
     251             :        * and @p __u has a compatible deleter type.
     252             :        */
     253             :       template<typename _Up, typename _Ep, typename = _Require<
     254             :                __safe_conversion_up<_Up, _Ep>,
     255             :                typename conditional<is_reference<_Dp>::value,
     256             :                                     is_same<_Ep, _Dp>,
     257             :                                     is_convertible<_Ep, _Dp>>::type>>
     258          83 :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     259          83 :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     260          83 :         { }
     261             : 
     262             : #if _GLIBCXX_USE_DEPRECATED
     263             : #pragma GCC diagnostic push
     264             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     265             :       /// Converting constructor from @c auto_ptr
     266             :       template<typename _Up, typename = _Require<
     267             :                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
     268             :         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
     269             : #pragma GCC diagnostic pop
     270             : #endif
     271             : 
     272             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     273        2614 :       ~unique_ptr() noexcept
     274             :       {
     275        2614 :         auto& __ptr = _M_t._M_ptr();
     276        2614 :         if (__ptr != nullptr)
     277        1068 :           get_deleter()(__ptr);
     278        2614 :         __ptr = pointer();
     279        2614 :       }
     280             : 
     281             :       // Assignment.
     282             : 
     283             :       /** @brief Move assignment operator.
     284             :        *
     285             :        * @param __u  The object to transfer ownership from.
     286             :        *
     287             :        * Invokes the deleter first if this object owns a pointer.
     288             :        */
     289             :       unique_ptr&
     290         502 :       operator=(unique_ptr&& __u) noexcept
     291             :       {
     292         502 :         reset(__u.release());
     293         502 :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     294         502 :         return *this;
     295             :       }
     296             : 
     297             :       /** @brief Assignment from another type.
     298             :        *
     299             :        * @param __u  The object to transfer ownership from, which owns a
     300             :        *             convertible pointer to a non-array object.
     301             :        *
     302             :        * Invokes the deleter first if this object owns a pointer.
     303             :        */
     304             :       template<typename _Up, typename _Ep>
     305             :         typename enable_if< __and_<
     306             :           __safe_conversion_up<_Up, _Ep>,
     307             :           is_assignable<deleter_type&, _Ep&&>
     308             :           >::value,
     309             :           unique_ptr&>::type
     310             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     311             :         {
     312             :           reset(__u.release());
     313             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     314             :           return *this;
     315             :         }
     316             : 
     317             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     318             :       unique_ptr&
     319             :       operator=(nullptr_t) noexcept
     320             :       {
     321             :         reset();
     322             :         return *this;
     323             :       }
     324             : 
     325             :       // Observers.
     326             : 
     327             :       /// Dereference the stored pointer.
     328             :       typename add_lvalue_reference<element_type>::type
     329          82 :       operator*() const
     330             :       {
     331             :         __glibcxx_assert(get() != pointer());
     332          82 :         return *get();
     333             :       }
     334             : 
     335             :       /// Return the stored pointer.
     336             :       pointer
     337        2387 :       operator->() const noexcept
     338             :       {
     339             :         _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
     340        2387 :         return get();
     341             :       }
     342             : 
     343             :       /// Return the stored pointer.
     344             :       pointer
     345       14450 :       get() const noexcept
     346       14450 :       { return _M_t._M_ptr(); }
     347             : 
     348             :       /// Return a reference to the stored deleter.
     349             :       deleter_type&
     350        2882 :       get_deleter() noexcept
     351        2882 :       { return _M_t._M_deleter(); }
     352             : 
     353             :       /// Return a reference to the stored deleter.
     354             :       const deleter_type&
     355             :       get_deleter() const noexcept
     356             :       { return _M_t._M_deleter(); }
     357             : 
     358             :       /// Return @c true if the stored pointer is not null.
     359           0 :       explicit operator bool() const noexcept
     360           0 :       { return get() == pointer() ? false : true; }
     361             : 
     362             :       // Modifiers.
     363             : 
     364             :       /// Release ownership of any stored pointer.
     365             :       pointer
     366        1312 :       release() noexcept
     367             :       {
     368        1312 :         pointer __p = get();
     369        1312 :         _M_t._M_ptr() = pointer();
     370        1312 :         return __p;
     371             :       }
     372             : 
     373             :       /** @brief Replace the stored pointer.
     374             :        *
     375             :        * @param __p  The new pointer to store.
     376             :        *
     377             :        * The deleter will be invoked if a pointer is already owned.
     378             :        */
     379             :       void
     380         502 :       reset(pointer __p = pointer()) noexcept
     381             :       {
     382             :         using std::swap;
     383         502 :         swap(_M_t._M_ptr(), __p);
     384         502 :         if (__p != pointer())
     385           0 :           get_deleter()(__p);
     386         502 :       }
     387             : 
     388             :       /// Exchange the pointer and deleter with another object.
     389             :       void
     390          83 :       swap(unique_ptr& __u) noexcept
     391             :       {
     392             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     393          83 :         _M_t.swap(__u._M_t);
     394          83 :       }
     395             : 
     396             :       // Disable copy from lvalue.
     397             :       unique_ptr(const unique_ptr&) = delete;
     398             :       unique_ptr& operator=(const unique_ptr&) = delete;
     399             :   };
     400             : 
     401             :   /// 20.7.1.3 unique_ptr for array objects with a runtime length
     402             :   // [unique.ptr.runtime]
     403             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     404             :   // DR 740 - omit specialization for array objects with a compile time length
     405             :   template<typename _Tp, typename _Dp>
     406             :     class unique_ptr<_Tp[], _Dp>
     407             :     {
     408             :       template <typename _Up>
     409             :       using _DeleterConstraint =
     410             :         typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
     411             : 
     412             :       __uniq_ptr_impl<_Tp, _Dp> _M_t;
     413             : 
     414             :       template<typename _Up>
     415             :         using __remove_cv = typename remove_cv<_Up>::type;
     416             : 
     417             :       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
     418             :       template<typename _Up>
     419             :         using __is_derived_Tp
     420             :           = __and_< is_base_of<_Tp, _Up>,
     421             :                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
     422             : 
     423             :     public:
     424             :       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
     425             :       using element_type  = _Tp;
     426             :       using deleter_type  = _Dp;
     427             : 
     428             :       // helper template for detecting a safe conversion from another
     429             :       // unique_ptr
     430             :       template<typename _Up, typename _Ep,
     431             :                typename _UPtr = unique_ptr<_Up, _Ep>,
     432             :                typename _UP_pointer = typename _UPtr::pointer,
     433             :                typename _UP_element_type = typename _UPtr::element_type>
     434             :         using __safe_conversion_up = __and_<
     435             :           is_array<_Up>,
     436             :           is_same<pointer, element_type*>,
     437             :           is_same<_UP_pointer, _UP_element_type*>,
     438             :           is_convertible<_UP_element_type(*)[], element_type(*)[]>
     439             :         >;
     440             : 
     441             :       // helper template for detecting a safe conversion from a raw pointer
     442             :       template<typename _Up>
     443             :         using __safe_conversion_raw = __and_<
     444             :           __or_<__or_<is_same<_Up, pointer>,
     445             :                       is_same<_Up, nullptr_t>>,
     446             :                 __and_<is_pointer<_Up>,
     447             :                        is_same<pointer, element_type*>,
     448             :                        is_convertible<
     449             :                          typename remove_pointer<_Up>::type(*)[],
     450             :                          element_type(*)[]>
     451             :                 >
     452             :           >
     453             :         >;
     454             : 
     455             :       // Constructors.
     456             : 
     457             :       /// Default constructor, creates a unique_ptr that owns nothing.
     458             :       template <typename _Up = _Dp,
     459             :                 typename = _DeleterConstraint<_Up>>
     460             :         constexpr unique_ptr() noexcept
     461             :         : _M_t()
     462             :         { }
     463             : 
     464             :       /** Takes ownership of a pointer.
     465             :        *
     466             :        * @param __p  A pointer to an array of a type safely convertible
     467             :        * to an array of @c element_type
     468             :        *
     469             :        * The deleter will be value-initialized.
     470             :        */
     471             :       template<typename _Up,
     472             :                typename _Vp = _Dp,
     473             :                typename = _DeleterConstraint<_Vp>,
     474             :                typename = typename enable_if<
     475             :                  __safe_conversion_raw<_Up>::value, bool>::type>
     476             :         explicit
     477             :         unique_ptr(_Up __p) noexcept
     478             :         : _M_t(__p)
     479             :         { }
     480             : 
     481             :       /** Takes ownership of a pointer.
     482             :        *
     483             :        * @param __p  A pointer to an array of a type safely convertible
     484             :        * to an array of @c element_type
     485             :        * @param __d  A reference to a deleter.
     486             :        *
     487             :        * The deleter will be initialized with @p __d
     488             :        */
     489             :       template<typename _Up,
     490             :                typename = typename enable_if<
     491             :                  __safe_conversion_raw<_Up>::value, bool>::type>
     492             :       unique_ptr(_Up __p,
     493             :                  typename conditional<is_reference<deleter_type>::value,
     494             :                  deleter_type, const deleter_type&>::type __d) noexcept
     495             :       : _M_t(__p, __d) { }
     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 std::move(__d)
     504             :        */
     505             :       template<typename _Up,
     506             :                typename = typename enable_if<
     507             :                  __safe_conversion_raw<_Up>::value, bool>::type>
     508             :       unique_ptr(_Up __p, typename
     509             :                  remove_reference<deleter_type>::type&& __d) noexcept
     510             :       : _M_t(std::move(__p), std::move(__d))
     511             :       { static_assert(!is_reference<deleter_type>::value,
     512             :                       "rvalue deleter bound to reference"); }
     513             : 
     514             :       /// Move constructor.
     515             :       unique_ptr(unique_ptr&& __u) noexcept
     516             :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     517             : 
     518             :       /// Creates a unique_ptr that owns nothing.
     519             :       template <typename _Up = _Dp,
     520             :                 typename = _DeleterConstraint<_Up>>
     521             :         constexpr unique_ptr(nullptr_t) noexcept : _M_t() { }
     522             : 
     523             :       template<typename _Up, typename _Ep, typename = _Require<
     524             :                __safe_conversion_up<_Up, _Ep>,
     525             :                typename conditional<is_reference<_Dp>::value,
     526             :                                     is_same<_Ep, _Dp>,
     527             :                                     is_convertible<_Ep, _Dp>>::type>>
     528             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     529             :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     530             :         { }
     531             : 
     532             :       /// Destructor, invokes the deleter if the stored pointer is not null.
     533             :       ~unique_ptr()
     534             :       {
     535             :         auto& __ptr = _M_t._M_ptr();
     536             :         if (__ptr != nullptr)
     537             :           get_deleter()(__ptr);
     538             :         __ptr = pointer();
     539             :       }
     540             : 
     541             :       // Assignment.
     542             : 
     543             :       /** @brief Move assignment operator.
     544             :        *
     545             :        * @param __u  The object to transfer ownership from.
     546             :        *
     547             :        * Invokes the deleter first if this object owns a pointer.
     548             :        */
     549             :       unique_ptr&
     550             :       operator=(unique_ptr&& __u) noexcept
     551             :       {
     552             :         reset(__u.release());
     553             :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     554             :         return *this;
     555             :       }
     556             : 
     557             :       /** @brief Assignment from another type.
     558             :        *
     559             :        * @param __u  The object to transfer ownership from, which owns a
     560             :        *             convertible pointer to an array object.
     561             :        *
     562             :        * Invokes the deleter first if this object owns a pointer.
     563             :        */
     564             :       template<typename _Up, typename _Ep>
     565             :         typename
     566             :         enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
     567             :                          is_assignable<deleter_type&, _Ep&&>
     568             :                   >::value,
     569             :                   unique_ptr&>::type
     570             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     571             :         {
     572             :           reset(__u.release());
     573             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     574             :           return *this;
     575             :         }
     576             : 
     577             :       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
     578             :       unique_ptr&
     579             :       operator=(nullptr_t) noexcept
     580             :       {
     581             :         reset();
     582             :         return *this;
     583             :       }
     584             : 
     585             :       // Observers.
     586             : 
     587             :       /// Access an element of owned array.
     588             :       typename std::add_lvalue_reference<element_type>::type
     589             :       operator[](size_t __i) const
     590             :       {
     591             :         __glibcxx_assert(get() != pointer());
     592             :         return get()[__i];
     593             :       }
     594             : 
     595             :       /// Return the stored pointer.
     596             :       pointer
     597             :       get() const noexcept
     598             :       { return _M_t._M_ptr(); }
     599             : 
     600             :       /// Return a reference to the stored deleter.
     601             :       deleter_type&
     602             :       get_deleter() noexcept
     603             :       { return _M_t._M_deleter(); }
     604             : 
     605             :       /// Return a reference to the stored deleter.
     606             :       const deleter_type&
     607             :       get_deleter() const noexcept
     608             :       { return _M_t._M_deleter(); }
     609             : 
     610             :       /// Return @c true if the stored pointer is not null.
     611             :       explicit operator bool() const noexcept
     612             :       { return get() == pointer() ? false : true; }
     613             : 
     614             :       // Modifiers.
     615             : 
     616             :       /// Release ownership of any stored pointer.
     617             :       pointer
     618             :       release() noexcept
     619             :       {
     620             :         pointer __p = get();
     621             :         _M_t._M_ptr() = pointer();
     622             :         return __p;
     623             :       }
     624             : 
     625             :       /** @brief Replace the stored pointer.
     626             :        *
     627             :        * @param __p  The new pointer to store.
     628             :        *
     629             :        * The deleter will be invoked if a pointer is already owned.
     630             :        */
     631             :       template <typename _Up,
     632             :                 typename = _Require<
     633             :                   __or_<is_same<_Up, pointer>,
     634             :                         __and_<is_same<pointer, element_type*>,
     635             :                                is_pointer<_Up>,
     636             :                                is_convertible<
     637             :                                  typename remove_pointer<_Up>::type(*)[],
     638             :                                  element_type(*)[]
     639             :                                >
     640             :                         >
     641             :                   >
     642             :                >>
     643             :       void
     644             :       reset(_Up __p) noexcept
     645             :       {
     646             :         pointer __ptr = __p;
     647             :         using std::swap;
     648             :         swap(_M_t._M_ptr(), __ptr);
     649             :         if (__ptr != nullptr)
     650             :           get_deleter()(__ptr);
     651             :       }
     652             : 
     653             :       void reset(nullptr_t = nullptr) noexcept
     654             :       {
     655             :         reset(pointer());
     656             :       }
     657             : 
     658             :       /// Exchange the pointer and deleter with another object.
     659             :       void
     660             :       swap(unique_ptr& __u) noexcept
     661             :       {
     662             :         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
     663             :         _M_t.swap(__u._M_t);
     664             :       }
     665             : 
     666             :       // Disable copy from lvalue.
     667             :       unique_ptr(const unique_ptr&) = delete;
     668             :       unique_ptr& operator=(const unique_ptr&) = delete;
     669             :     };
     670             : 
     671             :   template<typename _Tp, typename _Dp>
     672             :     inline
     673             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     674             :     // Constrained free swap overload, see p0185r1
     675             :     typename enable_if<__is_swappable<_Dp>::value>::type
     676             : #else
     677             :     void
     678             : #endif
     679             :     swap(unique_ptr<_Tp, _Dp>& __x,
     680             :          unique_ptr<_Tp, _Dp>& __y) noexcept
     681             :     { __x.swap(__y); }
     682             : 
     683             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     684             :   template<typename _Tp, typename _Dp>
     685             :     typename enable_if<!__is_swappable<_Dp>::value>::type
     686             :     swap(unique_ptr<_Tp, _Dp>&,
     687             :          unique_ptr<_Tp, _Dp>&) = delete;
     688             : #endif
     689             : 
     690             :   template<typename _Tp, typename _Dp,
     691             :            typename _Up, typename _Ep>
     692             :     inline bool
     693             :     operator==(const unique_ptr<_Tp, _Dp>& __x,
     694             :                const unique_ptr<_Up, _Ep>& __y)
     695             :     { return __x.get() == __y.get(); }
     696             : 
     697             :   template<typename _Tp, typename _Dp>
     698             :     inline bool
     699             :     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     700             :     { return !__x; }
     701             : 
     702             :   template<typename _Tp, typename _Dp>
     703             :     inline bool
     704             :     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     705             :     { return !__x; }
     706             : 
     707             :   template<typename _Tp, typename _Dp,
     708             :            typename _Up, typename _Ep>
     709             :     inline bool
     710             :     operator!=(const unique_ptr<_Tp, _Dp>& __x,
     711             :                const unique_ptr<_Up, _Ep>& __y)
     712             :     { return __x.get() != __y.get(); }
     713             : 
     714             :   template<typename _Tp, typename _Dp>
     715             :     inline bool
     716             :     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     717             :     { return (bool)__x; }
     718             : 
     719             :   template<typename _Tp, typename _Dp>
     720             :     inline bool
     721             :     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     722             :     { return (bool)__x; }
     723             : 
     724             :   template<typename _Tp, typename _Dp,
     725             :            typename _Up, typename _Ep>
     726             :     inline bool
     727             :     operator<(const unique_ptr<_Tp, _Dp>& __x,
     728             :               const unique_ptr<_Up, _Ep>& __y)
     729             :     {
     730             :       typedef typename
     731             :         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
     732             :                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
     733             :       return std::less<_CT>()(__x.get(), __y.get());
     734             :     }
     735             : 
     736             :   template<typename _Tp, typename _Dp>
     737             :     inline bool
     738             :     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     739             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     740             :                                                                  nullptr); }
     741             : 
     742             :   template<typename _Tp, typename _Dp>
     743             :     inline bool
     744             :     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     745             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     746             :                                                                  __x.get()); }
     747             : 
     748             :   template<typename _Tp, typename _Dp,
     749             :            typename _Up, typename _Ep>
     750             :     inline bool
     751             :     operator<=(const unique_ptr<_Tp, _Dp>& __x,
     752             :                const unique_ptr<_Up, _Ep>& __y)
     753             :     { return !(__y < __x); }
     754             : 
     755             :   template<typename _Tp, typename _Dp>
     756             :     inline bool
     757             :     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     758             :     { return !(nullptr < __x); }
     759             : 
     760             :   template<typename _Tp, typename _Dp>
     761             :     inline bool
     762             :     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     763             :     { return !(__x < nullptr); }
     764             : 
     765             :   template<typename _Tp, typename _Dp,
     766             :            typename _Up, typename _Ep>
     767             :     inline bool
     768             :     operator>(const unique_ptr<_Tp, _Dp>& __x,
     769             :               const unique_ptr<_Up, _Ep>& __y)
     770             :     { return (__y < __x); }
     771             : 
     772             :   template<typename _Tp, typename _Dp>
     773             :     inline bool
     774             :     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     775             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     776             :                                                                  __x.get()); }
     777             : 
     778             :   template<typename _Tp, typename _Dp>
     779             :     inline bool
     780             :     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     781             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     782             :                                                                  nullptr); }
     783             : 
     784             :   template<typename _Tp, typename _Dp,
     785             :            typename _Up, typename _Ep>
     786             :     inline bool
     787             :     operator>=(const unique_ptr<_Tp, _Dp>& __x,
     788             :                const unique_ptr<_Up, _Ep>& __y)
     789             :     { return !(__x < __y); }
     790             : 
     791             :   template<typename _Tp, typename _Dp>
     792             :     inline bool
     793             :     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     794             :     { return !(__x < nullptr); }
     795             : 
     796             :   template<typename _Tp, typename _Dp>
     797             :     inline bool
     798             :     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     799             :     { return !(nullptr < __x); }
     800             : 
     801             :   /// std::hash specialization for unique_ptr.
     802             :   template<typename _Tp, typename _Dp>
     803             :     struct hash<unique_ptr<_Tp, _Dp>>
     804             :     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
     805             :     private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
     806             :     {
     807             :       size_t
     808             :       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
     809             :       {
     810             :         typedef unique_ptr<_Tp, _Dp> _UP;
     811             :         return std::hash<typename _UP::pointer>()(__u.get());
     812             :       }
     813             :     };
     814             : 
     815             : #if __cplusplus > 201103L
     816             : 
     817             : #define __cpp_lib_make_unique 201304
     818             : 
     819             :   template<typename _Tp>
     820             :     struct _MakeUniq
     821             :     { typedef unique_ptr<_Tp> __single_object; };
     822             : 
     823             :   template<typename _Tp>
     824             :     struct _MakeUniq<_Tp[]>
     825             :     { typedef unique_ptr<_Tp[]> __array; };
     826             : 
     827             :   template<typename _Tp, size_t _Bound>
     828             :     struct _MakeUniq<_Tp[_Bound]>
     829             :     { struct __invalid_type { }; };
     830             : 
     831             :   /// std::make_unique for single objects
     832             :   template<typename _Tp, typename... _Args>
     833             :     inline typename _MakeUniq<_Tp>::__single_object
     834         985 :     make_unique(_Args&&... __args)
     835         985 :     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
     836             : 
     837             :   /// std::make_unique for arrays of unknown bound
     838             :   template<typename _Tp>
     839             :     inline typename _MakeUniq<_Tp>::__array
     840             :     make_unique(size_t __num)
     841             :     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
     842             : 
     843             :   /// Disable std::make_unique for arrays of known bound
     844             :   template<typename _Tp, typename... _Args>
     845             :     inline typename _MakeUniq<_Tp>::__invalid_type
     846             :     make_unique(_Args&&...) = delete;
     847             : #endif
     848             : 
     849             :   // @} group pointer_abstractions
     850             : 
     851             : _GLIBCXX_END_NAMESPACE_VERSION
     852             : } // namespace
     853             : 
     854             : #endif /* _UNIQUE_PTR_H */

Generated by: LCOV version 1.14