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