2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
11 #define _LIBCPP___MEMORY_UNIQUE_PTR_H
14 #include <__compare/compare_three_way.h>
15 #include <__compare/compare_three_way_result.h>
16 #include <__compare/three_way_comparable.h>
18 #include <__cstddef/nullptr_t.h>
19 #include <__cstddef/size_t.h>
20 #include <__functional/hash.h>
21 #include <__functional/operations.h>
22 #include <__memory/allocator_traits.h> // __pointer
23 #include <__memory/array_cookie.h>
24 #include <__memory/auto_ptr.h>
25 #include <__memory/compressed_pair.h>
26 #include <__memory/pointer_traits.h>
27 #include <__type_traits/add_lvalue_reference.h>
28 #include <__type_traits/common_type.h>
29 #include <__type_traits/conditional.h>
30 #include <__type_traits/dependent_type.h>
31 #include <__type_traits/enable_if.h>
32 #include <__type_traits/integral_constant.h>
33 #include <__type_traits/is_array.h>
34 #include <__type_traits/is_assignable.h>
35 #include <__type_traits/is_bounded_array.h>
36 #include <__type_traits/is_constant_evaluated.h>
37 #include <__type_traits/is_constructible.h>
38 #include <__type_traits/is_convertible.h>
39 #include <__type_traits/is_function.h>
40 #include <__type_traits/is_pointer.h>
41 #include <__type_traits/is_reference.h>
42 #include <__type_traits/is_same.h>
43 #include <__type_traits/is_swappable.h>
44 #include <__type_traits/is_trivially_relocatable.h>
45 #include <__type_traits/is_unbounded_array.h>
46 #include <__type_traits/is_void.h>
47 #include <__type_traits/remove_extent.h>
48 #include <__type_traits/type_identity.h>
49 #include <__utility/declval.h>
50 #include <__utility/forward.h>
51 #include <__utility/move.h>
52 #include <__utility/private_constructor_tag.h>
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 # pragma GCC system_header
60 #include <__undef_macros>
62 _LIBCPP_BEGIN_NAMESPACE_STD
65 struct _LIBCPP_TEMPLATE_VIS default_delete
{
66 static_assert(!is_function
<_Tp
>::value
, "default_delete cannot be instantiated for function types");
67 #ifndef _LIBCPP_CXX03_LANG
68 _LIBCPP_HIDE_FROM_ABI
constexpr default_delete() _NOEXCEPT
= default;
70 _LIBCPP_HIDE_FROM_ABI
default_delete() {}
72 template <class _Up
, __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
, int> = 0>
73 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
default_delete(const default_delete
<_Up
>&) _NOEXCEPT
{}
75 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void operator()(_Tp
* __ptr
) const _NOEXCEPT
{
76 static_assert(sizeof(_Tp
) >= 0, "cannot delete an incomplete type");
77 static_assert(!is_void
<_Tp
>::value
, "cannot delete an incomplete type");
83 struct _LIBCPP_TEMPLATE_VIS default_delete
<_Tp
[]> {
86 struct _EnableIfConvertible
: enable_if
<is_convertible
<_Up (*)[], _Tp (*)[]>::value
> {};
89 #ifndef _LIBCPP_CXX03_LANG
90 _LIBCPP_HIDE_FROM_ABI
constexpr default_delete() _NOEXCEPT
= default;
92 _LIBCPP_HIDE_FROM_ABI
default_delete() {}
96 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
97 default_delete(const default_delete
<_Up
[]>&, typename _EnableIfConvertible
<_Up
>::type
* = 0) _NOEXCEPT
{}
100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible
<_Up
>::type
101 operator()(_Up
* __ptr
) const _NOEXCEPT
{
102 static_assert(sizeof(_Up
) >= 0, "cannot delete an incomplete type");
107 template <class _Deleter
>
108 struct __is_default_deleter
: false_type
{};
111 struct __is_default_deleter
<default_delete
<_Tp
> > : true_type
{};
113 template <class _Deleter
>
114 struct __unique_ptr_deleter_sfinae
{
115 static_assert(!is_reference
<_Deleter
>::value
, "incorrect specialization");
116 typedef const _Deleter
& __lval_ref_type
;
117 typedef _Deleter
&& __good_rval_ref_type
;
118 typedef true_type __enable_rval_overload
;
121 template <class _Deleter
>
122 struct __unique_ptr_deleter_sfinae
<_Deleter
const&> {
123 typedef const _Deleter
& __lval_ref_type
;
124 typedef const _Deleter
&& __bad_rval_ref_type
;
125 typedef false_type __enable_rval_overload
;
128 template <class _Deleter
>
129 struct __unique_ptr_deleter_sfinae
<_Deleter
&> {
130 typedef _Deleter
& __lval_ref_type
;
131 typedef _Deleter
&& __bad_rval_ref_type
;
132 typedef false_type __enable_rval_overload
;
135 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
136 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
138 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
141 template <class _Tp
, class _Dp
= default_delete
<_Tp
> >
142 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
{
144 typedef _Tp element_type
;
145 typedef _Dp deleter_type
;
146 typedef _LIBCPP_NODEBUG typename __pointer
<_Tp
, deleter_type
>::type pointer
;
148 static_assert(!is_rvalue_reference
<deleter_type
>::value
, "the specified deleter type cannot be an rvalue reference");
150 // A unique_ptr contains the following members which may be trivially relocatable:
151 // - pointer : this may be trivially relocatable, so it's checked
152 // - deleter_type: this may be trivially relocatable, so it's checked
154 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
155 // references to itself. This means that the entire structure is trivially relocatable if its members are.
156 using __trivially_relocatable
= __conditional_t
<
157 __libcpp_is_trivially_relocatable
<pointer
>::value
&& __libcpp_is_trivially_relocatable
<deleter_type
>::value
,
162 _LIBCPP_COMPRESSED_PAIR(pointer
, __ptr_
, deleter_type
, __deleter_
);
164 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
166 template <bool _Dummy
>
167 using _LValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
169 template <bool _Dummy
>
170 using _GoodRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
172 template <bool _Dummy
>
173 using _BadRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
175 template <bool _Dummy
, class _Deleter
= typename __dependent_type
< __type_identity
<deleter_type
>, _Dummy
>::type
>
176 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
177 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&& !is_pointer
<_Deleter
>::value
>;
179 template <class _ArgType
>
180 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
= __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
182 template <class _UPtr
, class _Up
>
183 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
=
184 __enable_if_t
< is_convertible
<typename
_UPtr::pointer
, pointer
>::value
&& !is_array
<_Up
>::value
>;
186 template <class _UDel
>
187 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
=
188 __enable_if_t
< (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
189 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
) >;
191 template <class _UDel
>
192 using _EnableIfDeleterAssignable
= __enable_if_t
< is_assignable
<_Dp
&, _UDel
&&>::value
>;
195 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
196 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(), __deleter_() {}
198 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
199 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(), __deleter_() {}
201 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(pointer __p
) _NOEXCEPT
206 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(pointer __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
211 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(pointer __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
214 __deleter_(std::move(__d
)) {
215 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
218 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> > >
219 _LIBCPP_HIDE_FROM_ABI
unique_ptr(pointer __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
221 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
222 : __ptr_(__u
.release()),
223 __deleter_(std::forward
<deleter_type
>(__u
.get_deleter())) {}
227 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
228 class = _EnableIfDeleterConvertible
<_Ep
> >
229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
230 : __ptr_(__u
.release()),
231 __deleter_(std::forward
<_Ep
>(__u
.get_deleter())) {}
233 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
235 __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&& is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
236 _LIBCPP_HIDE_FROM_ABI
unique_ptr(auto_ptr
<_Up
>&& __p
) _NOEXCEPT
: __ptr_(__p
.release()), __deleter_() {}
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
240 reset(__u
.release());
241 __deleter_
= std::forward
<deleter_type
>(__u
.get_deleter());
247 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
248 class = _EnableIfDeleterAssignable
<_Ep
> >
249 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
250 reset(__u
.release());
251 __deleter_
= std::forward
<_Ep
>(__u
.get_deleter());
255 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
257 __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&& is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
258 _LIBCPP_HIDE_FROM_ABI unique_ptr
& operator=(auto_ptr
<_Up
> __p
) {
259 reset(__p
.release());
264 #ifdef _LIBCPP_CXX03_LANG
265 unique_ptr(unique_ptr
const&) = delete;
266 unique_ptr
& operator=(unique_ptr
const&) = delete;
269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
> operator*() const
277 _NOEXCEPT_(_NOEXCEPT_(*std::declval
<pointer
>())) {
280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
operator->() const _NOEXCEPT
{ return __ptr_
; }
281 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
; }
282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{ return __deleter_
; }
283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
286 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
287 return __ptr_
!= nullptr;
290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
291 pointer __t
= __ptr_
;
296 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(pointer __p
= pointer()) _NOEXCEPT
{
297 pointer __tmp
= __ptr_
;
303 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{
305 swap(__ptr_
, __u
.__ptr_
);
306 swap(__deleter_
, __u
.__deleter_
);
310 // Bounds checking in unique_ptr<T[]>
311 // ==================================
313 // We provide some helper classes that allow bounds checking when accessing a unique_ptr<T[]>.
314 // There are a few cases where bounds checking can be implemented:
316 // 1. When an array cookie (see [1]) exists at the beginning of the array allocation, we are
317 // able to reuse that cookie to extract the size of the array and perform bounds checking.
318 // An array cookie is a size inserted at the beginning of the allocation by the compiler.
319 // That size is inserted implicitly when doing `new T[n]` in some cases (as of writing this
320 // exactly when the array elements are not trivially destructible), and its main purpose is
321 // to allow the runtime to destroy the `n` array elements when doing `delete[] array`.
322 // When we are able to use array cookies, we reuse information already available in the
323 // current runtime, so bounds checking does not require changing libc++'s ABI.
325 // However, note that we cannot assume the presence of an array cookie when a custom deleter
326 // is used, because the unique_ptr could have been created from an allocation that wasn't
327 // obtained via `new T[n]` (since it may not be deleted with `delete[] arr`).
329 // 2. When the "bounded unique_ptr" ABI configuration (controlled by `_LIBCPP_ABI_BOUNDED_UNIQUE_PTR`)
330 // is enabled, we store the size of the allocation (when it is known) so we can check it when
331 // indexing into the `unique_ptr`. That changes the layout of `std::unique_ptr<T[]>`, which is
332 // an ABI break from the default configuration.
334 // Note that even under this ABI configuration, we can't always know the size of the unique_ptr.
335 // Indeed, the size of the allocation can only be known when the unique_ptr is created via
336 // make_unique or a similar API. For example, it can't be known when constructed from an arbitrary
337 // pointer, in which case we are not able to check the bounds on access:
339 // unique_ptr<T[], MyDeleter> ptr(new T[3]);
341 // When we don't know the size of the allocation via the API used to create the unique_ptr, we
342 // try to fall back to using an array cookie when available.
344 // Finally, note that when this ABI configuration is enabled, we have no choice but to always
345 // make space for the size to be stored in the unique_ptr. Indeed, while we might want to avoid
346 // storing the size when an array cookie is available, knowing whether an array cookie is available
347 // requires the type stored in the unique_ptr to be complete, while unique_ptr can normally
348 // accommodate incomplete types.
350 // (1) Implementation where we rely on the array cookie to know the size of the allocation, if
351 // an array cookie exists.
352 struct __unique_ptr_array_bounds_stateless
{
353 __unique_ptr_array_bounds_stateless() = default;
354 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
explicit __unique_ptr_array_bounds_stateless(size_t) {}
356 template <class _Deleter
,
358 __enable_if_t
<__is_default_deleter
<_Deleter
>::value
&& __has_array_cookie
<_Tp
>::value
, int> = 0>
359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool __in_bounds(_Tp
* __ptr
, size_t __index
) const {
360 // In constant expressions, we can't check the array cookie so we just pretend that the index
361 // is in-bounds. The compiler catches invalid accesses anyway.
362 if (__libcpp_is_constant_evaluated())
364 size_t __cookie
= std::__get_array_cookie(__ptr
);
365 return __index
< __cookie
;
368 template <class _Deleter
,
370 __enable_if_t
<!__is_default_deleter
<_Deleter
>::value
|| !__has_array_cookie
<_Tp
>::value
, int> = 0>
371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool __in_bounds(_Tp
*, size_t) const {
372 return true; // If we don't have an array cookie, we assume the access is in-bounds
376 // (2) Implementation where we store the size in the class whenever we have it.
378 // Semantically, we'd need to store the size as an optional<size_t>. However, since that
379 // is really heavy weight, we instead store a size_t and use SIZE_MAX as a magic value
380 // meaning that we don't know the size.
381 struct __unique_ptr_array_bounds_stored
{
382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
__unique_ptr_array_bounds_stored() : __size_(SIZE_MAX
) {}
383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
explicit __unique_ptr_array_bounds_stored(size_t __size
) : __size_(__size
) {}
385 // Use the array cookie if there's one
386 template <class _Deleter
,
388 __enable_if_t
<__is_default_deleter
<_Deleter
>::value
&& __has_array_cookie
<_Tp
>::value
, int> = 0>
389 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool __in_bounds(_Tp
* __ptr
, size_t __index
) const {
390 if (__libcpp_is_constant_evaluated())
392 size_t __cookie
= std::__get_array_cookie(__ptr
);
393 return __index
< __cookie
;
396 // Otherwise, fall back on the stored size (if any)
397 template <class _Deleter
,
399 __enable_if_t
<!__is_default_deleter
<_Deleter
>::value
|| !__has_array_cookie
<_Tp
>::value
, int> = 0>
400 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool __in_bounds(_Tp
*, size_t __index
) const {
401 return __index
< __size_
;
408 template <class _Tp
, class _Dp
>
409 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
<_Tp
[], _Dp
> {
411 typedef _Tp element_type
;
412 typedef _Dp deleter_type
;
413 typedef typename __pointer
<_Tp
, deleter_type
>::type pointer
;
415 // A unique_ptr contains the following members which may be trivially relocatable:
416 // - pointer: this may be trivially relocatable, so it's checked
417 // - deleter_type: this may be trivially relocatable, so it's checked
418 // - (optionally) size: this is trivially relocatable
420 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
421 // references to itself. This means that the entire structure is trivially relocatable if its members are.
422 using __trivially_relocatable
= __conditional_t
<
423 __libcpp_is_trivially_relocatable
<pointer
>::value
&& __libcpp_is_trivially_relocatable
<deleter_type
>::value
,
428 template <class _Up
, class _OtherDeleter
>
429 friend class unique_ptr
;
431 _LIBCPP_COMPRESSED_PAIR(pointer
, __ptr_
, deleter_type
, __deleter_
);
432 #ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
433 using _BoundsChecker
= __unique_ptr_array_bounds_stored
;
435 using _BoundsChecker
= __unique_ptr_array_bounds_stateless
;
437 _LIBCPP_NO_UNIQUE_ADDRESS _BoundsChecker __checker_
;
439 template <class _From
>
440 struct _CheckArrayPointerConversion
: is_same
<_From
, pointer
> {};
442 template <class _FromElem
>
443 struct _CheckArrayPointerConversion
<_FromElem
*>
444 : integral_constant
<bool,
445 is_same
<_FromElem
*, pointer
>::value
||
446 (is_same
<pointer
, element_type
*>::value
&&
447 is_convertible
<_FromElem (*)[], element_type (*)[]>::value
) > {};
449 typedef __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
451 template <bool _Dummy
>
452 using _LValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
454 template <bool _Dummy
>
455 using _GoodRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
457 template <bool _Dummy
>
458 using _BadRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
460 template <bool _Dummy
, class _Deleter
= typename __dependent_type
< __type_identity
<deleter_type
>, _Dummy
>::type
>
461 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
462 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&& !is_pointer
<_Deleter
>::value
>;
464 template <class _ArgType
>
465 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
= __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
468 using _EnableIfPointerConvertible _LIBCPP_NODEBUG
= __enable_if_t
< _CheckArrayPointerConversion
<_Pp
>::value
>;
470 template <class _UPtr
, class _Up
, class _ElemT
= typename
_UPtr::element_type
>
471 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
=
472 __enable_if_t
< is_array
<_Up
>::value
&& is_same
<pointer
, element_type
*>::value
&&
473 is_same
<typename
_UPtr::pointer
, _ElemT
*>::value
&&
474 is_convertible
<_ElemT (*)[], element_type (*)[]>::value
>;
476 template <class _UDel
>
477 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
=
478 __enable_if_t
< (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
479 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
) >;
481 template <class _UDel
>
482 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG
= __enable_if_t
< is_assignable
<_Dp
&, _UDel
&&>::value
>;
485 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
486 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(), __deleter_() {}
488 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
489 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(), __deleter_() {}
493 class = _EnableIfDeleterDefaultConstructible
<_Dummy
>,
494 class = _EnableIfPointerConvertible
<_Pp
> >
495 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(_Pp __p
) _NOEXCEPT
499 // Private constructor used by make_unique & friends to pass the size that was allocated
500 template <class _Tag
, class _Ptr
, __enable_if_t
<is_same
<_Tag
, __private_constructor_tag
>::value
, int> = 0>
501 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(_Tag
, _Ptr __ptr
, size_t __size
) _NOEXCEPT
503 __checker_(__size
) {}
507 class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> >,
508 class = _EnableIfPointerConvertible
<_Pp
> >
509 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
513 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
514 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
520 class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> >,
521 class = _EnableIfPointerConvertible
<_Pp
> >
522 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
524 __deleter_(std::move(__d
)) {
525 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
528 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
529 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
531 __deleter_(std::move(__d
)) {
532 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
537 class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> >,
538 class = _EnableIfPointerConvertible
<_Pp
> >
539 _LIBCPP_HIDE_FROM_ABI
unique_ptr(_Pp __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
541 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
542 : __ptr_(__u
.release()),
543 __deleter_(std::forward
<deleter_type
>(__u
.get_deleter())),
544 __checker_(std::move(__u
.__checker_
)) {}
546 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
547 reset(__u
.release());
548 __deleter_
= std::forward
<deleter_type
>(__u
.get_deleter());
549 __checker_
= std::move(__u
.__checker_
);
555 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
556 class = _EnableIfDeleterConvertible
<_Ep
> >
557 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
558 : __ptr_(__u
.release()),
559 __deleter_(std::forward
<_Ep
>(__u
.get_deleter())),
560 __checker_(std::move(__u
.__checker_
)) {}
564 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
565 class = _EnableIfDeleterAssignable
<_Ep
> >
566 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
567 reset(__u
.release());
568 __deleter_
= std::forward
<_Ep
>(__u
.get_deleter());
569 __checker_
= std::move(__u
.__checker_
);
573 #ifdef _LIBCPP_CXX03_LANG
574 unique_ptr(unique_ptr
const&) = delete;
575 unique_ptr
& operator=(unique_ptr
const&) = delete;
579 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
581 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
586 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
> operator[](size_t __i
) const {
587 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__checker_
.__in_bounds
<deleter_type
>(std::__to_address(__ptr_
), __i
),
588 "unique_ptr<T[]>::operator[](index): index out of range");
591 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
; }
593 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{ return __deleter_
; }
595 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
598 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
599 return __ptr_
!= nullptr;
602 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
603 pointer __t
= __ptr_
;
605 // The deleter and the optional bounds-checker are left unchanged. The bounds-checker
606 // will be reinitialized appropriately when/if the unique_ptr gets assigned-to or reset.
610 template <class _Pp
, __enable_if_t
<_CheckArrayPointerConversion
<_Pp
>::value
, int> = 0>
611 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(_Pp __p
) _NOEXCEPT
{
612 pointer __tmp
= __ptr_
;
614 __checker_
= _BoundsChecker();
619 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(nullptr_t
= nullptr) _NOEXCEPT
{
620 pointer __tmp
= __ptr_
;
622 __checker_
= _BoundsChecker();
627 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{
629 swap(__ptr_
, __u
.__ptr_
);
630 swap(__deleter_
, __u
.__deleter_
);
631 swap(__checker_
, __u
.__checker_
);
635 template <class _Tp
, class _Dp
, __enable_if_t
<__is_swappable_v
<_Dp
>, int> = 0>
636 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void
637 swap(unique_ptr
<_Tp
, _Dp
>& __x
, unique_ptr
<_Tp
, _Dp
>& __y
) _NOEXCEPT
{
641 template <class _T1
, class _D1
, class _T2
, class _D2
>
642 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
643 operator==(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
644 return __x
.get() == __y
.get();
647 #if _LIBCPP_STD_VER <= 17
648 template <class _T1
, class _D1
, class _T2
, class _D2
>
649 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
650 return !(__x
== __y
);
654 template <class _T1
, class _D1
, class _T2
, class _D2
>
655 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
656 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
657 typedef typename unique_ptr
<_T2
, _D2
>::pointer _P2
;
658 typedef typename common_type
<_P1
, _P2
>::type _Vp
;
659 return less
<_Vp
>()(__x
.get(), __y
.get());
662 template <class _T1
, class _D1
, class _T2
, class _D2
>
663 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
667 template <class _T1
, class _D1
, class _T2
, class _D2
>
668 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
672 template <class _T1
, class _D1
, class _T2
, class _D2
>
673 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
677 #if _LIBCPP_STD_VER >= 20
678 template <class _T1
, class _D1
, class _T2
, class _D2
>
679 requires three_way_comparable_with
<typename unique_ptr
<_T1
, _D1
>::pointer
, typename unique_ptr
<_T2
, _D2
>::pointer
>
680 _LIBCPP_HIDE_FROM_ABI
681 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
, typename unique_ptr
<_T2
, _D2
>::pointer
>
682 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
683 return compare_three_way()(__x
.get(), __y
.get());
687 template <class _T1
, class _D1
>
688 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
689 operator==(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
{
693 #if _LIBCPP_STD_VER <= 17
694 template <class _T1
, class _D1
>
695 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
{
699 template <class _T1
, class _D1
>
700 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
{
701 return static_cast<bool>(__x
);
704 template <class _T1
, class _D1
>
705 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
{
706 return static_cast<bool>(__x
);
708 #endif // _LIBCPP_STD_VER <= 17
710 template <class _T1
, class _D1
>
711 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
712 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
713 return less
<_P1
>()(__x
.get(), nullptr);
716 template <class _T1
, class _D1
>
717 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
718 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
719 return less
<_P1
>()(nullptr, __x
.get());
722 template <class _T1
, class _D1
>
723 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
724 return nullptr < __x
;
727 template <class _T1
, class _D1
>
728 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
729 return __x
< nullptr;
732 template <class _T1
, class _D1
>
733 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
734 return !(nullptr < __x
);
737 template <class _T1
, class _D1
>
738 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
739 return !(__x
< nullptr);
742 template <class _T1
, class _D1
>
743 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
744 return !(__x
< nullptr);
747 template <class _T1
, class _D1
>
748 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
749 return !(nullptr < __x
);
752 #if _LIBCPP_STD_VER >= 20
753 template <class _T1
, class _D1
>
754 requires three_way_comparable
< typename unique_ptr
<_T1
, _D1
>::pointer
>
755 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
>
756 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
757 return compare_three_way()(__x
.get(), static_cast<typename unique_ptr
<_T1
, _D1
>::pointer
>(nullptr));
761 #if _LIBCPP_STD_VER >= 14
763 template <class _Tp
, class... _Args
, enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
764 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
<_Tp
> make_unique(_Args
&&... __args
) {
765 return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...));
768 template <class _Tp
, enable_if_t
<__is_unbounded_array_v
<_Tp
>, int> = 0>
769 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
<_Tp
> make_unique(size_t __n
) {
770 typedef __remove_extent_t
<_Tp
> _Up
;
771 return unique_ptr
<_Tp
>(__private_constructor_tag(), new _Up
[__n
](), __n
);
774 template <class _Tp
, class... _Args
, enable_if_t
<__is_bounded_array_v
<_Tp
>, int> = 0>
775 void make_unique(_Args
&&...) = delete;
777 #endif // _LIBCPP_STD_VER >= 14
779 #if _LIBCPP_STD_VER >= 20
781 template <class _Tp
, enable_if_t
<!is_array_v
<_Tp
>, int> = 0>
782 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
<_Tp
> make_unique_for_overwrite() {
783 return unique_ptr
<_Tp
>(new _Tp
);
786 template <class _Tp
, enable_if_t
<is_unbounded_array_v
<_Tp
>, int> = 0>
787 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
<_Tp
> make_unique_for_overwrite(size_t __n
) {
788 return unique_ptr
<_Tp
>(__private_constructor_tag(), new __remove_extent_t
<_Tp
>[__n
], __n
);
791 template <class _Tp
, class... _Args
, enable_if_t
<is_bounded_array_v
<_Tp
>, int> = 0>
792 void make_unique_for_overwrite(_Args
&&...) = delete;
794 #endif // _LIBCPP_STD_VER >= 20
797 struct _LIBCPP_TEMPLATE_VIS hash
;
799 template <class _Tp
, class _Dp
>
800 #ifdef _LIBCPP_CXX03_LANG
801 struct _LIBCPP_TEMPLATE_VIS hash
<unique_ptr
<_Tp
, _Dp
> >
803 struct _LIBCPP_TEMPLATE_VIS hash
<__enable_hash_helper
< unique_ptr
<_Tp
, _Dp
>, typename unique_ptr
<_Tp
, _Dp
>::pointer
> >
806 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
807 _LIBCPP_DEPRECATED_IN_CXX17
typedef unique_ptr
<_Tp
, _Dp
> argument_type
;
808 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
811 _LIBCPP_HIDE_FROM_ABI
size_t operator()(const unique_ptr
<_Tp
, _Dp
>& __ptr
) const {
812 typedef typename unique_ptr
<_Tp
, _Dp
>::pointer pointer
;
813 return hash
<pointer
>()(__ptr
.get());
817 _LIBCPP_END_NAMESPACE_STD
821 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H