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