814 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H11#define _LIBCPP___MEMORY_UNIQUE_PTR_H12 13#include <__assert>14#include <__compare/compare_three_way.h>15#include <__compare/compare_three_way_result.h>16#include <__compare/three_way_comparable.h>17#include <__config>18#include <__cstddef/nullptr_t.h>19#include <__cstddef/size_t.h>20#include <__functional/hash.h>21#include <__functional/operations.h>22#include <__memory/allocator_traits.h> // __pointer23#include <__memory/array_cookie.h>24#include <__memory/auto_ptr.h>25#include <__memory/compressed_pair.h>26#include <__memory/pointer_traits.h>27#include <__type_traits/add_reference.h>28#include <__type_traits/common_type.h>29#include <__type_traits/conditional.h>30#include <__type_traits/dependent_type.h>31#include <__type_traits/enable_if.h>32#include <__type_traits/integral_constant.h>33#include <__type_traits/is_array.h>34#include <__type_traits/is_assignable.h>35#include <__type_traits/is_constant_evaluated.h>36#include <__type_traits/is_constructible.h>37#include <__type_traits/is_convertible.h>38#include <__type_traits/is_function.h>39#include <__type_traits/is_pointer.h>40#include <__type_traits/is_reference.h>41#include <__type_traits/is_same.h>42#include <__type_traits/is_swappable.h>43#include <__type_traits/is_trivially_relocatable.h>44#include <__type_traits/is_void.h>45#include <__type_traits/remove_extent.h>46#include <__type_traits/type_identity.h>47#include <__utility/declval.h>48#include <__utility/forward.h>49#include <__utility/move.h>50#include <__utility/private_constructor_tag.h>51#include <cstdint>52 53#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)54# pragma GCC system_header55#endif56 57_LIBCPP_PUSH_MACROS58#include <__undef_macros>59 60_LIBCPP_BEGIN_NAMESPACE_STD61 62template <class _Tp>63struct default_delete {64 static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types");65 66 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;67 68 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0>69 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up>&) _NOEXCEPT {}70 71 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT {72 static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");73 static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");74 delete __ptr;75 }76};77 78template <class _Tp>79struct default_delete<_Tp[]> {80 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;81 82 template <class _Up, __enable_if_t<is_convertible<_Up (*)[], _Tp (*)[]>::value, int> = 0>83 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up[]>&) _NOEXCEPT {}84 85 template <class _Up, __enable_if_t<is_convertible<_Up (*)[], _Tp (*)[]>::value, int> = 0>86 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Up* __ptr) const _NOEXCEPT {87 static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");88 delete[] __ptr;89 }90};91 92template <class _Deleter>93inline const bool __is_default_deleter_v = false;94 95template <class _Tp>96inline const bool __is_default_deleter_v<default_delete<_Tp> > = true;97 98template <class _Deleter>99struct __unique_ptr_deleter_sfinae {100 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");101 typedef const _Deleter& __lval_ref_type;102 typedef _Deleter&& __good_rval_ref_type;103 typedef true_type __enable_rval_overload;104};105 106template <class _Deleter>107struct __unique_ptr_deleter_sfinae<_Deleter const&> {108 typedef const _Deleter& __lval_ref_type;109 typedef const _Deleter&& __bad_rval_ref_type;110 typedef false_type __enable_rval_overload;111};112 113template <class _Deleter>114struct __unique_ptr_deleter_sfinae<_Deleter&> {115 typedef _Deleter& __lval_ref_type;116 typedef _Deleter&& __bad_rval_ref_type;117 typedef false_type __enable_rval_overload;118};119 120#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)121# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))122#else123# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI124#endif125 126template <class _Tp, class _Dp = default_delete<_Tp> >127class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {128public:129 typedef _Tp element_type;130 typedef _Dp deleter_type;131 using pointer _LIBCPP_NODEBUG = __pointer<_Tp, deleter_type>;132 133 static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");134 135 // A unique_ptr contains the following members which may be trivially relocatable:136 // - pointer : this may be trivially relocatable, so it's checked137 // - deleter_type: this may be trivially relocatable, so it's checked138 //139 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no140 // references to itself. This means that the entire structure is trivially relocatable if its members are.141 using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<142 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,143 unique_ptr,144 void>;145 146private:147 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);148 149 using _DeleterSFINAE _LIBCPP_NODEBUG = __unique_ptr_deleter_sfinae<_Dp>;150 151 template <bool _Dummy>152 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;153 154 template <bool _Dummy>155 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;156 157 template <bool _Dummy>158 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;159 160 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>161 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =162 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;163 164 template <class _ArgType>165 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;166 167 template <class _UPtr, class _Up>168 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =169 __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >;170 171 template <class _UDel>172 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =173 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||174 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;175 176 template <class _UDel>177 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;178 179public:180 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}182 183 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >184 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}185 186 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT188 : __ptr_(__p),189 __deleter_() {}190 191 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT193 : __ptr_(__p),194 __deleter_(__d) {}195 196 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >197 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT198 : __ptr_(__p),199 __deleter_(std::move(__d)) {200 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");201 }202 203 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >204 _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;205 206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT207 : __ptr_(__u.release()),208 __deleter_(std::forward<deleter_type>(__u.get_deleter())) {}209 210 template <class _Up,211 class _Ep,212 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,213 class = _EnableIfDeleterConvertible<_Ep> >214 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT215 : __ptr_(__u.release()),216 __deleter_(std::forward<_Ep>(__u.get_deleter())) {}217 218#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)219 template <class _Up,220 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>221 _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release()), __deleter_() {}222#endif223 224 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {225 reset(__u.release());226 __deleter_ = std::forward<deleter_type>(__u.get_deleter());227 return *this;228 }229 230 template <class _Up,231 class _Ep,232 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,233 class = _EnableIfDeleterAssignable<_Ep> >234 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {235 reset(__u.release());236 __deleter_ = std::forward<_Ep>(__u.get_deleter());237 return *this;238 }239 240#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)241 template <class _Up,242 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>243 _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) {244 reset(__p.release());245 return *this;246 }247#endif248 249#ifdef _LIBCPP_CXX03_LANG250 unique_ptr(unique_ptr const&) = delete;251 unique_ptr& operator=(unique_ptr const&) = delete;252#endif253 254 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }255 256 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {257 reset();258 return *this;259 }260 261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const262 _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {263 return *__ptr_;264 }265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }266 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }267 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {268 return __deleter_;269 }270 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type&271 get_deleter() const _NOEXCEPT {272 return __deleter_;273 }274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {275 return __ptr_ != nullptr;276 }277 278 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {279 pointer __t = __ptr_;280 __ptr_ = pointer();281 return __t;282 }283 284 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {285 pointer __tmp = __ptr_;286 __ptr_ = __p;287 if (__tmp)288 __deleter_(__tmp);289 }290 291 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {292 using std::swap;293 swap(__ptr_, __u.__ptr_);294 swap(__deleter_, __u.__deleter_);295 }296};297 298// Bounds checking in unique_ptr<T[]>299// ==================================300//301// We provide some helper classes that allow bounds checking when accessing a unique_ptr<T[]>.302// There are a few cases where bounds checking can be implemented:303//304// 1. When an array cookie exists at the beginning of the array allocation, we are305// able to reuse that cookie to extract the size of the array and perform bounds checking.306// An array cookie is a size inserted at the beginning of the allocation by the compiler.307// That size is inserted implicitly when doing `new T[n]` in some cases (as of writing this308// exactly when the array elements are not trivially destructible), and its main purpose is309// to allow the runtime to destroy the `n` array elements when doing `delete[] array`.310// When we are able to use array cookies, we reuse information already available in the311// current runtime, so bounds checking does not require changing libc++'s ABI.312//313// However, note that we cannot assume the presence of an array cookie when a custom deleter314// is used, because the unique_ptr could have been created from an allocation that wasn't315// obtained via `new T[n]` (since it may not be deleted with `delete[] arr`).316//317// 2. When the "bounded unique_ptr" ABI configuration (controlled by `_LIBCPP_ABI_BOUNDED_UNIQUE_PTR`)318// is enabled, we store the size of the allocation (when it is known) so we can check it when319// indexing into the `unique_ptr`. That changes the layout of `std::unique_ptr<T[]>`, which is320// an ABI break from the default configuration.321//322// Note that even under this ABI configuration, we can't always know the size of the unique_ptr.323// Indeed, the size of the allocation can only be known when the unique_ptr is created via324// make_unique or a similar API. For example, it can't be known when constructed from an arbitrary325// pointer, in which case we are not able to check the bounds on access:326//327// unique_ptr<T[], MyDeleter> ptr(new T[3]);328//329// When we don't know the size of the allocation via the API used to create the unique_ptr, we330// try to fall back to using an array cookie when available.331//332// Finally, note that when this ABI configuration is enabled, we have no choice but to always333// make space for the size to be stored in the unique_ptr. Indeed, while we might want to avoid334// storing the size when an array cookie is available, knowing whether an array cookie is available335// requires the type stored in the unique_ptr to be complete, while unique_ptr can normally336// accommodate incomplete types.337//338// (1) Implementation where we rely on the array cookie to know the size of the allocation, if339// an array cookie exists.340struct __unique_ptr_array_bounds_stateless {341 __unique_ptr_array_bounds_stateless() = default;342 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stateless(size_t) {}343 344 template <class _Deleter,345 class _Tp,346 __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>347 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {348 // In constant expressions, we can't check the array cookie so we just pretend that the index349 // is in-bounds. The compiler catches invalid accesses anyway.350 if (__libcpp_is_constant_evaluated())351 return true;352 size_t __cookie = std::__get_array_cookie(__ptr);353 return __index < __cookie;354 }355 356 template <class _Deleter,357 class _Tp,358 __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t) const {360 return true; // If we don't have an array cookie, we assume the access is in-bounds361 }362};363 364// (2) Implementation where we store the size in the class whenever we have it.365//366// Semantically, we'd need to store the size as an optional<size_t>. However, since that367// is really heavy weight, we instead store a size_t and use SIZE_MAX as a magic value368// meaning that we don't know the size.369struct __unique_ptr_array_bounds_stored {370 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __unique_ptr_array_bounds_stored() : __size_(SIZE_MAX) {}371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stored(size_t __size) : __size_(__size) {}372 373 // Use the array cookie if there's one374 template <class _Deleter,375 class _Tp,376 __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>377 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {378 if (__libcpp_is_constant_evaluated())379 return true;380 size_t __cookie = std::__get_array_cookie(__ptr);381 return __index < __cookie;382 }383 384 // Otherwise, fall back on the stored size (if any)385 template <class _Deleter,386 class _Tp,387 __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>388 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t __index) const {389 return __index < __size_;390 }391 392private:393 size_t __size_;394};395 396template <class _Tp, class _Dp>397class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {398public:399 typedef _Tp element_type;400 typedef _Dp deleter_type;401 using pointer = __pointer<_Tp, deleter_type>;402 403 // A unique_ptr contains the following members which may be trivially relocatable:404 // - pointer: this may be trivially relocatable, so it's checked405 // - deleter_type: this may be trivially relocatable, so it's checked406 // - (optionally) size: this is trivially relocatable407 //408 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no409 // references to itself. This means that the entire structure is trivially relocatable if its members are.410 using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<411 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,412 unique_ptr,413 void>;414 415private:416 template <class _Up, class _OtherDeleter>417 friend class unique_ptr;418 419 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);420#ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR421 using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stored;422#else423 using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stateless;424#endif425 _LIBCPP_NO_UNIQUE_ADDRESS _BoundsChecker __checker_;426 427 template <class _From>428 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};429 430 template <class _FromElem>431 struct _CheckArrayPointerConversion<_FromElem*>432 : integral_constant<bool,433 is_same<_FromElem*, pointer>::value ||434 (is_same<pointer, element_type*>::value &&435 is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {};436 437 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;438 439 template <bool _Dummy>440 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;441 442 template <bool _Dummy>443 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;444 445 template <bool _Dummy>446 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;447 448 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>449 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =450 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;451 452 template <class _ArgType>453 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;454 455 template <class _Pp>456 using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;457 458 template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type>459 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =460 __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value &&461 is_same<typename _UPtr::pointer, _ElemT*>::value &&462 is_convertible<_ElemT (*)[], element_type (*)[]>::value >;463 464 template <class _UDel>465 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =466 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||467 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;468 469 template <class _UDel>470 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;471 472public:473 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >474 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}475 476 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}478 479 template <class _Pp,480 bool _Dummy = true,481 class = _EnableIfDeleterDefaultConstructible<_Dummy>,482 class = _EnableIfPointerConvertible<_Pp> >483 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __ptr) _NOEXCEPT484 : __ptr_(__ptr),485 __deleter_() {}486 487 // Private constructor used by make_unique & friends to pass the size that was allocated488 template <class _Tag, class _Ptr, __enable_if_t<is_same<_Tag, __private_constructor_tag>::value, int> = 0>489 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Tag, _Ptr __ptr, size_t __size) _NOEXCEPT490 : __ptr_(__ptr),491 __checker_(__size) {}492 493 template <class _Pp,494 bool _Dummy = true,495 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,496 class = _EnableIfPointerConvertible<_Pp> >497 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __ptr, _LValRefType<_Dummy> __deleter) _NOEXCEPT498 : __ptr_(__ptr),499 __deleter_(__deleter) {}500 501 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >502 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __deleter) _NOEXCEPT503 : __ptr_(nullptr),504 __deleter_(__deleter) {}505 506 template <class _Pp,507 bool _Dummy = true,508 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,509 class = _EnableIfPointerConvertible<_Pp> >510 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23511 unique_ptr(_Pp __ptr, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT512 : __ptr_(__ptr),513 __deleter_(std::move(__deleter)) {514 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");515 }516 517 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >518 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23519 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT520 : __ptr_(nullptr),521 __deleter_(std::move(__deleter)) {522 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");523 }524 525 template <class _Pp,526 bool _Dummy = true,527 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,528 class = _EnableIfPointerConvertible<_Pp> >529 _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __ptr, _BadRValRefType<_Dummy> __deleter) = delete;530 531 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT532 : __ptr_(__u.release()),533 __deleter_(std::forward<deleter_type>(__u.get_deleter())),534 __checker_(std::move(__u.__checker_)) {}535 536 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {537 reset(__u.release());538 __deleter_ = std::forward<deleter_type>(__u.get_deleter());539 __checker_ = std::move(__u.__checker_);540 return *this;541 }542 543 template <class _Up,544 class _Ep,545 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,546 class = _EnableIfDeleterConvertible<_Ep> >547 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT548 : __ptr_(__u.release()),549 __deleter_(std::forward<_Ep>(__u.get_deleter())),550 __checker_(std::move(__u.__checker_)) {}551 552 template <class _Up,553 class _Ep,554 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,555 class = _EnableIfDeleterAssignable<_Ep> >556 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {557 reset(__u.release());558 __deleter_ = std::forward<_Ep>(__u.get_deleter());559 __checker_ = std::move(__u.__checker_);560 return *this;561 }562 563#ifdef _LIBCPP_CXX03_LANG564 unique_ptr(unique_ptr const&) = delete;565 unique_ptr& operator=(unique_ptr const&) = delete;566#endif567 568public:569 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }570 571 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {572 reset();573 return *this;574 }575 576 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const {577 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__checker_.__in_bounds<deleter_type>(std::__to_address(__ptr_), __i),578 "unique_ptr<T[]>::operator[](index): index out of range");579 return __ptr_[__i];580 }581 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }582 583 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }584 585 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {586 return __deleter_;587 }588 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {589 return __ptr_ != nullptr;590 }591 592 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {593 pointer __t = __ptr_;594 __ptr_ = pointer();595 // The deleter and the optional bounds-checker are left unchanged. The bounds-checker596 // will be reinitialized appropriately when/if the unique_ptr gets assigned-to or reset.597 return __t;598 }599 600 template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0>601 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(_Pp __ptr) _NOEXCEPT {602 pointer __tmp = __ptr_;603 __ptr_ = __ptr;604 __checker_ = _BoundsChecker();605 if (__tmp)606 __deleter_(__tmp);607 }608 609 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT {610 pointer __tmp = __ptr_;611 __ptr_ = nullptr;612 __checker_ = _BoundsChecker();613 if (__tmp)614 __deleter_(__tmp);615 }616 617 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {618 using std::swap;619 swap(__ptr_, __u.__ptr_);620 swap(__deleter_, __u.__deleter_);621 swap(__checker_, __u.__checker_);622 }623};624 625template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0>626inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void627swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {628 __x.swap(__y);629}630 631template <class _T1, class _D1, class _T2, class _D2>632inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool633operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {634 return __x.get() == __y.get();635}636 637#if _LIBCPP_STD_VER <= 17638template <class _T1, class _D1, class _T2, class _D2>639inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {640 return !(__x == __y);641}642#endif643 644template <class _T1, class _D1, class _T2, class _D2>645inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {646 typedef typename unique_ptr<_T1, _D1>::pointer _P1;647 typedef typename unique_ptr<_T2, _D2>::pointer _P2;648 typedef typename common_type<_P1, _P2>::type _Vp;649 return less<_Vp>()(__x.get(), __y.get());650}651 652template <class _T1, class _D1, class _T2, class _D2>653inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {654 return __y < __x;655}656 657template <class _T1, class _D1, class _T2, class _D2>658inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {659 return !(__y < __x);660}661 662template <class _T1, class _D1, class _T2, class _D2>663inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {664 return !(__x < __y);665}666 667#if _LIBCPP_STD_VER >= 20668template <class _T1, class _D1, class _T2, class _D2>669 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>670_LIBCPP_HIDE_FROM_ABI671compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>672operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {673 return compare_three_way()(__x.get(), __y.get());674}675#endif676 677template <class _T1, class _D1>678inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool679operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {680 return !__x;681}682 683#if _LIBCPP_STD_VER <= 17684template <class _T1, class _D1>685inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {686 return !__x;687}688 689template <class _T1, class _D1>690inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {691 return static_cast<bool>(__x);692}693 694template <class _T1, class _D1>695inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {696 return static_cast<bool>(__x);697}698#endif // _LIBCPP_STD_VER <= 17699 700template <class _T1, class _D1>701inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) {702 typedef typename unique_ptr<_T1, _D1>::pointer _P1;703 return less<_P1>()(__x.get(), nullptr);704}705 706template <class _T1, class _D1>707inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) {708 typedef typename unique_ptr<_T1, _D1>::pointer _P1;709 return less<_P1>()(nullptr, __x.get());710}711 712template <class _T1, class _D1>713inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {714 return nullptr < __x;715}716 717template <class _T1, class _D1>718inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {719 return __x < nullptr;720}721 722template <class _T1, class _D1>723inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {724 return !(nullptr < __x);725}726 727template <class _T1, class _D1>728inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {729 return !(__x < nullptr);730}731 732template <class _T1, class _D1>733inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {734 return !(__x < nullptr);735}736 737template <class _T1, class _D1>738inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {739 return !(nullptr < __x);740}741 742#if _LIBCPP_STD_VER >= 20743template <class _T1, class _D1>744 requires three_way_comparable< typename unique_ptr<_T1, _D1>::pointer>745_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>746operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {747 return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr));748}749#endif750 751#if _LIBCPP_STD_VER >= 14752 753template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>754[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI755_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {756 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));757}758 759template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>760[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {761 typedef __remove_extent_t<_Tp> _Up;762 return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);763}764 765template <class _Tp, class... _Args, enable_if_t<__is_bounded_array_v<_Tp>, int> = 0>766void make_unique(_Args&&...) = delete;767 768#endif // _LIBCPP_STD_VER >= 14769 770#if _LIBCPP_STD_VER >= 20771 772template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>773[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {774 return unique_ptr<_Tp>(new _Tp);775}776 777template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>778[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp>779make_unique_for_overwrite(size_t __n) {780 return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);781}782 783template <class _Tp, class... _Args, enable_if_t<is_bounded_array_v<_Tp>, int> = 0>784void make_unique_for_overwrite(_Args&&...) = delete;785 786#endif // _LIBCPP_STD_VER >= 20787 788template <class _Tp>789struct hash;790 791template <class _Tp, class _Dp>792#ifdef _LIBCPP_CXX03_LANG793struct hash<unique_ptr<_Tp, _Dp> >794#else795struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >796#endif797{798#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)799 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;800 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;801#endif802 803 _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {804 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;805 return hash<pointer>()(__ptr.get());806 }807};808 809_LIBCPP_END_NAMESPACE_STD810 811_LIBCPP_POP_MACROS812 813#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H814