libstdc++
unique_ptr.h
Go to the documentation of this file.
00001 // unique_ptr implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2008-2019 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/assertions.h>
00035 #include <type_traits>
00036 #include <utility>
00037 #include <tuple>
00038 #include <bits/stl_function.h>
00039 #include <bits/functional_hash.h>
00040 
00041 namespace std _GLIBCXX_VISIBILITY(default)
00042 {
00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00044 
00045   /**
00046    * @addtogroup pointer_abstractions
00047    * @{
00048    */
00049 
00050 #if _GLIBCXX_USE_DEPRECATED
00051 #pragma GCC diagnostic push
00052 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00053   template<typename> class auto_ptr;
00054 #pragma GCC diagnostic pop
00055 #endif
00056 
00057   /// Primary template of default_delete, used by unique_ptr
00058   template<typename _Tp>
00059     struct default_delete
00060     {
00061       /// Default constructor
00062       constexpr default_delete() noexcept = default;
00063 
00064       /** @brief Converting constructor.
00065        *
00066        * Allows conversion from a deleter for arrays of another type, @p _Up,
00067        * only if @p _Up* is convertible to @p _Tp*.
00068        */
00069       template<typename _Up, typename = typename
00070                enable_if<is_convertible<_Up*, _Tp*>::value>::type>
00071         default_delete(const default_delete<_Up>&) noexcept { }
00072 
00073       /// Calls @c delete @p __ptr
00074       void
00075       operator()(_Tp* __ptr) const
00076       {
00077         static_assert(!is_void<_Tp>::value,
00078                       "can't delete pointer to incomplete type");
00079         static_assert(sizeof(_Tp)>0,
00080                       "can't delete pointer to incomplete type");
00081         delete __ptr;
00082       }
00083     };
00084 
00085   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00086   // DR 740 - omit specialization for array objects with a compile time length
00087   /// Specialization for arrays, default_delete.
00088   template<typename _Tp>
00089     struct default_delete<_Tp[]>
00090     {
00091     public:
00092       /// Default constructor
00093       constexpr default_delete() noexcept = default;
00094 
00095       /** @brief Converting constructor.
00096        *
00097        * Allows conversion from a deleter for arrays of another type, such as
00098        * a const-qualified version of @p _Tp.
00099        *
00100        * Conversions from types derived from @c _Tp are not allowed because
00101        * it is unsafe to @c delete[] an array of derived types through a
00102        * pointer to the base type.
00103        */
00104       template<typename _Up, typename = typename
00105                enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
00106         default_delete(const default_delete<_Up[]>&) noexcept { }
00107 
00108       /// Calls @c delete[] @p __ptr
00109       template<typename _Up>
00110       typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
00111         operator()(_Up* __ptr) const
00112       {
00113         static_assert(sizeof(_Tp)>0,
00114                       "can't delete pointer to incomplete type");
00115         delete [] __ptr;
00116       }
00117     };
00118 
00119   template <typename _Tp, typename _Dp>
00120     class __uniq_ptr_impl
00121     {
00122       template <typename _Up, typename _Ep, typename = void>
00123         struct _Ptr
00124         {
00125           using type = _Up*;
00126         };
00127 
00128       template <typename _Up, typename _Ep>
00129         struct
00130         _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
00131         {
00132           using type = typename remove_reference<_Ep>::type::pointer;
00133         };
00134 
00135     public:
00136       using _DeleterConstraint = enable_if<
00137         __and_<__not_<is_pointer<_Dp>>,
00138                is_default_constructible<_Dp>>::value>;
00139 
00140       using pointer = typename _Ptr<_Tp, _Dp>::type;
00141 
00142       static_assert( !is_rvalue_reference<_Dp>::value,
00143                      "unique_ptr's deleter type must be a function object type"
00144                      " or an lvalue reference type" );
00145 
00146       __uniq_ptr_impl() = default;
00147       __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
00148 
00149       template<typename _Del>
00150       __uniq_ptr_impl(pointer __p, _Del&& __d)
00151         : _M_t(__p, std::forward<_Del>(__d)) { }
00152 
00153       pointer&   _M_ptr() { return std::get<0>(_M_t); }
00154       pointer    _M_ptr() const { return std::get<0>(_M_t); }
00155       _Dp&       _M_deleter() { return std::get<1>(_M_t); }
00156       const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
00157 
00158       void
00159       swap(__uniq_ptr_impl& __rhs) noexcept
00160       {
00161         using std::swap;
00162         swap(this->_M_ptr(), __rhs._M_ptr());
00163         swap(this->_M_deleter(), __rhs._M_deleter());
00164       }
00165 
00166     private:
00167       tuple<pointer, _Dp> _M_t;
00168     };
00169 
00170   /// 20.7.1.2 unique_ptr for single objects.
00171   template <typename _Tp, typename _Dp = default_delete<_Tp>>
00172     class unique_ptr
00173     {
00174       template <typename _Up>
00175         using _DeleterConstraint =
00176           typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
00177 
00178       __uniq_ptr_impl<_Tp, _Dp> _M_t;
00179 
00180     public:
00181       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
00182       using element_type  = _Tp;
00183       using deleter_type  = _Dp;
00184 
00185     private:
00186       // helper template for detecting a safe conversion from another
00187       // unique_ptr
00188       template<typename _Up, typename _Ep>
00189         using __safe_conversion_up = __and_<
00190           is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
00191           __not_<is_array<_Up>>
00192         >;
00193 
00194     public:
00195       // Constructors.
00196 
00197       /// Default constructor, creates a unique_ptr that owns nothing.
00198       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
00199         constexpr unique_ptr() noexcept
00200         : _M_t()
00201         { }
00202 
00203       /** Takes ownership of a pointer.
00204        *
00205        * @param __p  A pointer to an object of @c element_type
00206        *
00207        * The deleter will be value-initialized.
00208        */
00209       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
00210         explicit
00211         unique_ptr(pointer __p) noexcept
00212         : _M_t(__p)
00213         { }
00214 
00215       /** Takes ownership of a pointer.
00216        *
00217        * @param __p  A pointer to an object of @c element_type
00218        * @param __d  A reference to a deleter.
00219        *
00220        * The deleter will be initialized with @p __d
00221        */
00222       template<typename _Del = deleter_type,
00223                typename = _Require<is_copy_constructible<_Del>>>
00224         unique_ptr(pointer __p, const deleter_type& __d) noexcept
00225         : _M_t(__p, __d) { }
00226 
00227       /** Takes ownership of a pointer.
00228        *
00229        * @param __p  A pointer to an object of @c element_type
00230        * @param __d  An rvalue reference to a (non-reference) deleter.
00231        *
00232        * The deleter will be initialized with @p std::move(__d)
00233        */
00234       template<typename _Del = deleter_type,
00235                typename = _Require<is_move_constructible<_Del>>>
00236         unique_ptr(pointer __p,
00237                    __enable_if_t<!is_lvalue_reference<_Del>::value,
00238                                  _Del&&> __d) noexcept
00239         : _M_t(__p, std::move(__d))
00240         { }
00241 
00242       template<typename _Del = deleter_type,
00243                typename _DelUnref = typename remove_reference<_Del>::type>
00244         unique_ptr(pointer,
00245                    __enable_if_t<is_lvalue_reference<_Del>::value,
00246                                  _DelUnref&&>) = delete;
00247 
00248       /// Creates a unique_ptr that owns nothing.
00249       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
00250         constexpr unique_ptr(nullptr_t) noexcept
00251         : _M_t()
00252         { }
00253 
00254       // Move constructors.
00255 
00256       /// Move constructor.
00257       unique_ptr(unique_ptr&& __u) noexcept
00258       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00259 
00260       /** @brief Converting constructor from another type
00261        *
00262        * Requires that the pointer owned by @p __u is convertible to the
00263        * type of pointer owned by this object, @p __u does not own an array,
00264        * and @p __u has a compatible deleter type.
00265        */
00266       template<typename _Up, typename _Ep, typename = _Require<
00267                __safe_conversion_up<_Up, _Ep>,
00268                typename conditional<is_reference<_Dp>::value,
00269                                     is_same<_Ep, _Dp>,
00270                                     is_convertible<_Ep, _Dp>>::type>>
00271         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
00272         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
00273         { }
00274 
00275 #if _GLIBCXX_USE_DEPRECATED
00276 #pragma GCC diagnostic push
00277 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00278       /// Converting constructor from @c auto_ptr
00279       template<typename _Up, typename = _Require<
00280                is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
00281         unique_ptr(auto_ptr<_Up>&& __u) noexcept;
00282 #pragma GCC diagnostic pop
00283 #endif
00284 
00285       /// Destructor, invokes the deleter if the stored pointer is not null.
00286       ~unique_ptr() noexcept
00287       {
00288         static_assert(__is_invocable<deleter_type&, pointer>::value,
00289                       "unique_ptr's deleter must be invocable with a pointer");
00290         auto& __ptr = _M_t._M_ptr();
00291         if (__ptr != nullptr)
00292           get_deleter()(std::move(__ptr));
00293         __ptr = pointer();
00294       }
00295 
00296       // Assignment.
00297 
00298       /** @brief Move assignment operator.
00299        *
00300        * @param __u  The object to transfer ownership from.
00301        *
00302        * Invokes the deleter first if this object owns a pointer.
00303        */
00304       unique_ptr&
00305       operator=(unique_ptr&& __u) noexcept
00306       {
00307         reset(__u.release());
00308         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
00309         return *this;
00310       }
00311 
00312       /** @brief Assignment from another type.
00313        *
00314        * @param __u  The object to transfer ownership from, which owns a
00315        *             convertible pointer to a non-array object.
00316        *
00317        * Invokes the deleter first if this object owns a pointer.
00318        */
00319       template<typename _Up, typename _Ep>
00320         typename enable_if< __and_<
00321           __safe_conversion_up<_Up, _Ep>,
00322           is_assignable<deleter_type&, _Ep&&>
00323           >::value,
00324           unique_ptr&>::type
00325         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
00326         {
00327           reset(__u.release());
00328           get_deleter() = std::forward<_Ep>(__u.get_deleter());
00329           return *this;
00330         }
00331 
00332       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
00333       unique_ptr&
00334       operator=(nullptr_t) noexcept
00335       {
00336         reset();
00337         return *this;
00338       }
00339 
00340       // Observers.
00341 
00342       /// Dereference the stored pointer.
00343       typename add_lvalue_reference<element_type>::type
00344       operator*() const
00345       {
00346         __glibcxx_assert(get() != pointer());
00347         return *get();
00348       }
00349 
00350       /// Return the stored pointer.
00351       pointer
00352       operator->() const noexcept
00353       {
00354         _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
00355         return get();
00356       }
00357 
00358       /// Return the stored pointer.
00359       pointer
00360       get() const noexcept
00361       { return _M_t._M_ptr(); }
00362 
00363       /// Return a reference to the stored deleter.
00364       deleter_type&
00365       get_deleter() noexcept
00366       { return _M_t._M_deleter(); }
00367 
00368       /// Return a reference to the stored deleter.
00369       const deleter_type&
00370       get_deleter() const noexcept
00371       { return _M_t._M_deleter(); }
00372 
00373       /// Return @c true if the stored pointer is not null.
00374       explicit operator bool() const noexcept
00375       { return get() == pointer() ? false : true; }
00376 
00377       // Modifiers.
00378 
00379       /// Release ownership of any stored pointer.
00380       pointer
00381       release() noexcept
00382       {
00383         pointer __p = get();
00384         _M_t._M_ptr() = pointer();
00385         return __p;
00386       }
00387 
00388       /** @brief Replace the stored pointer.
00389        *
00390        * @param __p  The new pointer to store.
00391        *
00392        * The deleter will be invoked if a pointer is already owned.
00393        */
00394       void
00395       reset(pointer __p = pointer()) noexcept
00396       {
00397         static_assert(__is_invocable<deleter_type&, pointer>::value,
00398                       "unique_ptr's deleter must be invocable with a pointer");
00399         using std::swap;
00400         swap(_M_t._M_ptr(), __p);
00401         if (__p != pointer())
00402           get_deleter()(std::move(__p));
00403       }
00404 
00405       /// Exchange the pointer and deleter with another object.
00406       void
00407       swap(unique_ptr& __u) noexcept
00408       {
00409         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
00410         _M_t.swap(__u._M_t);
00411       }
00412 
00413       // Disable copy from lvalue.
00414       unique_ptr(const unique_ptr&) = delete;
00415       unique_ptr& operator=(const unique_ptr&) = delete;
00416   };
00417 
00418   /// 20.7.1.3 unique_ptr for array objects with a runtime length
00419   // [unique.ptr.runtime]
00420   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00421   // DR 740 - omit specialization for array objects with a compile time length
00422   template<typename _Tp, typename _Dp>
00423     class unique_ptr<_Tp[], _Dp>
00424     {
00425       template <typename _Up>
00426       using _DeleterConstraint =
00427         typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
00428 
00429       __uniq_ptr_impl<_Tp, _Dp> _M_t;
00430 
00431       template<typename _Up>
00432         using __remove_cv = typename remove_cv<_Up>::type;
00433 
00434       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
00435       template<typename _Up>
00436         using __is_derived_Tp
00437           = __and_< is_base_of<_Tp, _Up>,
00438                     __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
00439 
00440     public:
00441       using pointer       = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
00442       using element_type  = _Tp;
00443       using deleter_type  = _Dp;
00444 
00445       // helper template for detecting a safe conversion from another
00446       // unique_ptr
00447       template<typename _Up, typename _Ep,
00448                typename _UPtr = unique_ptr<_Up, _Ep>,
00449                typename _UP_pointer = typename _UPtr::pointer,
00450                typename _UP_element_type = typename _UPtr::element_type>
00451         using __safe_conversion_up = __and_<
00452           is_array<_Up>,
00453           is_same<pointer, element_type*>,
00454           is_same<_UP_pointer, _UP_element_type*>,
00455           is_convertible<_UP_element_type(*)[], element_type(*)[]>
00456         >;
00457 
00458       // helper template for detecting a safe conversion from a raw pointer
00459       template<typename _Up>
00460         using __safe_conversion_raw = __and_<
00461           __or_<__or_<is_same<_Up, pointer>,
00462                       is_same<_Up, nullptr_t>>,
00463                 __and_<is_pointer<_Up>,
00464                        is_same<pointer, element_type*>,
00465                        is_convertible<
00466                          typename remove_pointer<_Up>::type(*)[],
00467                          element_type(*)[]>
00468                 >
00469           >
00470         >;
00471 
00472       // Constructors.
00473 
00474       /// Default constructor, creates a unique_ptr that owns nothing.
00475       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
00476         constexpr unique_ptr() noexcept
00477         : _M_t()
00478         { }
00479 
00480       /** Takes ownership of a pointer.
00481        *
00482        * @param __p  A pointer to an array of a type safely convertible
00483        * to an array of @c element_type
00484        *
00485        * The deleter will be value-initialized.
00486        */
00487       template<typename _Up,
00488                typename _Vp = _Dp,
00489                typename = _DeleterConstraint<_Vp>,
00490                typename = typename enable_if<
00491                  __safe_conversion_raw<_Up>::value, bool>::type>
00492         explicit
00493         unique_ptr(_Up __p) noexcept
00494         : _M_t(__p)
00495         { }
00496 
00497       /** Takes ownership of a pointer.
00498        *
00499        * @param __p  A pointer to an array of a type safely convertible
00500        * to an array of @c element_type
00501        * @param __d  A reference to a deleter.
00502        *
00503        * The deleter will be initialized with @p __d
00504        */
00505       template<typename _Up, typename _Del = deleter_type,
00506                typename = _Require<__safe_conversion_raw<_Up>,
00507                                    is_copy_constructible<_Del>>>
00508       unique_ptr(_Up __p, const deleter_type& __d) noexcept
00509       : _M_t(__p, __d) { }
00510 
00511       /** Takes ownership of a pointer.
00512        *
00513        * @param __p  A pointer to an array of a type safely convertible
00514        * to an array of @c element_type
00515        * @param __d  A reference to a deleter.
00516        *
00517        * The deleter will be initialized with @p std::move(__d)
00518        */
00519       template<typename _Up, typename _Del = deleter_type,
00520                typename = _Require<__safe_conversion_raw<_Up>,
00521                                    is_move_constructible<_Del>>>
00522         unique_ptr(_Up __p,
00523                    __enable_if_t<!is_lvalue_reference<_Del>::value,
00524                                  _Del&&> __d) noexcept
00525         : _M_t(std::move(__p), std::move(__d))
00526         { }
00527 
00528       template<typename _Up, typename _Del = deleter_type,
00529                typename _DelUnref = typename remove_reference<_Del>::type,
00530                typename = _Require<__safe_conversion_raw<_Up>>>
00531         unique_ptr(_Up,
00532                    __enable_if_t<is_lvalue_reference<_Del>::value,
00533                                  _DelUnref&&>) = delete;
00534 
00535       /// Move constructor.
00536       unique_ptr(unique_ptr&& __u) noexcept
00537       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00538 
00539       /// Creates a unique_ptr that owns nothing.
00540       template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
00541         constexpr unique_ptr(nullptr_t) noexcept
00542         : _M_t()
00543         { }
00544 
00545       template<typename _Up, typename _Ep, typename = _Require<
00546                __safe_conversion_up<_Up, _Ep>,
00547                typename conditional<is_reference<_Dp>::value,
00548                                     is_same<_Ep, _Dp>,
00549                                     is_convertible<_Ep, _Dp>>::type>>
00550         unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
00551         : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
00552         { }
00553 
00554       /// Destructor, invokes the deleter if the stored pointer is not null.
00555       ~unique_ptr()
00556       {
00557         auto& __ptr = _M_t._M_ptr();
00558         if (__ptr != nullptr)
00559           get_deleter()(__ptr);
00560         __ptr = pointer();
00561       }
00562 
00563       // Assignment.
00564 
00565       /** @brief Move assignment operator.
00566        *
00567        * @param __u  The object to transfer ownership from.
00568        *
00569        * Invokes the deleter first if this object owns a pointer.
00570        */
00571       unique_ptr&
00572       operator=(unique_ptr&& __u) noexcept
00573       {
00574         reset(__u.release());
00575         get_deleter() = std::forward<deleter_type>(__u.get_deleter());
00576         return *this;
00577       }
00578 
00579       /** @brief Assignment from another type.
00580        *
00581        * @param __u  The object to transfer ownership from, which owns a
00582        *             convertible pointer to an array object.
00583        *
00584        * Invokes the deleter first if this object owns a pointer.
00585        */
00586       template<typename _Up, typename _Ep>
00587         typename
00588         enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
00589                          is_assignable<deleter_type&, _Ep&&>
00590                   >::value,
00591                   unique_ptr&>::type
00592         operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
00593         {
00594           reset(__u.release());
00595           get_deleter() = std::forward<_Ep>(__u.get_deleter());
00596           return *this;
00597         }
00598 
00599       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
00600       unique_ptr&
00601       operator=(nullptr_t) noexcept
00602       {
00603         reset();
00604         return *this;
00605       }
00606 
00607       // Observers.
00608 
00609       /// Access an element of owned array.
00610       typename std::add_lvalue_reference<element_type>::type
00611       operator[](size_t __i) const
00612       {
00613         __glibcxx_assert(get() != pointer());
00614         return get()[__i];
00615       }
00616 
00617       /// Return the stored pointer.
00618       pointer
00619       get() const noexcept
00620       { return _M_t._M_ptr(); }
00621 
00622       /// Return a reference to the stored deleter.
00623       deleter_type&
00624       get_deleter() noexcept
00625       { return _M_t._M_deleter(); }
00626 
00627       /// Return a reference to the stored deleter.
00628       const deleter_type&
00629       get_deleter() const noexcept
00630       { return _M_t._M_deleter(); }
00631 
00632       /// Return @c true if the stored pointer is not null.
00633       explicit operator bool() const noexcept
00634       { return get() == pointer() ? false : true; }
00635 
00636       // Modifiers.
00637 
00638       /// Release ownership of any stored pointer.
00639       pointer
00640       release() noexcept
00641       {
00642         pointer __p = get();
00643         _M_t._M_ptr() = pointer();
00644         return __p;
00645       }
00646 
00647       /** @brief Replace the stored pointer.
00648        *
00649        * @param __p  The new pointer to store.
00650        *
00651        * The deleter will be invoked if a pointer is already owned.
00652        */
00653       template <typename _Up,
00654                 typename = _Require<
00655                   __or_<is_same<_Up, pointer>,
00656                         __and_<is_same<pointer, element_type*>,
00657                                is_pointer<_Up>,
00658                                is_convertible<
00659                                  typename remove_pointer<_Up>::type(*)[],
00660                                  element_type(*)[]
00661                                >
00662                         >
00663                   >
00664                >>
00665       void
00666       reset(_Up __p) noexcept
00667       {
00668         pointer __ptr = __p;
00669         using std::swap;
00670         swap(_M_t._M_ptr(), __ptr);
00671         if (__ptr != nullptr)
00672           get_deleter()(__ptr);
00673       }
00674 
00675       void reset(nullptr_t = nullptr) noexcept
00676       {
00677         reset(pointer());
00678       }
00679 
00680       /// Exchange the pointer and deleter with another object.
00681       void
00682       swap(unique_ptr& __u) noexcept
00683       {
00684         static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
00685         _M_t.swap(__u._M_t);
00686       }
00687 
00688       // Disable copy from lvalue.
00689       unique_ptr(const unique_ptr&) = delete;
00690       unique_ptr& operator=(const unique_ptr&) = delete;
00691     };
00692 
00693   template<typename _Tp, typename _Dp>
00694     inline
00695 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
00696     // Constrained free swap overload, see p0185r1
00697     typename enable_if<__is_swappable<_Dp>::value>::type
00698 #else
00699     void
00700 #endif
00701     swap(unique_ptr<_Tp, _Dp>& __x,
00702          unique_ptr<_Tp, _Dp>& __y) noexcept
00703     { __x.swap(__y); }
00704 
00705 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
00706   template<typename _Tp, typename _Dp>
00707     typename enable_if<!__is_swappable<_Dp>::value>::type
00708     swap(unique_ptr<_Tp, _Dp>&,
00709          unique_ptr<_Tp, _Dp>&) = delete;
00710 #endif
00711 
00712   template<typename _Tp, typename _Dp,
00713            typename _Up, typename _Ep>
00714     _GLIBCXX_NODISCARD inline bool
00715     operator==(const unique_ptr<_Tp, _Dp>& __x,
00716                const unique_ptr<_Up, _Ep>& __y)
00717     { return __x.get() == __y.get(); }
00718 
00719   template<typename _Tp, typename _Dp>
00720     _GLIBCXX_NODISCARD inline bool
00721     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
00722     { return !__x; }
00723 
00724   template<typename _Tp, typename _Dp>
00725     _GLIBCXX_NODISCARD inline bool
00726     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
00727     { return !__x; }
00728 
00729   template<typename _Tp, typename _Dp,
00730            typename _Up, typename _Ep>
00731     _GLIBCXX_NODISCARD inline bool
00732     operator!=(const unique_ptr<_Tp, _Dp>& __x,
00733                const unique_ptr<_Up, _Ep>& __y)
00734     { return __x.get() != __y.get(); }
00735 
00736   template<typename _Tp, typename _Dp>
00737     _GLIBCXX_NODISCARD inline bool
00738     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
00739     { return (bool)__x; }
00740 
00741   template<typename _Tp, typename _Dp>
00742     _GLIBCXX_NODISCARD inline bool
00743     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
00744     { return (bool)__x; }
00745 
00746   template<typename _Tp, typename _Dp,
00747            typename _Up, typename _Ep>
00748     _GLIBCXX_NODISCARD inline bool
00749     operator<(const unique_ptr<_Tp, _Dp>& __x,
00750               const unique_ptr<_Up, _Ep>& __y)
00751     {
00752       typedef typename
00753         std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
00754                          typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
00755       return std::less<_CT>()(__x.get(), __y.get());
00756     }
00757 
00758   template<typename _Tp, typename _Dp>
00759     _GLIBCXX_NODISCARD inline bool
00760     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00761     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
00762                                                                  nullptr); }
00763 
00764   template<typename _Tp, typename _Dp>
00765     _GLIBCXX_NODISCARD inline bool
00766     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00767     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
00768                                                                  __x.get()); }
00769 
00770   template<typename _Tp, typename _Dp,
00771            typename _Up, typename _Ep>
00772     _GLIBCXX_NODISCARD inline bool
00773     operator<=(const unique_ptr<_Tp, _Dp>& __x,
00774                const unique_ptr<_Up, _Ep>& __y)
00775     { return !(__y < __x); }
00776 
00777   template<typename _Tp, typename _Dp>
00778     _GLIBCXX_NODISCARD inline bool
00779     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00780     { return !(nullptr < __x); }
00781 
00782   template<typename _Tp, typename _Dp>
00783     _GLIBCXX_NODISCARD inline bool
00784     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00785     { return !(__x < nullptr); }
00786 
00787   template<typename _Tp, typename _Dp,
00788            typename _Up, typename _Ep>
00789     _GLIBCXX_NODISCARD inline bool
00790     operator>(const unique_ptr<_Tp, _Dp>& __x,
00791               const unique_ptr<_Up, _Ep>& __y)
00792     { return (__y < __x); }
00793 
00794   template<typename _Tp, typename _Dp>
00795     _GLIBCXX_NODISCARD inline bool
00796     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00797     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
00798                                                                  __x.get()); }
00799 
00800   template<typename _Tp, typename _Dp>
00801     _GLIBCXX_NODISCARD inline bool
00802     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00803     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
00804                                                                  nullptr); }
00805 
00806   template<typename _Tp, typename _Dp,
00807            typename _Up, typename _Ep>
00808     _GLIBCXX_NODISCARD inline bool
00809     operator>=(const unique_ptr<_Tp, _Dp>& __x,
00810                const unique_ptr<_Up, _Ep>& __y)
00811     { return !(__x < __y); }
00812 
00813   template<typename _Tp, typename _Dp>
00814     _GLIBCXX_NODISCARD inline bool
00815     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
00816     { return !(__x < nullptr); }
00817 
00818   template<typename _Tp, typename _Dp>
00819     _GLIBCXX_NODISCARD inline bool
00820     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
00821     { return !(nullptr < __x); }
00822 
00823   /// std::hash specialization for unique_ptr.
00824   template<typename _Tp, typename _Dp>
00825     struct hash<unique_ptr<_Tp, _Dp>>
00826     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
00827     private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
00828     {
00829       size_t
00830       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
00831       {
00832         typedef unique_ptr<_Tp, _Dp> _UP;
00833         return std::hash<typename _UP::pointer>()(__u.get());
00834       }
00835     };
00836 
00837 #if __cplusplus > 201103L
00838 
00839 #define __cpp_lib_make_unique 201304
00840 
00841   template<typename _Tp>
00842     struct _MakeUniq
00843     { typedef unique_ptr<_Tp> __single_object; };
00844 
00845   template<typename _Tp>
00846     struct _MakeUniq<_Tp[]>
00847     { typedef unique_ptr<_Tp[]> __array; };
00848 
00849   template<typename _Tp, size_t _Bound>
00850     struct _MakeUniq<_Tp[_Bound]>
00851     { struct __invalid_type { }; };
00852 
00853   /// std::make_unique for single objects
00854   template<typename _Tp, typename... _Args>
00855     inline typename _MakeUniq<_Tp>::__single_object
00856     make_unique(_Args&&... __args)
00857     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
00858 
00859   /// std::make_unique for arrays of unknown bound
00860   template<typename _Tp>
00861     inline typename _MakeUniq<_Tp>::__array
00862     make_unique(size_t __num)
00863     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
00864 
00865   /// Disable std::make_unique for arrays of known bound
00866   template<typename _Tp, typename... _Args>
00867     inline typename _MakeUniq<_Tp>::__invalid_type
00868     make_unique(_Args&&...) = delete;
00869 #endif
00870 
00871   // @} group pointer_abstractions
00872 
00873 #if __cplusplus >= 201703L
00874   namespace __detail::__variant
00875   {
00876     template<typename> struct _Never_valueless_alt; // see <variant>
00877 
00878     // Provide the strong exception-safety guarantee when emplacing a
00879     // unique_ptr into a variant.
00880     template<typename _Tp, typename _Del>
00881       struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
00882       : std::true_type
00883       { };
00884   }  // namespace __detail::__variant
00885 #endif // C++17
00886 
00887 _GLIBCXX_END_NAMESPACE_VERSION
00888 } // namespace
00889 
00890 #endif /* _UNIQUE_PTR_H */