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