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