File indexing completed on 2026-05-03 08:13:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
0011 #define _LIBCPP___MEMORY_UNIQUE_PTR_H
0012
0013 #include <__assert>
0014 #include <__compare/compare_three_way.h>
0015 #include <__compare/compare_three_way_result.h>
0016 #include <__compare/three_way_comparable.h>
0017 #include <__config>
0018 #include <__cstddef/nullptr_t.h>
0019 #include <__cstddef/size_t.h>
0020 #include <__functional/hash.h>
0021 #include <__functional/operations.h>
0022 #include <__memory/allocator_traits.h> // __pointer
0023 #include <__memory/array_cookie.h>
0024 #include <__memory/auto_ptr.h>
0025 #include <__memory/compressed_pair.h>
0026 #include <__memory/pointer_traits.h>
0027 #include <__type_traits/add_lvalue_reference.h>
0028 #include <__type_traits/common_type.h>
0029 #include <__type_traits/conditional.h>
0030 #include <__type_traits/dependent_type.h>
0031 #include <__type_traits/enable_if.h>
0032 #include <__type_traits/integral_constant.h>
0033 #include <__type_traits/is_array.h>
0034 #include <__type_traits/is_assignable.h>
0035 #include <__type_traits/is_bounded_array.h>
0036 #include <__type_traits/is_constant_evaluated.h>
0037 #include <__type_traits/is_constructible.h>
0038 #include <__type_traits/is_convertible.h>
0039 #include <__type_traits/is_function.h>
0040 #include <__type_traits/is_pointer.h>
0041 #include <__type_traits/is_reference.h>
0042 #include <__type_traits/is_same.h>
0043 #include <__type_traits/is_swappable.h>
0044 #include <__type_traits/is_trivially_relocatable.h>
0045 #include <__type_traits/is_unbounded_array.h>
0046 #include <__type_traits/is_void.h>
0047 #include <__type_traits/remove_extent.h>
0048 #include <__type_traits/type_identity.h>
0049 #include <__utility/declval.h>
0050 #include <__utility/forward.h>
0051 #include <__utility/move.h>
0052 #include <__utility/private_constructor_tag.h>
0053 #include <cstdint>
0054
0055 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0056 # pragma GCC system_header
0057 #endif
0058
0059 _LIBCPP_PUSH_MACROS
0060 #include <__undef_macros>
0061
0062 _LIBCPP_BEGIN_NAMESPACE_STD
0063
0064 template <class _Tp>
0065 struct _LIBCPP_TEMPLATE_VIS default_delete {
0066 static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types");
0067 #ifndef _LIBCPP_CXX03_LANG
0068 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default;
0069 #else
0070 _LIBCPP_HIDE_FROM_ABI default_delete() {}
0071 #endif
0072 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0>
0073 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up>&) _NOEXCEPT {}
0074
0075 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT {
0076 static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
0077 static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");
0078 delete __ptr;
0079 }
0080 };
0081
0082 template <class _Tp>
0083 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
0084 private:
0085 template <class _Up>
0086 struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {};
0087
0088 public:
0089 #ifndef _LIBCPP_CXX03_LANG
0090 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default;
0091 #else
0092 _LIBCPP_HIDE_FROM_ABI default_delete() {}
0093 #endif
0094
0095 template <class _Up>
0096 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
0097 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
0098
0099 template <class _Up>
0100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type
0101 operator()(_Up* __ptr) const _NOEXCEPT {
0102 static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");
0103 delete[] __ptr;
0104 }
0105 };
0106
0107 template <class _Deleter>
0108 struct __is_default_deleter : false_type {};
0109
0110 template <class _Tp>
0111 struct __is_default_deleter<default_delete<_Tp> > : true_type {};
0112
0113 template <class _Deleter>
0114 struct __unique_ptr_deleter_sfinae {
0115 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
0116 typedef const _Deleter& __lval_ref_type;
0117 typedef _Deleter&& __good_rval_ref_type;
0118 typedef true_type __enable_rval_overload;
0119 };
0120
0121 template <class _Deleter>
0122 struct __unique_ptr_deleter_sfinae<_Deleter const&> {
0123 typedef const _Deleter& __lval_ref_type;
0124 typedef const _Deleter&& __bad_rval_ref_type;
0125 typedef false_type __enable_rval_overload;
0126 };
0127
0128 template <class _Deleter>
0129 struct __unique_ptr_deleter_sfinae<_Deleter&> {
0130 typedef _Deleter& __lval_ref_type;
0131 typedef _Deleter&& __bad_rval_ref_type;
0132 typedef false_type __enable_rval_overload;
0133 };
0134
0135 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
0136 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
0137 #else
0138 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
0139 #endif
0140
0141 template <class _Tp, class _Dp = default_delete<_Tp> >
0142 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
0143 public:
0144 typedef _Tp element_type;
0145 typedef _Dp deleter_type;
0146 using pointer _LIBCPP_NODEBUG = __pointer<_Tp, deleter_type>;
0147
0148 static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");
0149
0150
0151
0152
0153
0154
0155
0156 using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
0157 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
0158 unique_ptr,
0159 void>;
0160
0161 private:
0162 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
0163
0164 using _DeleterSFINAE _LIBCPP_NODEBUG = __unique_ptr_deleter_sfinae<_Dp>;
0165
0166 template <bool _Dummy>
0167 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
0168
0169 template <bool _Dummy>
0170 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
0171
0172 template <bool _Dummy>
0173 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
0174
0175 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
0176 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
0177 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
0178
0179 template <class _ArgType>
0180 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
0181
0182 template <class _UPtr, class _Up>
0183 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
0184 __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >;
0185
0186 template <class _UDel>
0187 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =
0188 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
0189 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;
0190
0191 template <class _UDel>
0192 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
0193
0194 public:
0195 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
0196 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
0197
0198 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
0199 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
0200
0201 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
0202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT
0203 : __ptr_(__p),
0204 __deleter_() {}
0205
0206 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
0207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
0208 : __ptr_(__p),
0209 __deleter_(__d) {}
0210
0211 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
0212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
0213 : __ptr_(__p),
0214 __deleter_(std::move(__d)) {
0215 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
0216 }
0217
0218 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
0219 _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
0220
0221 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
0222 : __ptr_(__u.release()),
0223 __deleter_(std::forward<deleter_type>(__u.get_deleter())) {}
0224
0225 template <class _Up,
0226 class _Ep,
0227 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
0228 class = _EnableIfDeleterConvertible<_Ep> >
0229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
0230 : __ptr_(__u.release()),
0231 __deleter_(std::forward<_Ep>(__u.get_deleter())) {}
0232
0233 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
0234 template <class _Up,
0235 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>
0236 _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release()), __deleter_() {}
0237 #endif
0238
0239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
0240 reset(__u.release());
0241 __deleter_ = std::forward<deleter_type>(__u.get_deleter());
0242 return *this;
0243 }
0244
0245 template <class _Up,
0246 class _Ep,
0247 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
0248 class = _EnableIfDeleterAssignable<_Ep> >
0249 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
0250 reset(__u.release());
0251 __deleter_ = std::forward<_Ep>(__u.get_deleter());
0252 return *this;
0253 }
0254
0255 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
0256 template <class _Up,
0257 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>
0258 _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) {
0259 reset(__p.release());
0260 return *this;
0261 }
0262 #endif
0263
0264 #ifdef _LIBCPP_CXX03_LANG
0265 unique_ptr(unique_ptr const&) = delete;
0266 unique_ptr& operator=(unique_ptr const&) = delete;
0267 #endif
0268
0269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
0270
0271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
0272 reset();
0273 return *this;
0274 }
0275
0276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
0277 _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
0278 return *__ptr_;
0279 }
0280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
0281 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
0282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
0283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
0284 return __deleter_;
0285 }
0286 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
0287 return __ptr_ != nullptr;
0288 }
0289
0290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
0291 pointer __t = __ptr_;
0292 __ptr_ = pointer();
0293 return __t;
0294 }
0295
0296 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {
0297 pointer __tmp = __ptr_;
0298 __ptr_ = __p;
0299 if (__tmp)
0300 __deleter_(__tmp);
0301 }
0302
0303 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
0304 using std::swap;
0305 swap(__ptr_, __u.__ptr_);
0306 swap(__deleter_, __u.__deleter_);
0307 }
0308 };
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352 struct __unique_ptr_array_bounds_stateless {
0353 __unique_ptr_array_bounds_stateless() = default;
0354 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stateless(size_t) {}
0355
0356 template <class _Deleter,
0357 class _Tp,
0358 __enable_if_t<__is_default_deleter<_Deleter>::value && __has_array_cookie<_Tp>::value, int> = 0>
0359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
0360
0361
0362 if (__libcpp_is_constant_evaluated())
0363 return true;
0364 size_t __cookie = std::__get_array_cookie(__ptr);
0365 return __index < __cookie;
0366 }
0367
0368 template <class _Deleter,
0369 class _Tp,
0370 __enable_if_t<!__is_default_deleter<_Deleter>::value || !__has_array_cookie<_Tp>::value, int> = 0>
0371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t) const {
0372 return true;
0373 }
0374 };
0375
0376
0377
0378
0379
0380
0381 struct __unique_ptr_array_bounds_stored {
0382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __unique_ptr_array_bounds_stored() : __size_(SIZE_MAX) {}
0383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stored(size_t __size) : __size_(__size) {}
0384
0385
0386 template <class _Deleter,
0387 class _Tp,
0388 __enable_if_t<__is_default_deleter<_Deleter>::value && __has_array_cookie<_Tp>::value, int> = 0>
0389 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
0390 if (__libcpp_is_constant_evaluated())
0391 return true;
0392 size_t __cookie = std::__get_array_cookie(__ptr);
0393 return __index < __cookie;
0394 }
0395
0396
0397 template <class _Deleter,
0398 class _Tp,
0399 __enable_if_t<!__is_default_deleter<_Deleter>::value || !__has_array_cookie<_Tp>::value, int> = 0>
0400 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t __index) const {
0401 return __index < __size_;
0402 }
0403
0404 private:
0405 size_t __size_;
0406 };
0407
0408 template <class _Tp, class _Dp>
0409 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
0410 public:
0411 typedef _Tp element_type;
0412 typedef _Dp deleter_type;
0413 using pointer = __pointer<_Tp, deleter_type>;
0414
0415
0416
0417
0418
0419
0420
0421
0422 using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
0423 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
0424 unique_ptr,
0425 void>;
0426
0427 private:
0428 template <class _Up, class _OtherDeleter>
0429 friend class unique_ptr;
0430
0431 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
0432 #ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
0433 using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stored;
0434 #else
0435 using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stateless;
0436 #endif
0437 _LIBCPP_NO_UNIQUE_ADDRESS _BoundsChecker __checker_;
0438
0439 template <class _From>
0440 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
0441
0442 template <class _FromElem>
0443 struct _CheckArrayPointerConversion<_FromElem*>
0444 : integral_constant<bool,
0445 is_same<_FromElem*, pointer>::value ||
0446 (is_same<pointer, element_type*>::value &&
0447 is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {};
0448
0449 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
0450
0451 template <bool _Dummy>
0452 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
0453
0454 template <bool _Dummy>
0455 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
0456
0457 template <bool _Dummy>
0458 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
0459
0460 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
0461 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
0462 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
0463
0464 template <class _ArgType>
0465 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
0466
0467 template <class _Pp>
0468 using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;
0469
0470 template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type>
0471 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
0472 __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value &&
0473 is_same<typename _UPtr::pointer, _ElemT*>::value &&
0474 is_convertible<_ElemT (*)[], element_type (*)[]>::value >;
0475
0476 template <class _UDel>
0477 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =
0478 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
0479 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;
0480
0481 template <class _UDel>
0482 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
0483
0484 public:
0485 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
0486 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
0487
0488 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
0489 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
0490
0491 template <class _Pp,
0492 bool _Dummy = true,
0493 class = _EnableIfDeleterDefaultConstructible<_Dummy>,
0494 class = _EnableIfPointerConvertible<_Pp> >
0495 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __ptr) _NOEXCEPT
0496 : __ptr_(__ptr),
0497 __deleter_() {}
0498
0499
0500 template <class _Tag, class _Ptr, __enable_if_t<is_same<_Tag, __private_constructor_tag>::value, int> = 0>
0501 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Tag, _Ptr __ptr, size_t __size) _NOEXCEPT
0502 : __ptr_(__ptr),
0503 __checker_(__size) {}
0504
0505 template <class _Pp,
0506 bool _Dummy = true,
0507 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
0508 class = _EnableIfPointerConvertible<_Pp> >
0509 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __ptr, _LValRefType<_Dummy> __deleter) _NOEXCEPT
0510 : __ptr_(__ptr),
0511 __deleter_(__deleter) {}
0512
0513 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
0514 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __deleter) _NOEXCEPT
0515 : __ptr_(nullptr),
0516 __deleter_(__deleter) {}
0517
0518 template <class _Pp,
0519 bool _Dummy = true,
0520 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
0521 class = _EnableIfPointerConvertible<_Pp> >
0522 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
0523 unique_ptr(_Pp __ptr, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT
0524 : __ptr_(__ptr),
0525 __deleter_(std::move(__deleter)) {
0526 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
0527 }
0528
0529 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
0530 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
0531 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __deleter) _NOEXCEPT
0532 : __ptr_(nullptr),
0533 __deleter_(std::move(__deleter)) {
0534 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
0535 }
0536
0537 template <class _Pp,
0538 bool _Dummy = true,
0539 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
0540 class = _EnableIfPointerConvertible<_Pp> >
0541 _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __ptr, _BadRValRefType<_Dummy> __deleter) = delete;
0542
0543 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
0544 : __ptr_(__u.release()),
0545 __deleter_(std::forward<deleter_type>(__u.get_deleter())),
0546 __checker_(std::move(__u.__checker_)) {}
0547
0548 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
0549 reset(__u.release());
0550 __deleter_ = std::forward<deleter_type>(__u.get_deleter());
0551 __checker_ = std::move(__u.__checker_);
0552 return *this;
0553 }
0554
0555 template <class _Up,
0556 class _Ep,
0557 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
0558 class = _EnableIfDeleterConvertible<_Ep> >
0559 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
0560 : __ptr_(__u.release()),
0561 __deleter_(std::forward<_Ep>(__u.get_deleter())),
0562 __checker_(std::move(__u.__checker_)) {}
0563
0564 template <class _Up,
0565 class _Ep,
0566 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
0567 class = _EnableIfDeleterAssignable<_Ep> >
0568 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
0569 reset(__u.release());
0570 __deleter_ = std::forward<_Ep>(__u.get_deleter());
0571 __checker_ = std::move(__u.__checker_);
0572 return *this;
0573 }
0574
0575 #ifdef _LIBCPP_CXX03_LANG
0576 unique_ptr(unique_ptr const&) = delete;
0577 unique_ptr& operator=(unique_ptr const&) = delete;
0578 #endif
0579
0580 public:
0581 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
0582
0583 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
0584 reset();
0585 return *this;
0586 }
0587
0588 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const {
0589 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__checker_.__in_bounds<deleter_type>(std::__to_address(__ptr_), __i),
0590 "unique_ptr<T[]>::operator[](index): index out of range");
0591 return __ptr_[__i];
0592 }
0593 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
0594
0595 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
0596
0597 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
0598 return __deleter_;
0599 }
0600 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
0601 return __ptr_ != nullptr;
0602 }
0603
0604 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
0605 pointer __t = __ptr_;
0606 __ptr_ = pointer();
0607
0608
0609 return __t;
0610 }
0611
0612 template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0>
0613 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(_Pp __ptr) _NOEXCEPT {
0614 pointer __tmp = __ptr_;
0615 __ptr_ = __ptr;
0616 __checker_ = _BoundsChecker();
0617 if (__tmp)
0618 __deleter_(__tmp);
0619 }
0620
0621 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT {
0622 pointer __tmp = __ptr_;
0623 __ptr_ = nullptr;
0624 __checker_ = _BoundsChecker();
0625 if (__tmp)
0626 __deleter_(__tmp);
0627 }
0628
0629 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
0630 using std::swap;
0631 swap(__ptr_, __u.__ptr_);
0632 swap(__deleter_, __u.__deleter_);
0633 swap(__checker_, __u.__checker_);
0634 }
0635 };
0636
0637 template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0>
0638 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
0639 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {
0640 __x.swap(__y);
0641 }
0642
0643 template <class _T1, class _D1, class _T2, class _D2>
0644 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
0645 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0646 return __x.get() == __y.get();
0647 }
0648
0649 #if _LIBCPP_STD_VER <= 17
0650 template <class _T1, class _D1, class _T2, class _D2>
0651 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0652 return !(__x == __y);
0653 }
0654 #endif
0655
0656 template <class _T1, class _D1, class _T2, class _D2>
0657 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0658 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
0659 typedef typename unique_ptr<_T2, _D2>::pointer _P2;
0660 typedef typename common_type<_P1, _P2>::type _Vp;
0661 return less<_Vp>()(__x.get(), __y.get());
0662 }
0663
0664 template <class _T1, class _D1, class _T2, class _D2>
0665 inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0666 return __y < __x;
0667 }
0668
0669 template <class _T1, class _D1, class _T2, class _D2>
0670 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0671 return !(__y < __x);
0672 }
0673
0674 template <class _T1, class _D1, class _T2, class _D2>
0675 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0676 return !(__x < __y);
0677 }
0678
0679 #if _LIBCPP_STD_VER >= 20
0680 template <class _T1, class _D1, class _T2, class _D2>
0681 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>
0682 _LIBCPP_HIDE_FROM_ABI
0683 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>
0684 operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
0685 return compare_three_way()(__x.get(), __y.get());
0686 }
0687 #endif
0688
0689 template <class _T1, class _D1>
0690 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
0691 operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
0692 return !__x;
0693 }
0694
0695 #if _LIBCPP_STD_VER <= 17
0696 template <class _T1, class _D1>
0697 inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {
0698 return !__x;
0699 }
0700
0701 template <class _T1, class _D1>
0702 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
0703 return static_cast<bool>(__x);
0704 }
0705
0706 template <class _T1, class _D1>
0707 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {
0708 return static_cast<bool>(__x);
0709 }
0710 #endif
0711
0712 template <class _T1, class _D1>
0713 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
0714 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
0715 return less<_P1>()(__x.get(), nullptr);
0716 }
0717
0718 template <class _T1, class _D1>
0719 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
0720 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
0721 return less<_P1>()(nullptr, __x.get());
0722 }
0723
0724 template <class _T1, class _D1>
0725 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
0726 return nullptr < __x;
0727 }
0728
0729 template <class _T1, class _D1>
0730 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
0731 return __x < nullptr;
0732 }
0733
0734 template <class _T1, class _D1>
0735 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
0736 return !(nullptr < __x);
0737 }
0738
0739 template <class _T1, class _D1>
0740 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
0741 return !(__x < nullptr);
0742 }
0743
0744 template <class _T1, class _D1>
0745 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
0746 return !(__x < nullptr);
0747 }
0748
0749 template <class _T1, class _D1>
0750 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
0751 return !(nullptr < __x);
0752 }
0753
0754 #if _LIBCPP_STD_VER >= 20
0755 template <class _T1, class _D1>
0756 requires three_way_comparable< typename unique_ptr<_T1, _D1>::pointer>
0757 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>
0758 operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
0759 return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr));
0760 }
0761 #endif
0762
0763 #if _LIBCPP_STD_VER >= 14
0764
0765 template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
0766 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
0767 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
0768 }
0769
0770 template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
0771 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
0772 typedef __remove_extent_t<_Tp> _Up;
0773 return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
0774 }
0775
0776 template <class _Tp, class... _Args, enable_if_t<__is_bounded_array_v<_Tp>, int> = 0>
0777 void make_unique(_Args&&...) = delete;
0778
0779 #endif
0780
0781 #if _LIBCPP_STD_VER >= 20
0782
0783 template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
0784 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
0785 return unique_ptr<_Tp>(new _Tp);
0786 }
0787
0788 template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
0789 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
0790 return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
0791 }
0792
0793 template <class _Tp, class... _Args, enable_if_t<is_bounded_array_v<_Tp>, int> = 0>
0794 void make_unique_for_overwrite(_Args&&...) = delete;
0795
0796 #endif
0797
0798 template <class _Tp>
0799 struct _LIBCPP_TEMPLATE_VIS hash;
0800
0801 template <class _Tp, class _Dp>
0802 #ifdef _LIBCPP_CXX03_LANG
0803 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
0804 #else
0805 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
0806 #endif
0807 {
0808 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
0809 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
0810 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
0811 #endif
0812
0813 _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
0814 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
0815 return hash<pointer>()(__ptr.get());
0816 }
0817 };
0818
0819 _LIBCPP_END_NAMESPACE_STD
0820
0821 _LIBCPP_POP_MACROS
0822
0823 #endif