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 52template <class _Tp> 53struct _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 70template <class _Tp> 71struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { 72private: 73 template <class _Up> 74 struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {}; 75 76public: 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 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, "the specified deleter type cannot be an rvalue reference"); 131 132private: 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 165public: 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 272template <class _Tp, class _Dp> 273class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { 274public: 275 typedef _Tp element_type; 276 typedef _Dp deleter_type; 277 typedef typename __pointer<_Tp, deleter_type>::type pointer; 278 279private: 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 327public: 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 405public: 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 451template <class _Tp, class _Dp, __enable_if_t<__is_swappable<_Dp>::value, int> = 0> 452inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void 453swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { 454 __x.swap(__y); 455} 456 457template <class _T1, class _D1, class _T2, class _D2> 458inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 459operator==(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 464template <class _T1, class _D1, class _T2, class _D2> 465inline _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 470template <class _T1, class _D1, class _T2, class _D2> 471inline _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 478template <class _T1, class _D1, class _T2, class _D2> 479inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 480 return __y < __x; 481} 482 483template <class _T1, class _D1, class _T2, class _D2> 484inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 485 return !(__y < __x); 486} 487 488template <class _T1, class _D1, class _T2, class _D2> 489inline _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 494template <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 503template <class _T1, class _D1> 504inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 505operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 506 return !__x; 507} 508 509#if _LIBCPP_STD_VER <= 17 510template <class _T1, class _D1> 511inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { 512 return !__x; 513} 514 515template <class _T1, class _D1> 516inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 517 return static_cast<bool>(__x); 518} 519 520template <class _T1, class _D1> 521inline _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 526template <class _T1, class _D1> 527inline _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 532template <class _T1, class _D1> 533inline _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 538template <class _T1, class _D1> 539inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 540 return nullptr < __x; 541} 542 543template <class _T1, class _D1> 544inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 545 return __x < nullptr; 546} 547 548template <class _T1, class _D1> 549inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 550 return !(nullptr < __x); 551} 552 553template <class _T1, class _D1> 554inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 555 return !(__x < nullptr); 556} 557 558template <class _T1, class _D1> 559inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 560 return !(__x < nullptr); 561} 562 563template <class _T1, class _D1> 564inline _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 569template <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> 572operator<=>(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 579template <class _Tp> 580struct __unique_if { 581 typedef unique_ptr<_Tp> __unique_single; 582}; 583 584template <class _Tp> 585struct __unique_if<_Tp[]> { 586 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; 587}; 588 589template <class _Tp, size_t _Np> 590struct __unique_if<_Tp[_Np]> { 591 typedef void __unique_array_known_bound; 592}; 593 594template <class _Tp, class... _Args> 595inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 596make_unique(_Args&&... __args) { 597 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); 598} 599 600template <class _Tp> 601inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 602make_unique(size_t __n) { 603 typedef __remove_extent_t<_Tp> _Up; 604 return unique_ptr<_Tp>(new _Up[__n]()); 605} 606 607template <class _Tp, class... _Args> 608typename __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 614template <class _Tp> 615_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 616make_unique_for_overwrite() { 617 return unique_ptr<_Tp>(new _Tp); 618} 619 620template <class _Tp> 621_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 622make_unique_for_overwrite(size_t __n) { 623 return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); 624} 625 626template <class _Tp, class... _Args> 627typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; 628 629#endif // _LIBCPP_STD_VER >= 20 630 631template <class _Tp> 632struct _LIBCPP_TEMPLATE_VIS hash; 633 634template <class _Tp, class _Dp> 635#ifdef _LIBCPP_CXX03_LANG 636struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > 637#else 638struct _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