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