unique_ptr.h revision 1.1.1.2
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 49template <class _Tp> 50struct _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 69template <class _Tp> 70struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { 71private: 72 template <class _Up> 73 struct _EnableIfConvertible 74 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {}; 75 76public: 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 95template <class _Deleter> 96struct __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 103template <class _Deleter> 104struct __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 110template <class _Deleter> 111struct __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 123template <class _Tp, class _Dp = default_delete<_Tp> > 124class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { 125public: 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 133private: 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 179public: 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 306template <class _Tp, class _Dp> 307class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { 308public: 309 typedef _Tp element_type; 310 typedef _Dp deleter_type; 311 typedef typename __pointer<_Tp, deleter_type>::type pointer; 312 313private: 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 377public: 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 459public: 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 512template <class _Tp, class _Dp> 513inline _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 519template <class _T1, class _D1, class _T2, class _D2> 520inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 521operator==(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 526template <class _T1, class _D1, class _T2, class _D2> 527inline _LIBCPP_INLINE_VISIBILITY 528bool 529operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} 530#endif 531 532template <class _T1, class _D1, class _T2, class _D2> 533inline _LIBCPP_INLINE_VISIBILITY 534bool 535operator< (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 543template <class _T1, class _D1, class _T2, class _D2> 544inline _LIBCPP_INLINE_VISIBILITY 545bool 546operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} 547 548template <class _T1, class _D1, class _T2, class _D2> 549inline _LIBCPP_INLINE_VISIBILITY 550bool 551operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} 552 553template <class _T1, class _D1, class _T2, class _D2> 554inline _LIBCPP_INLINE_VISIBILITY 555bool 556operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} 557 558 559#if _LIBCPP_STD_VER > 17 560template <class _T1, class _D1, class _T2, class _D2> 561requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, 562 typename unique_ptr<_T2, _D2>::pointer> 563_LIBCPP_HIDE_FROM_ABI 564compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, 565 typename unique_ptr<_T2, _D2>::pointer> 566operator<=>(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 571template <class _T1, class _D1> 572inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 573operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 574 return !__x; 575} 576 577#if _LIBCPP_STD_VER <= 17 578template <class _T1, class _D1> 579inline _LIBCPP_INLINE_VISIBILITY 580bool 581operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 582{ 583 return !__x; 584} 585 586template <class _T1, class _D1> 587inline _LIBCPP_INLINE_VISIBILITY 588bool 589operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT 590{ 591 return static_cast<bool>(__x); 592} 593 594template <class _T1, class _D1> 595inline _LIBCPP_INLINE_VISIBILITY 596bool 597operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT 598{ 599 return static_cast<bool>(__x); 600} 601#endif // _LIBCPP_STD_VER <= 17 602 603template <class _T1, class _D1> 604inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 605operator<(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 610template <class _T1, class _D1> 611inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 612operator<(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 617template <class _T1, class _D1> 618inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 619operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 620 return nullptr < __x; 621} 622 623template <class _T1, class _D1> 624inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 625operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 626 return __x < nullptr; 627} 628 629template <class _T1, class _D1> 630inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 631operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 632 return !(nullptr < __x); 633} 634 635template <class _T1, class _D1> 636inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 637operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 638 return !(__x < nullptr); 639} 640 641template <class _T1, class _D1> 642inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 643operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 644 return !(__x < nullptr); 645} 646 647template <class _T1, class _D1> 648inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 649operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 650 return !(nullptr < __x); 651} 652 653#if _LIBCPP_STD_VER > 17 654template <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> 658operator<=>(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 665template<class _Tp> 666struct __unique_if 667{ 668 typedef unique_ptr<_Tp> __unique_single; 669}; 670 671template<class _Tp> 672struct __unique_if<_Tp[]> 673{ 674 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; 675}; 676 677template<class _Tp, size_t _Np> 678struct __unique_if<_Tp[_Np]> 679{ 680 typedef void __unique_array_known_bound; 681}; 682 683template <class _Tp, class... _Args> 684inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 685make_unique(_Args&&... __args) { 686 return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); 687} 688 689template <class _Tp> 690inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 691make_unique(size_t __n) { 692 typedef __remove_extent_t<_Tp> _Up; 693 return unique_ptr<_Tp>(new _Up[__n]()); 694} 695 696template<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 704template <class _Tp> 705_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 706make_unique_for_overwrite() { 707 return unique_ptr<_Tp>(new _Tp); 708} 709 710template <class _Tp> 711_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 712make_unique_for_overwrite(size_t __n) { 713 return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); 714} 715 716template<class _Tp, class... _Args> 717typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; 718 719#endif // _LIBCPP_STD_VER >= 20 720 721template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 722 723template <class _Tp, class _Dp> 724#ifdef _LIBCPP_CXX03_LANG 725struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > 726#else 727struct _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