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_BEGIN_NAMESPACE_STD 48 49 template <class _Tp> 50 struct _LIBCPP_TEMPLATE_VIS default_delete { 51 static_assert(!is_function<_Tp>::value, 52 "default_delete cannot be instantiated for function types"); 53 #ifndef _LIBCPP_CXX03_LANG 54 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default; 55 #else 56 _LIBCPP_INLINE_VISIBILITY default_delete() {} 57 #endif 58 template <class _Up> 59 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete( 60 const default_delete<_Up>&, typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {} 61 62 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { 63 static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); 64 static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); 65 delete __ptr; 66 } 67 }; 68 69 template <class _Tp> 70 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { 71 private: 72 template <class _Up> 73 struct _EnableIfConvertible 74 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {}; 75 76 public: 77 #ifndef _LIBCPP_CXX03_LANG 78 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default; 79 #else 80 _LIBCPP_INLINE_VISIBILITY default_delete() {} 81 #endif 82 83 template <class _Up> 84 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 85 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} 86 87 template <class _Up> 88 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type 89 operator()(_Up* __ptr) const _NOEXCEPT { 90 static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); 91 delete[] __ptr; 92 } 93 }; 94 95 template <class _Deleter> 96 struct __unique_ptr_deleter_sfinae { 97 static_assert(!is_reference<_Deleter>::value, "incorrect specialization"); 98 typedef const _Deleter& __lval_ref_type; 99 typedef _Deleter&& __good_rval_ref_type; 100 typedef true_type __enable_rval_overload; 101 }; 102 103 template <class _Deleter> 104 struct __unique_ptr_deleter_sfinae<_Deleter const&> { 105 typedef const _Deleter& __lval_ref_type; 106 typedef const _Deleter&& __bad_rval_ref_type; 107 typedef false_type __enable_rval_overload; 108 }; 109 110 template <class _Deleter> 111 struct __unique_ptr_deleter_sfinae<_Deleter&> { 112 typedef _Deleter& __lval_ref_type; 113 typedef _Deleter&& __bad_rval_ref_type; 114 typedef false_type __enable_rval_overload; 115 }; 116 117 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI) 118 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) 119 #else 120 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI 121 #endif 122 123 template <class _Tp, class _Dp = default_delete<_Tp> > 124 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { 125 public: 126 typedef _Tp element_type; 127 typedef _Dp deleter_type; 128 typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer; 129 130 static_assert(!is_rvalue_reference<deleter_type>::value, 131 "the specified deleter type cannot be an rvalue reference"); 132 133 private: 134 __compressed_pair<pointer, deleter_type> __ptr_; 135 136 struct __nat { int __for_bool_; }; 137 138 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; 139 140 template <bool _Dummy> 141 using _LValRefType _LIBCPP_NODEBUG = 142 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; 143 144 template <bool _Dummy> 145 using _GoodRValRefType _LIBCPP_NODEBUG = 146 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; 147 148 template <bool _Dummy> 149 using _BadRValRefType _LIBCPP_NODEBUG = 150 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; 151 152 template <bool _Dummy, class _Deleter = typename __dependent_type< 153 __type_identity<deleter_type>, _Dummy>::type> 154 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = 155 typename enable_if<is_default_constructible<_Deleter>::value && 156 !is_pointer<_Deleter>::value>::type; 157 158 template <class _ArgType> 159 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = 160 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type; 161 162 template <class _UPtr, class _Up> 163 using _EnableIfMoveConvertible _LIBCPP_NODEBUG = typename enable_if< 164 is_convertible<typename _UPtr::pointer, pointer>::value && 165 !is_array<_Up>::value 166 >::type; 167 168 template <class _UDel> 169 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = typename enable_if< 170 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 171 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) 172 >::type; 173 174 template <class _UDel> 175 using _EnableIfDeleterAssignable = typename enable_if< 176 is_assignable<_Dp&, _UDel&&>::value 177 >::type; 178 179 public: 180 template <bool _Dummy = true, 181 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 182 _LIBCPP_INLINE_VISIBILITY 183 _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 184 185 template <bool _Dummy = true, 186 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 187 _LIBCPP_INLINE_VISIBILITY 188 _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 189 190 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 191 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT 192 : __ptr_(__p, __value_init_tag()) {} 193 194 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > 195 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT 196 : __ptr_(__p, __d) {} 197 198 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > 199 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 200 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { 201 static_assert(!is_reference<deleter_type>::value, 202 "rvalue deleter bound to reference"); 203 } 204 205 template <bool _Dummy = true, 206 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > > 207 _LIBCPP_INLINE_VISIBILITY 208 unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; 209 210 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 211 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {} 212 213 template <class _Up, 214 class _Ep, 215 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 216 class = _EnableIfDeleterConvertible<_Ep> > 217 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 218 : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {} 219 220 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 221 template <class _Up> 222 _LIBCPP_INLINE_VISIBILITY 223 unique_ptr(auto_ptr<_Up>&& __p, 224 typename enable_if<is_convertible<_Up*, _Tp*>::value && 225 is_same<_Dp, default_delete<_Tp> >::value, 226 __nat>::type = __nat()) _NOEXCEPT 227 : __ptr_(__p.release(), __value_init_tag()) {} 228 #endif 229 230 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 231 reset(__u.release()); 232 __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter()); 233 return *this; 234 } 235 236 template <class _Up, 237 class _Ep, 238 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 239 class = _EnableIfDeleterAssignable<_Ep> > 240 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 241 reset(__u.release()); 242 __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); 243 return *this; 244 } 245 246 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 247 template <class _Up> 248 _LIBCPP_INLINE_VISIBILITY 249 typename enable_if<is_convertible<_Up*, _Tp*>::value && 250 is_same<_Dp, default_delete<_Tp> >::value, 251 unique_ptr&>::type 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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 264 265 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 266 reset(); 267 return *this; 268 } 269 270 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const { 271 return *__ptr_.first(); 272 } 273 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { 274 return __ptr_.first(); 275 } 276 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 277 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { 278 return __ptr_.second(); 279 } 280 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 281 return __ptr_.second(); 282 } 283 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 284 return __ptr_.first() != nullptr; 285 } 286 287 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { 288 pointer __t = __ptr_.first(); 289 __ptr_.first() = pointer(); 290 return __t; 291 } 292 293 _LIBCPP_INLINE_VISIBILITY _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_INLINE_VISIBILITY _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 typename enable_if<is_default_constructible<_Deleter>::value && 346 !is_pointer<_Deleter>::value>::type; 347 348 template <class _ArgType> 349 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = 350 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type; 351 352 template <class _Pp> 353 using _EnableIfPointerConvertible _LIBCPP_NODEBUG = typename enable_if< 354 _CheckArrayPointerConversion<_Pp>::value 355 >::type; 356 357 template <class _UPtr, class _Up, 358 class _ElemT = typename _UPtr::element_type> 359 using _EnableIfMoveConvertible _LIBCPP_NODEBUG = typename enable_if< 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 >::type; 365 366 template <class _UDel> 367 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = typename enable_if< 368 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 369 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) 370 >::type; 371 372 template <class _UDel> 373 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = typename enable_if< 374 is_assignable<_Dp&, _UDel&&>::value 375 >::type; 376 377 public: 378 template <bool _Dummy = true, 379 class = _EnableIfDeleterDefaultConstructible<_Dummy> > 380 _LIBCPP_INLINE_VISIBILITY 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_INLINE_VISIBILITY 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_INLINE_VISIBILITY _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_INLINE_VISIBILITY _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_INLINE_VISIBILITY _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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 411 : __ptr_(__p, _VSTD::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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 418 : __ptr_(nullptr, _VSTD::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_INLINE_VISIBILITY 427 unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; 428 429 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 430 : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {} 431 432 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 433 reset(__u.release()); 434 __ptr_.second() = _VSTD::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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 443 : __ptr_(__u.release(), _VSTD::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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 450 reset(__u.release()); 451 __ptr_.second() = _VSTD::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_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 461 462 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 463 reset(); 464 return *this; 465 } 466 467 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> 468 operator[](size_t __i) const { 469 return __ptr_.first()[__i]; 470 } 471 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 472 473 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { 474 return __ptr_.second(); 475 } 476 477 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 478 return __ptr_.second(); 479 } 480 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 481 return __ptr_.first() != nullptr; 482 } 483 484 _LIBCPP_INLINE_VISIBILITY _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> 491 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 492 typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type 493 reset(_Pp __p) _NOEXCEPT { 494 pointer __tmp = __ptr_.first(); 495 __ptr_.first() = __p; 496 if (__tmp) 497 __ptr_.second()(__tmp); 498 } 499 500 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { 501 pointer __tmp = __ptr_.first(); 502 __ptr_.first() = nullptr; 503 if (__tmp) 504 __ptr_.second()(__tmp); 505 } 506 507 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { 508 __ptr_.swap(__u.__ptr_); 509 } 510 }; 511 512 template <class _Tp, class _Dp> 513 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 514 typename enable_if< __is_swappable<_Dp>::value, void >::type 515 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { 516 __x.swap(__y); 517 } 518 519 template <class _T1, class _D1, class _T2, class _D2> 520 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 521 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 522 return __x.get() == __y.get(); 523 } 524 525 #if _LIBCPP_STD_VER <= 17 526 template <class _T1, class _D1, class _T2, class _D2> 527 inline _LIBCPP_INLINE_VISIBILITY 528 bool 529 operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} 530 #endif 531 532 template <class _T1, class _D1, class _T2, class _D2> 533 inline _LIBCPP_INLINE_VISIBILITY 534 bool 535 operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) 536 { 537 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 538 typedef typename unique_ptr<_T2, _D2>::pointer _P2; 539 typedef typename common_type<_P1, _P2>::type _Vp; 540 return less<_Vp>()(__x.get(), __y.get()); 541 } 542 543 template <class _T1, class _D1, class _T2, class _D2> 544 inline _LIBCPP_INLINE_VISIBILITY 545 bool 546 operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} 547 548 template <class _T1, class _D1, class _T2, class _D2> 549 inline _LIBCPP_INLINE_VISIBILITY 550 bool 551 operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} 552 553 template <class _T1, class _D1, class _T2, class _D2> 554 inline _LIBCPP_INLINE_VISIBILITY 555 bool 556 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} 557 558 559 #if _LIBCPP_STD_VER > 17 560 template <class _T1, class _D1, class _T2, class _D2> 561 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, 562 typename unique_ptr<_T2, _D2>::pointer> 563 _LIBCPP_HIDE_FROM_ABI 564 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, 565 typename unique_ptr<_T2, _D2>::pointer> 566 operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 567 return compare_three_way()(__x.get(), __y.get()); 568 } 569 #endif 570 571 template <class _T1, class _D1> 572 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 573 operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 574 return !__x; 575 } 576 577 #if _LIBCPP_STD_VER <= 17 578 template <class _T1, class _D1> 579 inline _LIBCPP_INLINE_VISIBILITY 580 bool 581 operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 582 { 583 return !__x; 584 } 585 586 template <class _T1, class _D1> 587 inline _LIBCPP_INLINE_VISIBILITY 588 bool 589 operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT 590 { 591 return static_cast<bool>(__x); 592 } 593 594 template <class _T1, class _D1> 595 inline _LIBCPP_INLINE_VISIBILITY 596 bool 597 operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 598 { 599 return static_cast<bool>(__x); 600 } 601 #endif // _LIBCPP_STD_VER <= 17 602 603 template <class _T1, class _D1> 604 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 605 operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 606 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 607 return less<_P1>()(__x.get(), nullptr); 608 } 609 610 template <class _T1, class _D1> 611 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 612 operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 613 typedef typename unique_ptr<_T1, _D1>::pointer _P1; 614 return less<_P1>()(nullptr, __x.get()); 615 } 616 617 template <class _T1, class _D1> 618 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 619 operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 620 return nullptr < __x; 621 } 622 623 template <class _T1, class _D1> 624 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 625 operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 626 return __x < nullptr; 627 } 628 629 template <class _T1, class _D1> 630 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 631 operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 632 return !(nullptr < __x); 633 } 634 635 template <class _T1, class _D1> 636 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 637 operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 638 return !(__x < nullptr); 639 } 640 641 template <class _T1, class _D1> 642 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 643 operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 644 return !(__x < nullptr); 645 } 646 647 template <class _T1, class _D1> 648 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 649 operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 650 return !(nullptr < __x); 651 } 652 653 #if _LIBCPP_STD_VER > 17 654 template <class _T1, class _D1> 655 requires three_way_comparable< 656 typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 657 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> 658 operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 659 return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr)); 660 } 661 #endif 662 663 #if _LIBCPP_STD_VER > 11 664 665 template<class _Tp> 666 struct __unique_if 667 { 668 typedef unique_ptr<_Tp> __unique_single; 669 }; 670 671 template<class _Tp> 672 struct __unique_if<_Tp[]> 673 { 674 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; 675 }; 676 677 template<class _Tp, size_t _Np> 678 struct __unique_if<_Tp[_Np]> 679 { 680 typedef void __unique_array_known_bound; 681 }; 682 683 template <class _Tp, class... _Args> 684 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 685 make_unique(_Args&&... __args) { 686 return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); 687 } 688 689 template <class _Tp> 690 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 691 make_unique(size_t __n) { 692 typedef __remove_extent_t<_Tp> _Up; 693 return unique_ptr<_Tp>(new _Up[__n]()); 694 } 695 696 template<class _Tp, class... _Args> 697 typename __unique_if<_Tp>::__unique_array_known_bound 698 make_unique(_Args&&...) = delete; 699 700 #endif // _LIBCPP_STD_VER > 11 701 702 #if _LIBCPP_STD_VER >= 20 703 704 template <class _Tp> 705 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 706 make_unique_for_overwrite() { 707 return unique_ptr<_Tp>(new _Tp); 708 } 709 710 template <class _Tp> 711 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 712 make_unique_for_overwrite(size_t __n) { 713 return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); 714 } 715 716 template<class _Tp, class... _Args> 717 typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; 718 719 #endif // _LIBCPP_STD_VER >= 20 720 721 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 722 723 template <class _Tp, class _Dp> 724 #ifdef _LIBCPP_CXX03_LANG 725 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > 726 #else 727 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< 728 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > 729 #endif 730 { 731 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 732 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; 733 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 734 #endif 735 736 _LIBCPP_INLINE_VISIBILITY 737 size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const 738 { 739 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; 740 return hash<pointer>()(__ptr.get()); 741 } 742 }; 743 744 _LIBCPP_END_NAMESPACE_STD 745 746 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H 747