LCOV - code coverage report
Current view: top level - c++/4.8/bits - unique_ptr.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 18 18 100.0 %
Date: 2016-01-31 12:01:00 Functions: 29 30 96.7 %

          Line data    Source code
       1             : // unique_ptr implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2008-2013 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/debug.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, default_delete.
      53             :   template<typename _Tp>
      54             :     struct default_delete
      55             :     {
      56             :       constexpr default_delete() noexcept = default;
      57             : 
      58             :       template<typename _Up, typename = typename
      59             :                enable_if<is_convertible<_Up*, _Tp*>::value>::type>
      60          12 :         default_delete(const default_delete<_Up>&) noexcept { }
      61             : 
      62             :       void
      63             :       operator()(_Tp* __ptr) const
      64             :       {
      65             :         static_assert(sizeof(_Tp)>0,
      66             :                       "can't delete pointer to incomplete type");
      67         126 :         delete __ptr;
      68          63 :       }
      69             :     };
      70             : 
      71             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
      72             :   // DR 740 - omit specialization for array objects with a compile time length
      73             :   /// Specialization, default_delete.
      74             :   template<typename _Tp>
      75             :     struct default_delete<_Tp[]>
      76             :     {
      77             :     private:
      78             :       template<typename _Up>
      79             :         using __remove_cv = typename remove_cv<_Up>::type;
      80             : 
      81             :       // Like is_base_of<_Tp, _Up> but false if unqualified types are the same
      82             :       template<typename _Up>
      83             :         using __is_derived_Tp
      84             :           = __and_< is_base_of<_Tp, _Up>,
      85             :                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
      86             : 
      87             :     public:
      88             :       constexpr default_delete() noexcept = default;
      89             : 
      90             :       template<typename _Up, typename = typename
      91             :                enable_if<!__is_derived_Tp<_Up>::value>::type>
      92             :         default_delete(const default_delete<_Up[]>&) noexcept { }
      93             : 
      94             :       void
      95             :       operator()(_Tp* __ptr) const
      96             :       {
      97             :         static_assert(sizeof(_Tp)>0,
      98             :                       "can't delete pointer to incomplete type");
      99             :         delete [] __ptr;
     100             :       }
     101             : 
     102             :       template<typename _Up>
     103             :         typename enable_if<__is_derived_Tp<_Up>::value>::type
     104             :         operator()(_Up*) const = delete;
     105             :     };
     106             : 
     107             :   /// 20.7.1.2 unique_ptr for single objects.
     108             :   template <typename _Tp, typename _Dp = default_delete<_Tp> >
     109             :     class unique_ptr
     110             :     {
     111             :       // use SFINAE to determine whether _Del::pointer exists
     112             :       class _Pointer
     113             :       {
     114             :         template<typename _Up>
     115             :           static typename _Up::pointer __test(typename _Up::pointer*);
     116             : 
     117             :         template<typename _Up>
     118             :           static _Tp* __test(...);
     119             : 
     120             :         typedef typename remove_reference<_Dp>::type _Del;
     121             : 
     122             :       public:
     123             :         typedef decltype(__test<_Del>(0)) type;
     124             :       };
     125             : 
     126             :       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
     127             :       __tuple_type                                      _M_t;
     128             : 
     129             :     public:
     130             :       typedef typename _Pointer::type   pointer;
     131             :       typedef _Tp                       element_type;
     132             :       typedef _Dp                       deleter_type;
     133             : 
     134             :       // Constructors.
     135             :       constexpr unique_ptr() noexcept
     136             :       : _M_t()
     137             :       { static_assert(!is_pointer<deleter_type>::value,
     138             :                      "constructed with null function pointer deleter"); }
     139             : 
     140             :       explicit
     141             :       unique_ptr(pointer __p) noexcept
     142          35 :       : _M_t(__p, deleter_type())
     143             :       { static_assert(!is_pointer<deleter_type>::value,
     144          35 :                      "constructed with null function pointer deleter"); }
     145             : 
     146             :       unique_ptr(pointer __p,
     147             :           typename conditional<is_reference<deleter_type>::value,
     148             :             deleter_type, const deleter_type&>::type __d) noexcept
     149             :       : _M_t(__p, __d) { }
     150             : 
     151             :       unique_ptr(pointer __p,
     152             :           typename remove_reference<deleter_type>::type&& __d) noexcept
     153             :       : _M_t(std::move(__p), std::move(__d))
     154             :       { static_assert(!std::is_reference<deleter_type>::value,
     155             :                       "rvalue deleter bound to reference"); }
     156             : 
     157             :       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
     158             : 
     159             :       // Move constructors.
     160             :       unique_ptr(unique_ptr&& __u) noexcept
     161             :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     162             : 
     163             :       template<typename _Up, typename _Ep, typename = _Require<
     164             :                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
     165             :                __not_<is_array<_Up>>,
     166             :                typename conditional<is_reference<_Dp>::value,
     167             :                                     is_same<_Ep, _Dp>,
     168             :                                     is_convertible<_Ep, _Dp>>::type>>
     169             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     170          12 :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     171          12 :         { }
     172             : 
     173             : #if _GLIBCXX_USE_DEPRECATED
     174             :       template<typename _Up, typename = _Require<
     175             :                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
     176             :         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
     177             : #endif
     178             : 
     179             :       // Destructor.
     180             :       ~unique_ptr() noexcept
     181             :       {
     182          75 :         auto& __ptr = std::get<0>(_M_t);
     183          75 :         if (__ptr != nullptr)
     184         126 :           get_deleter()(__ptr);
     185          75 :         __ptr = pointer();
     186          75 :       }
     187             : 
     188             :       // Assignment.
     189             :       unique_ptr&
     190             :       operator=(unique_ptr&& __u) noexcept
     191             :       {
     192             :         reset(__u.release());
     193             :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     194             :         return *this;
     195             :       }
     196             : 
     197             :       template<typename _Up, typename _Ep>
     198             :         typename enable_if< __and_<
     199             :           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
     200             :           __not_<is_array<_Up>>
     201             :           >::value,
     202             :           unique_ptr&>::type
     203             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     204             :         {
     205             :           reset(__u.release());
     206             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     207             :           return *this;
     208             :         }
     209             : 
     210             :       unique_ptr&
     211             :       operator=(nullptr_t) noexcept
     212             :       {
     213             :         reset();
     214             :         return *this;
     215             :       }
     216             : 
     217             :       // Observers.
     218             :       typename add_lvalue_reference<element_type>::type
     219             :       operator*() const
     220             :       {
     221             :         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
     222          23 :         return *get();
     223             :       }
     224             : 
     225             :       pointer
     226             :       operator->() const noexcept
     227             :       {
     228             :         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
     229             :         return get();
     230             :       }
     231             : 
     232             :       pointer
     233             :       get() const noexcept
     234          47 :       { return std::get<0>(_M_t); }
     235             : 
     236             :       deleter_type&
     237             :       get_deleter() noexcept
     238          75 :       { return std::get<1>(_M_t); }
     239             : 
     240             :       const deleter_type&
     241             :       get_deleter() const noexcept
     242             :       { return std::get<1>(_M_t); }
     243             : 
     244             :       explicit operator bool() const noexcept
     245             :       { return get() == pointer() ? false : true; }
     246             : 
     247             :       // Modifiers.
     248             :       pointer
     249             :       release() noexcept
     250             :       {
     251          12 :         pointer __p = get();
     252          12 :         std::get<0>(_M_t) = pointer();
     253          12 :         return __p;
     254             :       }
     255             : 
     256             :       void
     257             :       reset(pointer __p = pointer()) noexcept
     258             :       {
     259             :         using std::swap;
     260             :         swap(std::get<0>(_M_t), __p);
     261             :         if (__p != pointer())
     262             :           get_deleter()(__p);
     263             :       }
     264             : 
     265             :       void
     266             :       swap(unique_ptr& __u) noexcept
     267             :       {
     268             :         using std::swap;
     269             :         swap(_M_t, __u._M_t);
     270             :       }
     271             : 
     272             :       // Disable copy from lvalue.
     273             :       unique_ptr(const unique_ptr&) = delete;
     274             :       unique_ptr& operator=(const unique_ptr&) = delete;
     275             :   };
     276             : 
     277             :   /// 20.7.1.3 unique_ptr for array objects with a runtime length
     278             :   // [unique.ptr.runtime]
     279             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     280             :   // DR 740 - omit specialization for array objects with a compile time length
     281             :   template<typename _Tp, typename _Dp>
     282             :     class unique_ptr<_Tp[], _Dp>
     283             :     {
     284             :       // use SFINAE to determine whether _Del::pointer exists
     285             :       class _Pointer
     286             :       {
     287             :         template<typename _Up>
     288             :           static typename _Up::pointer __test(typename _Up::pointer*);
     289             : 
     290             :         template<typename _Up>
     291             :           static _Tp* __test(...);
     292             : 
     293             :         typedef typename remove_reference<_Dp>::type _Del;
     294             : 
     295             :       public:
     296             :         typedef decltype(__test<_Del>(0)) type;
     297             :       };
     298             : 
     299             :       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
     300             :       __tuple_type                                      _M_t;
     301             : 
     302             :       template<typename _Up>
     303             :         using __remove_cv = typename remove_cv<_Up>::type;
     304             : 
     305             :       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
     306             :       template<typename _Up>
     307             :         using __is_derived_Tp
     308             :           = __and_< is_base_of<_Tp, _Up>,
     309             :                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
     310             : 
     311             :       template<typename _Up, typename _Ep,
     312             :                typename _Tp_pointer = typename _Pointer::type,
     313             :                typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer>
     314             :         using __safe_conversion = __and_<
     315             :             is_convertible<_Up_pointer, _Tp_pointer>,
     316             :             is_array<_Up>,
     317             :             __or_<__not_<is_pointer<_Up_pointer>>,
     318             :                   __not_<is_pointer<_Tp_pointer>>,
     319             :                   __not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
     320             :             >
     321             :           >;
     322             : 
     323             :     public:
     324             :       typedef typename _Pointer::type   pointer;
     325             :       typedef _Tp                       element_type;
     326             :       typedef _Dp                       deleter_type;
     327             : 
     328             :       // Constructors.
     329             :       constexpr unique_ptr() noexcept
     330             :       : _M_t()
     331             :       { static_assert(!std::is_pointer<deleter_type>::value,
     332             :                       "constructed with null function pointer deleter"); }
     333             : 
     334             :       explicit
     335             :       unique_ptr(pointer __p) noexcept
     336             :       : _M_t(__p, deleter_type())
     337             :       { static_assert(!is_pointer<deleter_type>::value,
     338             :                       "constructed with null function pointer deleter"); }
     339             : 
     340             :       template<typename _Up, typename = _Require<is_pointer<pointer>,
     341             :                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
     342             :         explicit
     343             :         unique_ptr(_Up* __p) = delete;
     344             : 
     345             :       unique_ptr(pointer __p,
     346             :           typename conditional<is_reference<deleter_type>::value,
     347             :               deleter_type, const deleter_type&>::type __d) noexcept
     348             :       : _M_t(__p, __d) { }
     349             : 
     350             :       unique_ptr(pointer __p, typename
     351             :                  remove_reference<deleter_type>::type&& __d) noexcept
     352             :       : _M_t(std::move(__p), std::move(__d))
     353             :       { static_assert(!is_reference<deleter_type>::value,
     354             :                       "rvalue deleter bound to reference"); }
     355             : 
     356             :       // Move constructor.
     357             :       unique_ptr(unique_ptr&& __u) noexcept
     358             :       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
     359             : 
     360             :       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
     361             : 
     362             :       template<typename _Up, typename _Ep,
     363             :                typename = _Require<__safe_conversion<_Up, _Ep>,
     364             :                  typename conditional<is_reference<_Dp>::value,
     365             :                                       is_same<_Ep, _Dp>,
     366             :                                       is_convertible<_Ep, _Dp>>::type
     367             :                >>
     368             :         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
     369             :         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
     370             :         { }
     371             : 
     372             :       // Destructor.
     373             :       ~unique_ptr()
     374             :       {
     375             :         auto& __ptr = std::get<0>(_M_t);
     376             :         if (__ptr != nullptr)
     377             :           get_deleter()(__ptr);
     378             :         __ptr = pointer();
     379             :       }
     380             : 
     381             :       // Assignment.
     382             :       unique_ptr&
     383             :       operator=(unique_ptr&& __u) noexcept
     384             :       {
     385             :         reset(__u.release());
     386             :         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
     387             :         return *this;
     388             :       }
     389             : 
     390             :       template<typename _Up, typename _Ep>
     391             :         typename
     392             :         enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type
     393             :         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
     394             :         {
     395             :           reset(__u.release());
     396             :           get_deleter() = std::forward<_Ep>(__u.get_deleter());
     397             :           return *this;
     398             :         }
     399             : 
     400             :       unique_ptr&
     401             :       operator=(nullptr_t) noexcept
     402             :       {
     403             :         reset();
     404             :         return *this;
     405             :       }
     406             : 
     407             :       // Observers.
     408             :       typename std::add_lvalue_reference<element_type>::type
     409             :       operator[](size_t __i) const
     410             :       {
     411             :         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
     412             :         return get()[__i];
     413             :       }
     414             : 
     415             :       pointer
     416             :       get() const noexcept
     417             :       { return std::get<0>(_M_t); }
     418             : 
     419             :       deleter_type&
     420             :       get_deleter() noexcept
     421             :       { return std::get<1>(_M_t); }
     422             : 
     423             :       const deleter_type&
     424             :       get_deleter() const noexcept
     425             :       { return std::get<1>(_M_t); }
     426             : 
     427             :       explicit operator bool() const noexcept
     428             :       { return get() == pointer() ? false : true; }
     429             : 
     430             :       // Modifiers.
     431             :       pointer
     432             :       release() noexcept
     433             :       {
     434             :         pointer __p = get();
     435             :         std::get<0>(_M_t) = pointer();
     436             :         return __p;
     437             :       }
     438             : 
     439             :       void
     440             :       reset() noexcept
     441             :       { reset(pointer()); }
     442             : 
     443             :       void
     444             :       reset(pointer __p) noexcept
     445             :       {
     446             :         using std::swap;
     447             :         swap(std::get<0>(_M_t), __p);
     448             :         if (__p != nullptr)
     449             :           get_deleter()(__p);
     450             :       }
     451             : 
     452             :       template<typename _Up, typename = _Require<is_pointer<pointer>,
     453             :                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
     454             :         void reset(_Up*) = delete;
     455             : 
     456             :       void
     457             :       swap(unique_ptr& __u) noexcept
     458             :       {
     459             :         using std::swap;
     460             :         swap(_M_t, __u._M_t);
     461             :       }
     462             : 
     463             :       // Disable copy from lvalue.
     464             :       unique_ptr(const unique_ptr&) = delete;
     465             :       unique_ptr& operator=(const unique_ptr&) = delete;
     466             : 
     467             :       // Disable construction from convertible pointer types.
     468             :       template<typename _Up, typename = _Require<is_pointer<pointer>,
     469             :                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
     470             :         unique_ptr(_Up*, typename
     471             :                    conditional<is_reference<deleter_type>::value,
     472             :                    deleter_type, const deleter_type&>::type) = delete;
     473             : 
     474             :       template<typename _Up, typename = _Require<is_pointer<pointer>,
     475             :                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
     476             :         unique_ptr(_Up*, typename
     477             :                    remove_reference<deleter_type>::type&&) = delete;
     478             :     };
     479             : 
     480             :   template<typename _Tp, typename _Dp>
     481             :     inline void
     482             :     swap(unique_ptr<_Tp, _Dp>& __x,
     483             :          unique_ptr<_Tp, _Dp>& __y) noexcept
     484             :     { __x.swap(__y); }
     485             : 
     486             :   template<typename _Tp, typename _Dp,
     487             :            typename _Up, typename _Ep>
     488             :     inline bool
     489             :     operator==(const unique_ptr<_Tp, _Dp>& __x,
     490             :                const unique_ptr<_Up, _Ep>& __y)
     491             :     { return __x.get() == __y.get(); }
     492             : 
     493             :   template<typename _Tp, typename _Dp>
     494             :     inline bool
     495             :     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     496             :     { return !__x; }
     497             : 
     498             :   template<typename _Tp, typename _Dp>
     499             :     inline bool
     500             :     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     501             :     { return !__x; }
     502             : 
     503             :   template<typename _Tp, typename _Dp,
     504             :            typename _Up, typename _Ep>
     505             :     inline bool
     506             :     operator!=(const unique_ptr<_Tp, _Dp>& __x,
     507             :                const unique_ptr<_Up, _Ep>& __y)
     508             :     { return __x.get() != __y.get(); }
     509             : 
     510             :   template<typename _Tp, typename _Dp>
     511             :     inline bool
     512             :     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
     513             :     { return (bool)__x; }
     514             : 
     515             :   template<typename _Tp, typename _Dp>
     516             :     inline bool
     517             :     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
     518             :     { return (bool)__x; }
     519             : 
     520             :   template<typename _Tp, typename _Dp,
     521             :            typename _Up, typename _Ep>
     522             :     inline bool
     523             :     operator<(const unique_ptr<_Tp, _Dp>& __x,
     524             :               const unique_ptr<_Up, _Ep>& __y)
     525             :     {
     526             :       typedef typename
     527             :         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
     528             :                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
     529             :       return std::less<_CT>()(__x.get(), __y.get());
     530             :     }
     531             : 
     532             :   template<typename _Tp, typename _Dp>
     533             :     inline bool
     534             :     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     535             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     536             :                                                                  nullptr); }
     537             : 
     538             :   template<typename _Tp, typename _Dp>
     539             :     inline bool
     540             :     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     541             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     542             :                                                                  __x.get()); }
     543             : 
     544             :   template<typename _Tp, typename _Dp,
     545             :            typename _Up, typename _Ep>
     546             :     inline bool
     547             :     operator<=(const unique_ptr<_Tp, _Dp>& __x,
     548             :                const unique_ptr<_Up, _Ep>& __y)
     549             :     { return !(__y < __x); }
     550             : 
     551             :   template<typename _Tp, typename _Dp>
     552             :     inline bool
     553             :     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     554             :     { return !(nullptr < __x); }
     555             : 
     556             :   template<typename _Tp, typename _Dp>
     557             :     inline bool
     558             :     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     559             :     { return !(__x < nullptr); }
     560             : 
     561             :   template<typename _Tp, typename _Dp,
     562             :            typename _Up, typename _Ep>
     563             :     inline bool
     564             :     operator>(const unique_ptr<_Tp, _Dp>& __x,
     565             :               const unique_ptr<_Up, _Ep>& __y)
     566             :     { return (__y < __x); }
     567             : 
     568             :   template<typename _Tp, typename _Dp>
     569             :     inline bool
     570             :     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     571             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
     572             :                                                                  __x.get()); }
     573             : 
     574             :   template<typename _Tp, typename _Dp>
     575             :     inline bool
     576             :     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     577             :     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
     578             :                                                                  nullptr); }
     579             : 
     580             :   template<typename _Tp, typename _Dp,
     581             :            typename _Up, typename _Ep>
     582             :     inline bool
     583             :     operator>=(const unique_ptr<_Tp, _Dp>& __x,
     584             :                const unique_ptr<_Up, _Ep>& __y)
     585             :     { return !(__x < __y); }
     586             : 
     587             :   template<typename _Tp, typename _Dp>
     588             :     inline bool
     589             :     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
     590             :     { return !(__x < nullptr); }
     591             : 
     592             :   template<typename _Tp, typename _Dp>
     593             :     inline bool
     594             :     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
     595             :     { return !(nullptr < __x); }
     596             : 
     597             :   /// std::hash specialization for unique_ptr.
     598             :   template<typename _Tp, typename _Dp>
     599             :     struct hash<unique_ptr<_Tp, _Dp>>
     600             :     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
     601             :     {
     602             :       size_t
     603             :       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
     604             :       {
     605             :         typedef unique_ptr<_Tp, _Dp> _UP;
     606             :         return std::hash<typename _UP::pointer>()(__u.get());
     607             :       }
     608             :     };
     609             : 
     610             :   // @} group pointer_abstractions
     611             : 
     612             : _GLIBCXX_END_NAMESPACE_VERSION
     613             : } // namespace
     614             : 
     615             : #endif /* _UNIQUE_PTR_H */

Generated by: LCOV version 1.11