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