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 <__compare/compare_three_way.h> 14 #include <__compare/compare_three_way_result.h> 15 #include <__compare/three_way_comparable.h> 16 #include <__config> 17 #include <__functional/hash.h> 18 #include <__functional/operations.h> 19 #include <__memory/allocator_traits.h> // __pointer 20 #include <__memory/auto_ptr.h> 21 #include <__memory/compressed_pair.h> 22 #include <__type_traits/add_lvalue_reference.h> 23 #include <__type_traits/common_type.h> 24 #include <__type_traits/dependent_type.h> 25 #include <__type_traits/integral_constant.h> 26 #include <__type_traits/is_array.h> 27 #include <__type_traits/is_assignable.h> 28 #include <__type_traits/is_constructible.h> 29 #include <__type_traits/is_convertible.h> 30 #include <__type_traits/is_default_constructible.h> 31 #include <__type_traits/is_function.h> 32 #include <__type_traits/is_pointer.h> 33 #include <__type_traits/is_reference.h> 34 #include <__type_traits/is_same.h> 35 #include <__type_traits/is_swappable.h> 36 #include <__type_traits/is_void.h> 37 #include <__type_traits/remove_extent.h> 38 #include <__type_traits/type_identity.h> 39 #include <__utility/forward.h> 40 #include <__utility/move.h> 41 #include <cstddef> 42 43 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 44 # pragma GCC system_header 45 #endif 46 47 _LIBCPP_PUSH_MACROS 48 #include <__undef_macros> 49 50 _LIBCPP_BEGIN_NAMESPACE_STD 51 52 template <class _Tp> 53 struct _LIBCPP_TEMPLATE_VIS default_delete { 54 static_assert(!is_function<_Tp>::value, 55 "default_delete cannot be instantiated for function types"); 56 #ifndef _LIBCPP_CXX03_LANG 57 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; 58 #else 59 _LIBCPP_HIDE_FROM_ABI default_delete() {} 60 #endif 61 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0> 62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete( 63 const default_delete<_Up>&) _NOEXCEPT {} 64 65 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { 66 static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); 67 static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); 68 delete __ptr; 69 } 70 }; 71 72 template <class _Tp> 73 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { 74 private: 75 template <class _Up> 76 struct _EnableIfConvertible 77 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {}; 78 79 public: 80 #ifndef _LIBCPP_CXX03_LANG 81 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; 82 #else 83 _LIBCPP_HIDE_FROM_ABI default_delete() {} 84 #endif 85 86 template <class _Up> 87 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 88 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} 89 90 template <class _Up> 91 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type 92 operator()(_Up* __ptr) const _NOEXCEPT { 93 static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); 94 delete[] __ptr; 95 } 96 }; 97 98 template <class _Deleter> 99 struct __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 106 template <class _Deleter> 107 struct __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 113 template <class _Deleter> 114 struct __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 #else 123 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI 124 #endif 125 126 template <class _Tp, class _Dp = default_delete<_Tp> > 127 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { 128 public: 129 typedef _Tp element_type; 130 typedef _Dp deleter_type; 131 typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer; 132 133 static_assert(!is_rvalue_reference<deleter_type>::value, 134 "the specified deleter type cannot be an rvalue reference"); 135 136 private: 137 __compressed_pair<pointer, deleter_type> __ptr_; 138 139 struct __nat { int __for_bool_; }; 140 141 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; 142 143 template <bool _Dummy> 144 using _LValRefType _LIBCPP_NODEBUG = 145 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; 146 147 template <bool _Dummy> 148 using _GoodRValRefType _LIBCPP_NODEBUG = 149 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; 150 151 template <bool _Dummy> 152 using _BadRValRefType _LIBCPP_NODEBUG = 153 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; 154 155 template <bool _Dummy, class _Deleter = typename __dependent_type< 156 __type_identity<deleter_type>, _Dummy>::type> 157 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = 158 __enable_if_t<is_default_constructible<_Deleter>::value && 159 !is_pointer<_Deleter>::value>; 160 161 template <class _ArgType> 162 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = 163 __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; 164 165 template <class _UPtr, class _Up> 166 using _EnableIfMoveConvertible _LIBCPP_NODEBUG = __enable_if_t< 167 is_convertible<typename _UPtr::pointer, pointer>::value && 168 !is_array<_Up>::value 169 >; 170 171 template <class _UDel> 172 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = __enable_if_t< 173 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 174 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) 175 >; 176 177 template <class _UDel> 178 using _EnableIfDeleterAssignable = __enable_if_t< 179 is_assignable<_Dp&, _UDel&&>::value 180 >; 181 182 public: 183 template <bool _Dummy = true, 184 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 185 _LIBCPP_HIDE_FROM_ABI 186 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 187 188 template <bool _Dummy = true, 189 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 190 _LIBCPP_HIDE_FROM_ABI 191 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 192 193 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT 195 : __ptr_(__p, __value_init_tag()) {} 196 197 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > 198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT 199 : __ptr_(__p, __d) {} 200 201 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > 202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 203 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, std::move(__d)) { 204 static_assert(!is_reference<deleter_type>::value, 205 "rvalue deleter bound to reference"); 206 } 207 208 template <bool _Dummy = true, 209 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > > 210 _LIBCPP_HIDE_FROM_ABI 211 unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; 212 213 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 214 : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} 215 216 template <class _Up, 217 class _Ep, 218 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 219 class = _EnableIfDeleterConvertible<_Ep> > 220 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 221 : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} 222 223 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 224 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value && 225 is_same<_Dp, default_delete<_Tp> >::value, int> = 0> 226 _LIBCPP_HIDE_FROM_ABI 227 unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT 228 : __ptr_(__p.release(), __value_init_tag()) {} 229 #endif 230 231 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 232 reset(__u.release()); 233 __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); 234 return *this; 235 } 236 237 template <class _Up, 238 class _Ep, 239 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 240 class = _EnableIfDeleterAssignable<_Ep> > 241 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 242 reset(__u.release()); 243 __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); 244 return *this; 245 } 246 247 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 248 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value && 249 is_same<_Dp, default_delete<_Tp> >::value, int> = 0> 250 _LIBCPP_HIDE_FROM_ABI 251 unique_ptr& 252 operator=(auto_ptr<_Up> __p) { 253 reset(__p.release()); 254 return *this; 255 } 256 #endif 257 258 #ifdef _LIBCPP_CXX03_LANG 259 unique_ptr(unique_ptr const&) = delete; 260 unique_ptr& operator=(unique_ptr const&) = delete; 261 #endif 262 263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 264 265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 266 reset(); 267 return *this; 268 } 269 270 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const { 271 return *__ptr_.first(); 272 } 273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { 274 return __ptr_.first(); 275 } 276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { 278 return __ptr_.second(); 279 } 280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 281 return __ptr_.second(); 282 } 283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 284 return __ptr_.first() != nullptr; 285 } 286 287 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { 288 pointer __t = __ptr_.first(); 289 __ptr_.first() = pointer(); 290 return __t; 291 } 292 293 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT { 294 pointer __tmp = __ptr_.first(); 295 __ptr_.first() = __p; 296 if (__tmp) 297 __ptr_.second()(__tmp); 298 } 299 300 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { 301 __ptr_.swap(__u.__ptr_); 302 } 303 }; 304 305 306 template <class _Tp, class _Dp> 307 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { 308 public: 309 typedef _Tp element_type; 310 typedef _Dp deleter_type; 311 typedef typename __pointer<_Tp, deleter_type>::type pointer; 312 313 private: 314 __compressed_pair<pointer, deleter_type> __ptr_; 315 316 template <class _From> 317 struct _CheckArrayPointerConversion : is_same<_From, pointer> {}; 318 319 template <class _FromElem> 320 struct _CheckArrayPointerConversion<_FromElem*> 321 : integral_constant<bool, 322 is_same<_FromElem*, pointer>::value || 323 (is_same<pointer, element_type*>::value && 324 is_convertible<_FromElem(*)[], element_type(*)[]>::value) 325 > 326 {}; 327 328 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; 329 330 template <bool _Dummy> 331 using _LValRefType _LIBCPP_NODEBUG = 332 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; 333 334 template <bool _Dummy> 335 using _GoodRValRefType _LIBCPP_NODEBUG = 336 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; 337 338 template <bool _Dummy> 339 using _BadRValRefType _LIBCPP_NODEBUG = 340 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; 341 342 template <bool _Dummy, class _Deleter = typename __dependent_type< 343 __type_identity<deleter_type>, _Dummy>::type> 344 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = 345 __enable_if_t<is_default_constructible<_Deleter>::value && 346 !is_pointer<_Deleter>::value>; 347 348 template <class _ArgType> 349 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = 350 __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; 351 352 template <class _Pp> 353 using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< 354 _CheckArrayPointerConversion<_Pp>::value 355 >; 356 357 template <class _UPtr, class _Up, 358 class _ElemT = typename _UPtr::element_type> 359 using _EnableIfMoveConvertible _LIBCPP_NODEBUG = __enable_if_t< 360 is_array<_Up>::value && 361 is_same<pointer, element_type*>::value && 362 is_same<typename _UPtr::pointer, _ElemT*>::value && 363 is_convertible<_ElemT(*)[], element_type(*)[]>::value 364 >; 365 366 template <class _UDel> 367 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = __enable_if_t< 368 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 369 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) 370 >; 371 372 template <class _UDel> 373 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< 374 is_assignable<_Dp&, _UDel&&>::value 375 >; 376 377 public: 378 template <bool _Dummy = true, 379 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 380 _LIBCPP_HIDE_FROM_ABI 381 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 382 383 template <bool _Dummy = true, 384 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 385 _LIBCPP_HIDE_FROM_ABI 386 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 387 388 template <class _Pp, 389 bool _Dummy = true, 390 class = _EnableIfDeleterDefaultConstructible<_Dummy>, 391 class = _EnableIfPointerConvertible<_Pp> > 392 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT 393 : __ptr_(__p, __value_init_tag()) {} 394 395 template <class _Pp, 396 bool _Dummy = true, 397 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >, 398 class = _EnableIfPointerConvertible<_Pp> > 399 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT 400 : __ptr_(__p, __d) {} 401 402 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > 403 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT 404 : __ptr_(nullptr, __d) {} 405 406 template <class _Pp, 407 bool _Dummy = true, 408 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >, 409 class = _EnableIfPointerConvertible<_Pp> > 410 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 411 : __ptr_(__p, std::move(__d)) { 412 static_assert(!is_reference<deleter_type>::value, 413 "rvalue deleter bound to reference"); 414 } 415 416 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > 417 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 418 : __ptr_(nullptr, std::move(__d)) { 419 static_assert(!is_reference<deleter_type>::value, 420 "rvalue deleter bound to reference"); 421 } 422 423 template <class _Pp, bool _Dummy = true, 424 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >, 425 class = _EnableIfPointerConvertible<_Pp> > 426 _LIBCPP_HIDE_FROM_ABI 427 unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; 428 429 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 430 : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} 431 432 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 433 reset(__u.release()); 434 __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); 435 return *this; 436 } 437 438 template <class _Up, 439 class _Ep, 440 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 441 class = _EnableIfDeleterConvertible<_Ep> > 442 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 443 : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} 444 445 template <class _Up, 446 class _Ep, 447 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 448 class = _EnableIfDeleterAssignable<_Ep> > 449 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 450 reset(__u.release()); 451 __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); 452 return *this; 453 } 454 455 #ifdef _LIBCPP_CXX03_LANG 456 unique_ptr(unique_ptr const&) = delete; 457 unique_ptr& operator=(unique_ptr const&) = delete; 458 #endif 459 public: 460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 461 462 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 463 reset(); 464 return *this; 465 } 466 467 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> 468 operator[](size_t __i) const { 469 return __ptr_.first()[__i]; 470 } 471 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 472 473 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { 474 return __ptr_.second(); 475 } 476 477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 478 return __ptr_.second(); 479 } 480 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 481 return __ptr_.first() != nullptr; 482 } 483 484 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { 485 pointer __t = __ptr_.first(); 486 __ptr_.first() = pointer(); 487 return __t; 488 } 489 490 template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0> 491 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 492 void reset(_Pp __p) _NOEXCEPT { 493 pointer __tmp = __ptr_.first(); 494 __ptr_.first() = __p; 495 if (__tmp) 496 __ptr_.second()(__tmp); 497 } 498 499 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { 500 pointer __tmp = __ptr_.first(); 501 __ptr_.first() = nullptr; 502 if (__tmp) 503 __ptr_.second()(__tmp); 504 } 505 506 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { 507 __ptr_.swap(__u.__ptr_); 508 } 509 }; 510 511 template <class _Tp, class _Dp, __enable_if_t<__is_swappable<_Dp>::value, int> = 0> 512 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 513 void 514 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { 515 __x.swap(__y); 516 } 517 518 template <class _T1, class _D1, class _T2, class _D2> 519 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 520 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 521 return __x.get() == __y.get(); 522 } 523 524 #if _LIBCPP_STD_VER <= 17 525 template <class _T1, class _D1, class _T2, class _D2> 526 inline _LIBCPP_HIDE_FROM_ABI 527 bool 528 operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} 529 #endif 530 531 template <class _T1, class _D1, class _T2, class _D2> 532 inline _LIBCPP_HIDE_FROM_ABI 533 bool 534 operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) 535 { 536 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 537 typedef typename unique_ptr<_T2, _D2>::pointer _P2; 538 typedef typename common_type<_P1, _P2>::type _Vp; 539 return less<_Vp>()(__x.get(), __y.get()); 540 } 541 542 template <class _T1, class _D1, class _T2, class _D2> 543 inline _LIBCPP_HIDE_FROM_ABI 544 bool 545 operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} 546 547 template <class _T1, class _D1, class _T2, class _D2> 548 inline _LIBCPP_HIDE_FROM_ABI 549 bool 550 operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} 551 552 template <class _T1, class _D1, class _T2, class _D2> 553 inline _LIBCPP_HIDE_FROM_ABI 554 bool 555 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} 556 557 558 #if _LIBCPP_STD_VER >= 20 559 template <class _T1, class _D1, class _T2, class _D2> 560 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, 561 typename unique_ptr<_T2, _D2>::pointer> 562 _LIBCPP_HIDE_FROM_ABI 563 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, 564 typename unique_ptr<_T2, _D2>::pointer> 565 operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 566 return compare_three_way()(__x.get(), __y.get()); 567 } 568 #endif 569 570 template <class _T1, class _D1> 571 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 572 operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 573 return !__x; 574 } 575 576 #if _LIBCPP_STD_VER <= 17 577 template <class _T1, class _D1> 578 inline _LIBCPP_HIDE_FROM_ABI 579 bool 580 operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 581 { 582 return !__x; 583 } 584 585 template <class _T1, class _D1> 586 inline _LIBCPP_HIDE_FROM_ABI 587 bool 588 operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT 589 { 590 return static_cast<bool>(__x); 591 } 592 593 template <class _T1, class _D1> 594 inline _LIBCPP_HIDE_FROM_ABI 595 bool 596 operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 597 { 598 return static_cast<bool>(__x); 599 } 600 #endif // _LIBCPP_STD_VER <= 17 601 602 template <class _T1, class _D1> 603 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 604 operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 605 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 606 return less<_P1>()(__x.get(), nullptr); 607 } 608 609 template <class _T1, class _D1> 610 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 611 operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 612 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 613 return less<_P1>()(nullptr, __x.get()); 614 } 615 616 template <class _T1, class _D1> 617 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 618 operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 619 return nullptr < __x; 620 } 621 622 template <class _T1, class _D1> 623 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 624 operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 625 return __x < nullptr; 626 } 627 628 template <class _T1, class _D1> 629 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 630 operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 631 return !(nullptr < __x); 632 } 633 634 template <class _T1, class _D1> 635 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 636 operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 637 return !(__x < nullptr); 638 } 639 640 template <class _T1, class _D1> 641 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 642 operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 643 return !(__x < nullptr); 644 } 645 646 template <class _T1, class _D1> 647 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 648 operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 649 return !(nullptr < __x); 650 } 651 652 #if _LIBCPP_STD_VER >= 20 653 template <class _T1, class _D1> 654 requires three_way_comparable< 655 typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 656 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> 657 operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 658 return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr)); 659 } 660 #endif 661 662 #if _LIBCPP_STD_VER >= 14 663 664 template<class _Tp> 665 struct __unique_if 666 { 667 typedef unique_ptr<_Tp> __unique_single; 668 }; 669 670 template<class _Tp> 671 struct __unique_if<_Tp[]> 672 { 673 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; 674 }; 675 676 template<class _Tp, size_t _Np> 677 struct __unique_if<_Tp[_Np]> 678 { 679 typedef void __unique_array_known_bound; 680 }; 681 682 template <class _Tp, class... _Args> 683 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 684 make_unique(_Args&&... __args) { 685 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); 686 } 687 688 template <class _Tp> 689 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 690 make_unique(size_t __n) { 691 typedef __remove_extent_t<_Tp> _Up; 692 return unique_ptr<_Tp>(new _Up[__n]()); 693 } 694 695 template<class _Tp, class... _Args> 696 typename __unique_if<_Tp>::__unique_array_known_bound 697 make_unique(_Args&&...) = delete; 698 699 #endif // _LIBCPP_STD_VER >= 14 700 701 #if _LIBCPP_STD_VER >= 20 702 703 template <class _Tp> 704 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 705 make_unique_for_overwrite() { 706 return unique_ptr<_Tp>(new _Tp); 707 } 708 709 template <class _Tp> 710 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 711 make_unique_for_overwrite(size_t __n) { 712 return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); 713 } 714 715 template<class _Tp, class... _Args> 716 typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; 717 718 #endif // _LIBCPP_STD_VER >= 20 719 720 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 721 722 template <class _Tp, class _Dp> 723 #ifdef _LIBCPP_CXX03_LANG 724 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > 725 #else 726 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< 727 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > 728 #endif 729 { 730 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 731 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; 732 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 733 #endif 734 735 _LIBCPP_HIDE_FROM_ABI 736 size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const 737 { 738 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; 739 return hash<pointer>()(__ptr.get()); 740 } 741 }; 742 743 _LIBCPP_END_NAMESPACE_STD 744 745 _LIBCPP_POP_MACROS 746 747 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H 748