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