libstdc++

unique_ptr.h

Go to the documentation of this file.
00001 // unique_ptr implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/unique_ptr.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{memory}
00028  */
00029 
00030 #ifndef _UNIQUE_PTR_H
00031 #define _UNIQUE_PTR_H 1
00032 
00033 #include <bits/c++config.h>
00034 #include <debug/debug.h>
00035 #include <type_traits>
00036 #include <utility>
00037 #include <tuple>
00038 
00039 namespace std _GLIBCXX_VISIBILITY(default)
00040 {
00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00042 
00043   /**
00044    * @addtogroup pointer_abstractions
00045    * @{
00046    */
00047 
00048 #if _GLIBCXX_USE_DEPRECATED
00049   template<typename> class auto_ptr;
00050 #endif
00051 
00052   /// Primary template of default_delete, used by unique_ptr
00053   template<typename _Tp>
00054     struct default_delete
00055     {
00056       /// Default constructor
00057       constexpr default_delete() noexcept = default;
00058 
00059       /** @brief Converting constructor.
00060        *
00061        * Allows conversion from a deleter for arrays of another type, @p _Up,
00062        * only if @p _Up* is convertible to @p _Tp*.
00063        */
00064       template<typename _Up, typename = typename
00065                enable_if<is_convertible<_Up*, _Tp*>::value>::type>
00066         default_delete(const default_delete<_Up>&) noexcept { }
00067 
00068       /// Calls @c delete @p __ptr
00069       void
00070       operator()(_Tp* __ptr) const
00071       {
00072         static_assert(!is_void<_Tp>::value,
00073                       "can't delete pointer to incomplete type");
00074         static_assert(sizeof(_Tp)>0,
00075                       "can't delete pointer to incomplete type");
00076         delete __ptr;
00077       }
00078     };
00079 
00080   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00081   // DR 740 - omit specialization for array objects with a compile time length
00082   /// Specialization for arrays, default_delete.
00083   template<typename _Tp>
00084     struct default_delete<_Tp[]>
00085     {
00086     private:
00087       template<typename _Up>
00088         using __remove_cv = typename remove_cv<_Up>::type;
00089 
00090       // Like is_base_of<_Tp, _Up> but false if unqualified types are the same
00091       template<typename _Up>
00092         using __is_derived_Tp
00093           = __and_< is_base_of<_Tp, _Up>,
00094                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
00095 
00096     public:
00097       /// Default constructor
00098       constexpr default_delete() noexcept = default;
00099 
00100       /** @brief Converting constructor.
00101        *
00102        * Allows conversion from a deleter for arrays of another type, such as
00103        * a const-qualified version of @p _Tp.
00104        *
00105        * Conversions from types derived from @c _Tp are not allowed because
00106        * it is unsafe to @c delete[] an array of derived types through a
00107        * pointer to the base type.
00108        */
00109       template<typename _Up, typename = typename
00110                enable_if<!__is_derived_Tp<_Up>::value>::type>
00111         default_delete(const default_delete<_Up[]>&) noexcept { }
00112 
00113       /// Calls @c delete[] @p __ptr
00114       void
00115       operator()(_Tp* __ptr) const
00116       {
00117         static_assert(sizeof(_Tp)>0,
00118                       "can't delete pointer to incomplete type");
00119         delete [] __ptr;
00120       }
00121 
00122       template<typename _Up>
00123         typename enable_if<__is_derived_Tp<_Up>::value>::type
00124         operator()(_Up*) const = delete;
00125     };
00126 
00127   /// 20.7.1.2 unique_ptr for single objects.
00128   template <typename _Tp, typename _Dp = default_delete<_Tp> >
00129     class unique_ptr
00130     {
00131       // use SFINAE to determine whether _Del::pointer exists
00132       class _Pointer
00133       {
00134         template<typename _Up>
00135           static typename _Up::pointer __test(typename _Up::pointer*);
00136 
00137         template<typename _Up>
00138           static _Tp* __test(...);
00139 
00140         typedef typename remove_reference<_Dp>::type _Del;
00141 
00142       public:
00143         typedef decltype(__test<_Del>(0)) type;
00144       };
00145 
00146       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
00147       __tuple_type                                      _M_t;
00148 
00149     public:
00150       typedef typename _Pointer::type   pointer;
00151       typedef _Tp                       element_type;
00152       typedef _Dp                       deleter_type;
00153 
00154       // Constructors.
00155 
00156       /// Default constructor, creates a unique_ptr that owns nothing.
00157       constexpr unique_ptr() noexcept
00158       : _M_t()
00159       { static_assert(!is_pointer<deleter_type>::value,
00160                      "constructed with null function pointer deleter"); }
00161 
00162       /** Takes ownership of a pointer.
00163        *
00164        * @param __p  A pointer to an object of @c element_type
00165        *
00166        * The deleter will be value-initialized.
00167        */
00168       explicit
00169       unique_ptr(pointer __p) noexcept
00170       : _M_t()
00171       {
00172         std::get<0>(_M_t) = __p;
00173         static_assert(!is_pointer<deleter_type>::value,
00174                      "constructed with null function pointer deleter");
00175       }
00176 
00177       /** Takes ownership of a pointer.
00178        *
00179        * @param __p  A pointer to an object of @c element_type
00180        * @param __d  A reference to a deleter.
00181        *
00182        * The deleter will be initialized with @p __d
00183        */
00184       unique_ptr(pointer __p,
00185           typename conditional<is_reference<deleter_type>::value,
00186             deleter_type, const deleter_type&>::type __d) noexcept
00187       : _M_t(__p, __d) { }
00188 
00189       /** Takes ownership of a pointer.
00190        *
00191        * @param __p  A pointer to an object of @c element_type
00192        * @param __d  An rvalue reference to a deleter.
00193        *
00194        * The deleter will be initialized with @p std::move(__d)
00195        */
00196       unique_ptr(pointer __p,
00197           typename remove_reference<deleter_type>::type&& __d) noexcept
00198       : _M_t(std::move(__p), std::move(__d))
00199       { static_assert(!std::is_reference<deleter_type>::value,
00200                       "rvalue deleter bound to reference"); }
00201 
00202       /// Creates a unique_ptr that owns nothing.
00203       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
00204 
00205       // Move constructors.
00206 
00207       /// Move constructor.
00208       unique_ptr(unique_ptr&& __u) noexcept
00209       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00210 
00211       /** @brief Converting constructor from another type
00212        *
00213        * Requires that the pointer owned by @p __u is convertible to the
00214        * type of pointer owned by this object, @p __u does not own an array,
00215        * and @p __u has a compatible deleter type.
00216        */
00217       template<typename _Up, typename _Ep, typename = _Require<
00218                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
00219                __not_<is_array<_Up>>,
00220                typename conditional<is_reference<_Dp>::value,
00221                                     is_same<_Ep, _Dp>,
00222                                     is_convertible<_Ep, _Dp>>::type>>
00223         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
00224         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
00225         { }
00226 
00227 #if _GLIBCXX_USE_DEPRECATED
00228       /// Converting constructor from @c auto_ptr
00229       template<typename _Up, typename = _Require<
00230                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
00231         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
00232 #endif
00233 
00234       /// Destructor, invokes the deleter if the stored pointer is not null.
00235       ~unique_ptr() noexcept
00236       {
00237         auto& __ptr = std::get<0>(_M_t);
00238         if (__ptr != nullptr)
00239           get_deleter()(__ptr);
00240         __ptr = pointer();
00241       }
00242 
00243       // Assignment.
00244 
00245       /** @brief Move assignment operator.
00246        *
00247        * @param __u  The object to transfer ownership from.
00248        *
00249        * Invokes the deleter first if this object owns a pointer.
00250        */
00251       unique_ptr&
00252       operator=(unique_ptr&& __u) noexcept
00253       {
00254         reset(__u.release());
00255         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
00256         return *this;
00257       }
00258 
00259       /** @brief Assignment from another type.
00260        *
00261        * @param __u  The object to transfer ownership from, which owns a
00262        *             convertible pointer to a non-array object.
00263        *
00264        * Invokes the deleter first if this object owns a pointer.
00265        */
00266       template<typename _Up, typename _Ep>
00267         typename enable_if< __and_<
00268           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
00269           __not_<is_array<_Up>>
00270           >::value,
00271           unique_ptr&>::type
00272         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
00273         {
00274           reset(__u.release());
00275           get_deleter() = std::forward<_Ep>(__u.get_deleter());
00276           return *this;
00277         }
00278 
00279       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
00280       unique_ptr&
00281       operator=(nullptr_t) noexcept
00282       {
00283         reset();
00284         return *this;
00285       }
00286 
00287       // Observers.
00288 
00289       /// Dereference the stored pointer.
00290       typename add_lvalue_reference<element_type>::type
00291       operator*() const
00292       {
00293         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00294         return *get();
00295       }
00296 
00297       /// Return the stored pointer.
00298       pointer
00299       operator->() const noexcept
00300       {
00301         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00302         return get();
00303       }
00304 
00305       /// Return the stored pointer.
00306       pointer
00307       get() const noexcept
00308       { return std::get<0>(_M_t); }
00309 
00310       /// Return a reference to the stored deleter.
00311       deleter_type&
00312       get_deleter() noexcept
00313       { return std::get<1>(_M_t); }
00314 
00315       /// Return a reference to the stored deleter.
00316       const deleter_type&
00317       get_deleter() const noexcept
00318       { return std::get<1>(_M_t); }
00319 
00320       /// Return @c true if the stored pointer is not null.
00321       explicit operator bool() const noexcept
00322       { return get() == pointer() ? false : true; }
00323 
00324       // Modifiers.
00325 
00326       /// Release ownership of any stored pointer.
00327       pointer
00328       release() noexcept
00329       {
00330         pointer __p = get();
00331         std::get<0>(_M_t) = pointer();
00332         return __p;
00333       }
00334 
00335       /** @brief Replace the stored pointer.
00336        *
00337        * @param __p  The new pointer to store.
00338        *
00339        * The deleter will be invoked if a pointer is already owned.
00340        */
00341       void
00342       reset(pointer __p = pointer()) noexcept
00343       {
00344         using std::swap;
00345         swap(std::get<0>(_M_t), __p);
00346         if (__p != pointer())
00347           get_deleter()(__p);
00348       }
00349 
00350       /// Exchange the pointer and deleter with another object.
00351       void
00352       swap(unique_ptr& __u) noexcept
00353       {
00354         using std::swap;
00355         swap(_M_t, __u._M_t);
00356       }
00357 
00358       // Disable copy from lvalue.
00359       unique_ptr(const unique_ptr&) = delete;
00360       unique_ptr& operator=(const unique_ptr&) = delete;
00361   };
00362 
00363   /// 20.7.1.3 unique_ptr for array objects with a runtime length
00364   // [unique.ptr.runtime]
00365   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00366   // DR 740 - omit specialization for array objects with a compile time length
00367   template<typename _Tp, typename _Dp>
00368     class unique_ptr<_Tp[], _Dp>
00369     {
00370       // use SFINAE to determine whether _Del::pointer exists
00371       class _Pointer
00372       {
00373         template<typename _Up>
00374           static typename _Up::pointer __test(typename _Up::pointer*);
00375 
00376         template<typename _Up>
00377           static _Tp* __test(...);
00378 
00379         typedef typename remove_reference<_Dp>::type _Del;
00380 
00381       public:
00382         typedef decltype(__test<_Del>(0)) type;
00383       };
00384 
00385       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
00386       __tuple_type                                      _M_t;
00387 
00388       template<typename _Up>
00389         using __remove_cv = typename remove_cv<_Up>::type;
00390 
00391       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
00392       template<typename _Up>
00393         using __is_derived_Tp
00394           = __and_< is_base_of<_Tp, _Up>,
00395                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
00396 
00397       template<typename _Up, typename _Ep,
00398                typename _Tp_pointer = typename _Pointer::type,
00399                typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer>
00400         using __safe_conversion = __and_<
00401             is_convertible<_Up_pointer, _Tp_pointer>,
00402             is_array<_Up>,
00403             __or_<__not_<is_pointer<_Up_pointer>>,
00404                   __not_<is_pointer<_Tp_pointer>>,
00405                   __not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
00406             >
00407           >;
00408 
00409     public:
00410       typedef typename _Pointer::type   pointer;
00411       typedef _Tp                       element_type;
00412       typedef _Dp                       deleter_type;
00413 
00414       // Constructors.
00415 
00416       /// Default constructor, creates a unique_ptr that owns nothing.
00417       constexpr unique_ptr() noexcept
00418       : _M_t()
00419       { static_assert(!std::is_pointer<deleter_type>::value,
00420                       "constructed with null function pointer deleter"); }
00421 
00422       /** Takes ownership of a pointer.
00423        *
00424        * @param __p  A pointer to an array of @c element_type
00425        *
00426        * The deleter will be value-initialized.
00427        */
00428       explicit
00429       unique_ptr(pointer __p) noexcept
00430       : _M_t(__p, deleter_type())
00431       { static_assert(!is_pointer<deleter_type>::value,
00432                       "constructed with null function pointer deleter"); }
00433 
00434       // Disable construction from convertible pointer types.
00435       template<typename _Up, typename = _Require<is_pointer<pointer>,
00436                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
00437         explicit
00438         unique_ptr(_Up* __p) = delete;
00439 
00440       /** Takes ownership of a pointer.
00441        *
00442        * @param __p  A pointer to an array of @c element_type
00443        * @param __d  A reference to a deleter.
00444        *
00445        * The deleter will be initialized with @p __d
00446        */
00447       unique_ptr(pointer __p,
00448           typename conditional<is_reference<deleter_type>::value,
00449               deleter_type, const deleter_type&>::type __d) noexcept
00450       : _M_t(__p, __d) { }
00451 
00452       /** Takes ownership of a pointer.
00453        *
00454        * @param __p  A pointer to an array of @c element_type
00455        * @param __d  A reference to a deleter.
00456        *
00457        * The deleter will be initialized with @p std::move(__d)
00458        */
00459       unique_ptr(pointer __p, typename
00460                  remove_reference<deleter_type>::type&& __d) noexcept
00461       : _M_t(std::move(__p), std::move(__d))
00462       { static_assert(!is_reference<deleter_type>::value,
00463                       "rvalue deleter bound to reference"); }
00464 
00465       /// Move constructor.
00466       unique_ptr(unique_ptr&& __u) noexcept
00467       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00468 
00469       /// Creates a unique_ptr that owns nothing.
00470       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
00471 
00472       template<typename _Up, typename _Ep,
00473                typename = _Require<__safe_conversion<_Up, _Ep>,
00474                  typename conditional<is_reference<_Dp>::value,
00475                                       is_same<_Ep, _Dp>,
00476                                       is_convertible<_Ep, _Dp>>::type
00477                >>
00478         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
00479         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
00480         { }
00481 
00482       /// Destructor, invokes the deleter if the stored pointer is not null.
00483       ~unique_ptr()
00484       {
00485         auto& __ptr = std::get<0>(_M_t);
00486         if (__ptr != nullptr)
00487           get_deleter()(__ptr);
00488         __ptr = pointer();
00489       }
00490 
00491       // Assignment.
00492 
00493       /** @brief Move assignment operator.
00494        *
00495        * @param __u  The object to transfer ownership from.
00496        *
00497        * Invokes the deleter first if this object owns a pointer.
00498        */
00499       unique_ptr&
00500       operator=(unique_ptr&& __u) noexcept
00501       {
00502         reset(__u.release());
00503         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
00504         return *this;
00505       }
00506 
00507       /** @brief Assignment from another type.
00508        *
00509        * @param __u  The object to transfer ownership from, which owns a
00510        *             convertible pointer to an array object.
00511        *
00512        * Invokes the deleter first if this object owns a pointer.
00513        */
00514       template<typename _Up, typename _Ep>
00515         typename
00516         enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type
00517         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
00518         {
00519           reset(__u.release());
00520           get_deleter() = std::forward<_Ep>(__u.get_deleter());
00521           return *this;
00522         }
00523 
00524       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
00525       unique_ptr&
00526       operator=(nullptr_t) noexcept
00527       {
00528         reset();
00529         return *this;
00530       }
00531 
00532       // Observers.
00533 
00534       /// Access an element of owned array.
00535       typename std::add_lvalue_reference<element_type>::type
00536       operator[](size_t __i) const
00537       {
00538         _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00539         return get()[__i];
00540       }
00541 
00542       /// Return the stored pointer.
00543       pointer
00544       get() const noexcept
00545       { return std::get<0>(_M_t); }
00546 
00547       /// Return a reference to the stored deleter.
00548       deleter_type&
00549       get_deleter() noexcept
00550       { return std::get<1>(_M_t); }
00551 
00552       /// Return a reference to the stored deleter.
00553       const deleter_type&
00554       get_deleter() const noexcept
00555       { return std::get<1>(_M_t); }
00556 
00557       /// Return @c true if the stored pointer is not null.
00558       explicit operator bool() const noexcept
00559       { return get() == pointer() ? false : true; }
00560 
00561       // Modifiers.
00562 
00563       /// Release ownership of any stored pointer.
00564       pointer
00565       release() noexcept
00566       {
00567         pointer __p = get();
00568         std::get<0>(_M_t) = pointer();
00569         return __p;
00570       }
00571 
00572       /** @brief Replace the stored pointer.
00573        *
00574        * @param __p  The new pointer to store.
00575        *
00576        * The deleter will be invoked if a pointer is already owned.
00577        */
00578       void
00579       reset(pointer __p = pointer()) noexcept
00580       {
00581         using std::swap;
00582         swap(std::get<0>(_M_t), __p);
00583         if (__p != nullptr)
00584           get_deleter()(__p);
00585       }
00586 
00587       // Disable resetting from convertible pointer types.
00588       template<typename _Up, typename = _Require<is_pointer<pointer>,
00589                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
00590         void reset(_Up*) = delete;
00591 
00592       /// Exchange the pointer and deleter with another object.
00593       void
00594       swap(unique_ptr& __u) noexcept
00595       {
00596         using std::swap;
00597         swap(_M_t, __u._M_t);
00598       }
00599 
00600       // Disable copy from lvalue.
00601       unique_ptr(const unique_ptr&) = delete;
00602       unique_ptr& operator=(const unique_ptr&) = delete;
00603 
00604       // Disable construction from convertible pointer types.
00605       template<typename _Up, typename = _Require<is_pointer<pointer>,
00606                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
00607         unique_ptr(_Up*, typename
00608                    conditional<is_reference<deleter_type>::value,
00609                    deleter_type, const deleter_type&>::type) = delete;
00610 
00611       // Disable construction from convertible pointer types.
00612       template<typename _Up, typename = _Require<is_pointer<pointer>,
00613                is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
00614         unique_ptr(_Up*, typename
00615                    remove_reference<deleter_type>::type&&) = delete;
00616     };
00617 
00618   template<typename _Tp, typename _Dp>
00619     inline void
00620     swap(unique_ptr<_Tp, _Dp>& __x,
00621          unique_ptr<_Tp, _Dp>& __y) noexcept
00622     { __x.swap(__y); }
00623 
00624   template<typename _Tp, typename _Dp,
00625            typename _Up, typename _Ep>
00626     inline bool
00627     operator==(const unique_ptr<_Tp, _Dp>& __x,
00628                const unique_ptr<_Up, _Ep>& __y)
00629     { return __x.get() == __y.get(); }
00630 
00631   template<typename _Tp, typename _Dp>
00632     inline bool
00633     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
00634     { return !__x; }
00635 
00636   template<typename _Tp, typename _Dp>
00637     inline bool
00638     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
00639     { return !__x; }
00640 
00641   template<typename _Tp, typename _Dp,
00642            typename _Up, typename _Ep>
00643     inline bool
00644     operator!=(const unique_ptr<_Tp, _Dp>& __x,
00645                const unique_ptr<_Up, _Ep>& __y)
00646     { return __x.get() != __y.get(); }
00647 
00648   template<typename _Tp, typename _Dp>
00649     inline bool
00650     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
00651     { return (bool)__x; }
00652 
00653   template<typename _Tp, typename _Dp>
00654     inline bool
00655     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
00656     { return (bool)__x; }
00657 
00658   template<typename _Tp, typename _Dp,
00659            typename _Up, typename _Ep>
00660     inline bool
00661     operator<(const unique_ptr<_Tp, _Dp>& __x,
00662               const unique_ptr<_Up, _Ep>& __y)
00663     {
00664       typedef typename
00665         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
00666                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
00667       return std::less<_CT>()(__x.get(), __y.get());
00668     }
00669 
00670   template<typename _Tp, typename _Dp>
00671     inline bool
00672     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00673     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
00674                                                                  nullptr); }
00675 
00676   template<typename _Tp, typename _Dp>
00677     inline bool
00678     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00679     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
00680                                                                  __x.get()); }
00681 
00682   template<typename _Tp, typename _Dp,
00683            typename _Up, typename _Ep>
00684     inline bool
00685     operator<=(const unique_ptr<_Tp, _Dp>& __x,
00686                const unique_ptr<_Up, _Ep>& __y)
00687     { return !(__y < __x); }
00688 
00689   template<typename _Tp, typename _Dp>
00690     inline bool
00691     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00692     { return !(nullptr < __x); }
00693 
00694   template<typename _Tp, typename _Dp>
00695     inline bool
00696     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00697     { return !(__x < nullptr); }
00698 
00699   template<typename _Tp, typename _Dp,
00700            typename _Up, typename _Ep>
00701     inline bool
00702     operator>(const unique_ptr<_Tp, _Dp>& __x,
00703               const unique_ptr<_Up, _Ep>& __y)
00704     { return (__y < __x); }
00705 
00706   template<typename _Tp, typename _Dp>
00707     inline bool
00708     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00709     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
00710                                                                  __x.get()); }
00711 
00712   template<typename _Tp, typename _Dp>
00713     inline bool
00714     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00715     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
00716                                                                  nullptr); }
00717 
00718   template<typename _Tp, typename _Dp,
00719            typename _Up, typename _Ep>
00720     inline bool
00721     operator>=(const unique_ptr<_Tp, _Dp>& __x,
00722                const unique_ptr<_Up, _Ep>& __y)
00723     { return !(__x < __y); }
00724 
00725   template<typename _Tp, typename _Dp>
00726     inline bool
00727     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00728     { return !(__x < nullptr); }
00729 
00730   template<typename _Tp, typename _Dp>
00731     inline bool
00732     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00733     { return !(nullptr < __x); }
00734 
00735   /// std::hash specialization for unique_ptr.
00736   template<typename _Tp, typename _Dp>
00737     struct hash<unique_ptr<_Tp, _Dp>>
00738     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
00739     {
00740       size_t
00741       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
00742       {
00743         typedef unique_ptr<_Tp, _Dp> _UP;
00744         return std::hash<typename _UP::pointer>()(__u.get());
00745       }
00746     };
00747 
00748 #if __cplusplus > 201103L
00749 
00750 #define __cpp_lib_make_unique 201304
00751 
00752   template<typename _Tp>
00753     struct _MakeUniq
00754     { typedef unique_ptr<_Tp> __single_object; };
00755 
00756   template<typename _Tp>
00757     struct _MakeUniq<_Tp[]>
00758     { typedef unique_ptr<_Tp[]> __array; };
00759 
00760   template<typename _Tp, size_t _Bound>
00761     struct _MakeUniq<_Tp[_Bound]>
00762     { struct __invalid_type { }; };
00763 
00764   /// std::make_unique for single objects
00765   template<typename _Tp, typename... _Args>
00766     inline typename _MakeUniq<_Tp>::__single_object
00767     make_unique(_Args&&... __args)
00768     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
00769 
00770   /// std::make_unique for arrays of unknown bound
00771   template<typename _Tp>
00772     inline typename _MakeUniq<_Tp>::__array
00773     make_unique(size_t __num)
00774     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
00775 
00776   /// Disable std::make_unique for arrays of known bound
00777   template<typename _Tp, typename... _Args>
00778     inline typename _MakeUniq<_Tp>::__invalid_type
00779     make_unique(_Args&&...) = delete;
00780 #endif
00781 
00782   // @} group pointer_abstractions
00783 
00784 _GLIBCXX_END_NAMESPACE_VERSION
00785 } // namespace
00786 
00787 #endif /* _UNIQUE_PTR_H */