brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.7 KiB · b5f4693 Raw
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