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