LCOV - code coverage report
Current view: top level - usr/include/c++/6/bits - unique_ptr.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 40 87.5 %
Date: 2017-03-02 17:11:10 Functions: 14 32 43.8 %

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

Generated by: LCOV version 1.13