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
13 #include <__compare/compare_three_way.h>
14 #include <__compare/compare_three_way_result.h>
15 #include <__compare/three_way_comparable.h>
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>
43 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
44 # pragma GCC system_header
48 #include <__undef_macros>
50 _LIBCPP_BEGIN_NAMESPACE_STD
53 struct _LIBCPP_TEMPLATE_VIS default_delete
{
54 static_assert(!is_function
<_Tp
>::value
,
55 "default_delete cannot be instantiated for function types");
56 #ifndef _LIBCPP_CXX03_LANG
57 _LIBCPP_INLINE_VISIBILITY
constexpr default_delete() _NOEXCEPT
= default;
59 _LIBCPP_INLINE_VISIBILITY
default_delete() {}
61 template <class _Up
, __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
, int> = 0>
62 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
default_delete(
63 const default_delete
<_Up
>&) _NOEXCEPT
{}
65 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
void operator()(_Tp
* __ptr
) const _NOEXCEPT
{
66 static_assert(sizeof(_Tp
) >= 0, "cannot delete an incomplete type");
67 static_assert(!is_void
<_Tp
>::value
, "cannot delete an incomplete type");
73 struct _LIBCPP_TEMPLATE_VIS default_delete
<_Tp
[]> {
76 struct _EnableIfConvertible
77 : enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
> {};
80 #ifndef _LIBCPP_CXX03_LANG
81 _LIBCPP_INLINE_VISIBILITY
constexpr default_delete() _NOEXCEPT
= default;
83 _LIBCPP_INLINE_VISIBILITY
default_delete() {}
87 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
88 default_delete(const default_delete
<_Up
[]>&, typename _EnableIfConvertible
<_Up
>::type
* = 0) _NOEXCEPT
{}
91 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible
<_Up
>::type
92 operator()(_Up
* __ptr
) const _NOEXCEPT
{
93 static_assert(sizeof(_Up
) >= 0, "cannot delete an incomplete type");
98 template <class _Deleter
>
99 struct __unique_ptr_deleter_sfinae
{
100 static_assert(!is_reference
<_Deleter
>::value
, "incorrect specialization");
101 typedef const _Deleter
& __lval_ref_type
;
102 typedef _Deleter
&& __good_rval_ref_type
;
103 typedef true_type __enable_rval_overload
;
106 template <class _Deleter
>
107 struct __unique_ptr_deleter_sfinae
<_Deleter
const&> {
108 typedef const _Deleter
& __lval_ref_type
;
109 typedef const _Deleter
&& __bad_rval_ref_type
;
110 typedef false_type __enable_rval_overload
;
113 template <class _Deleter
>
114 struct __unique_ptr_deleter_sfinae
<_Deleter
&> {
115 typedef _Deleter
& __lval_ref_type
;
116 typedef _Deleter
&& __bad_rval_ref_type
;
117 typedef false_type __enable_rval_overload
;
120 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
121 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
123 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
126 template <class _Tp
, class _Dp
= default_delete
<_Tp
> >
127 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
{
129 typedef _Tp element_type
;
130 typedef _Dp deleter_type
;
131 typedef _LIBCPP_NODEBUG typename __pointer
<_Tp
, deleter_type
>::type pointer
;
133 static_assert(!is_rvalue_reference
<deleter_type
>::value
,
134 "the specified deleter type cannot be an rvalue reference");
137 __compressed_pair
<pointer
, deleter_type
> __ptr_
;
139 struct __nat
{ int __for_bool_
; };
141 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
143 template <bool _Dummy
>
144 using _LValRefType _LIBCPP_NODEBUG
=
145 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
147 template <bool _Dummy
>
148 using _GoodRValRefType _LIBCPP_NODEBUG
=
149 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
151 template <bool _Dummy
>
152 using _BadRValRefType _LIBCPP_NODEBUG
=
153 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
155 template <bool _Dummy
, class _Deleter
= typename __dependent_type
<
156 __type_identity
<deleter_type
>, _Dummy
>::type
>
157 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
158 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&&
159 !is_pointer
<_Deleter
>::value
>;
161 template <class _ArgType
>
162 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
=
163 __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
165 template <class _UPtr
, class _Up
>
166 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
= __enable_if_t
<
167 is_convertible
<typename
_UPtr::pointer
, pointer
>::value
&&
168 !is_array
<_Up
>::value
171 template <class _UDel
>
172 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
= __enable_if_t
<
173 (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
174 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
)
177 template <class _UDel
>
178 using _EnableIfDeleterAssignable
= __enable_if_t
<
179 is_assignable
<_Dp
&, _UDel
&&>::value
183 template <bool _Dummy
= true,
184 class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
185 _LIBCPP_INLINE_VISIBILITY
186 _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
188 template <bool _Dummy
= true,
189 class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
190 _LIBCPP_INLINE_VISIBILITY
191 _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
193 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
194 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(pointer __p
) _NOEXCEPT
195 : __ptr_(__p
, __value_init_tag()) {}
197 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
198 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(pointer __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
199 : __ptr_(__p
, __d
) {}
201 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
202 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
203 unique_ptr(pointer __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
: __ptr_(__p
, _VSTD::move(__d
)) {
204 static_assert(!is_reference
<deleter_type
>::value
,
205 "rvalue deleter bound to reference");
208 template <bool _Dummy
= true,
209 class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> > >
210 _LIBCPP_INLINE_VISIBILITY
211 unique_ptr(pointer __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
213 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
214 : __ptr_(__u
.release(), _VSTD::forward
<deleter_type
>(__u
.get_deleter())) {}
218 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
219 class = _EnableIfDeleterConvertible
<_Ep
> >
220 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
221 : __ptr_(__u
.release(), _VSTD::forward
<_Ep
>(__u
.get_deleter())) {}
223 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
224 template <class _Up
, __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&&
225 is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
226 _LIBCPP_INLINE_VISIBILITY
227 unique_ptr(auto_ptr
<_Up
>&& __p
) _NOEXCEPT
228 : __ptr_(__p
.release(), __value_init_tag()) {}
231 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
232 reset(__u
.release());
233 __ptr_
.second() = _VSTD::forward
<deleter_type
>(__u
.get_deleter());
239 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
240 class = _EnableIfDeleterAssignable
<_Ep
> >
241 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
242 reset(__u
.release());
243 __ptr_
.second() = _VSTD::forward
<_Ep
>(__u
.get_deleter());
247 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
248 template <class _Up
, __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&&
249 is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
250 _LIBCPP_INLINE_VISIBILITY
252 operator=(auto_ptr
<_Up
> __p
) {
253 reset(__p
.release());
258 #ifdef _LIBCPP_CXX03_LANG
259 unique_ptr(unique_ptr
const&) = delete;
260 unique_ptr
& operator=(unique_ptr
const&) = delete;
263 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
265 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
270 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
> operator*() const {
271 return *__ptr_
.first();
273 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
operator->() const _NOEXCEPT
{
274 return __ptr_
.first();
276 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
.first(); }
277 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{
278 return __ptr_
.second();
280 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
281 return __ptr_
.second();
283 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
284 return __ptr_
.first() != nullptr;
287 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
288 pointer __t
= __ptr_
.first();
289 __ptr_
.first() = pointer();
293 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(pointer __p
= pointer()) _NOEXCEPT
{
294 pointer __tmp
= __ptr_
.first();
295 __ptr_
.first() = __p
;
297 __ptr_
.second()(__tmp
);
300 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{
301 __ptr_
.swap(__u
.__ptr_
);
306 template <class _Tp
, class _Dp
>
307 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
<_Tp
[], _Dp
> {
309 typedef _Tp element_type
;
310 typedef _Dp deleter_type
;
311 typedef typename __pointer
<_Tp
, deleter_type
>::type pointer
;
314 __compressed_pair
<pointer
, deleter_type
> __ptr_
;
316 template <class _From
>
317 struct _CheckArrayPointerConversion
: is_same
<_From
, pointer
> {};
319 template <class _FromElem
>
320 struct _CheckArrayPointerConversion
<_FromElem
*>
321 : integral_constant
<bool,
322 is_same
<_FromElem
*, pointer
>::value
||
323 (is_same
<pointer
, element_type
*>::value
&&
324 is_convertible
<_FromElem(*)[], element_type(*)[]>::value
)
328 typedef __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
330 template <bool _Dummy
>
331 using _LValRefType _LIBCPP_NODEBUG
=
332 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
334 template <bool _Dummy
>
335 using _GoodRValRefType _LIBCPP_NODEBUG
=
336 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
338 template <bool _Dummy
>
339 using _BadRValRefType _LIBCPP_NODEBUG
=
340 typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
342 template <bool _Dummy
, class _Deleter
= typename __dependent_type
<
343 __type_identity
<deleter_type
>, _Dummy
>::type
>
344 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
345 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&&
346 !is_pointer
<_Deleter
>::value
>;
348 template <class _ArgType
>
349 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
=
350 __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
353 using _EnableIfPointerConvertible _LIBCPP_NODEBUG
= __enable_if_t
<
354 _CheckArrayPointerConversion
<_Pp
>::value
357 template <class _UPtr
, class _Up
,
358 class _ElemT
= typename
_UPtr::element_type
>
359 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
= __enable_if_t
<
360 is_array
<_Up
>::value
&&
361 is_same
<pointer
, element_type
*>::value
&&
362 is_same
<typename
_UPtr::pointer
, _ElemT
*>::value
&&
363 is_convertible
<_ElemT(*)[], element_type(*)[]>::value
366 template <class _UDel
>
367 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
= __enable_if_t
<
368 (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
369 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
)
372 template <class _UDel
>
373 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG
= __enable_if_t
<
374 is_assignable
<_Dp
&, _UDel
&&>::value
378 template <bool _Dummy
= true,
379 class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
380 _LIBCPP_INLINE_VISIBILITY
381 _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
383 template <bool _Dummy
= true,
384 class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
385 _LIBCPP_INLINE_VISIBILITY
386 _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
390 class = _EnableIfDeleterDefaultConstructible
<_Dummy
>,
391 class = _EnableIfPointerConvertible
<_Pp
> >
392 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(_Pp __p
) _NOEXCEPT
393 : __ptr_(__p
, __value_init_tag()) {}
397 class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> >,
398 class = _EnableIfPointerConvertible
<_Pp
> >
399 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
400 : __ptr_(__p
, __d
) {}
402 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
403 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
404 : __ptr_(nullptr, __d
) {}
408 class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> >,
409 class = _EnableIfPointerConvertible
<_Pp
> >
410 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
411 : __ptr_(__p
, _VSTD::move(__d
)) {
412 static_assert(!is_reference
<deleter_type
>::value
,
413 "rvalue deleter bound to reference");
416 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
417 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
418 : __ptr_(nullptr, _VSTD::move(__d
)) {
419 static_assert(!is_reference
<deleter_type
>::value
,
420 "rvalue deleter bound to reference");
423 template <class _Pp
, bool _Dummy
= true,
424 class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> >,
425 class = _EnableIfPointerConvertible
<_Pp
> >
426 _LIBCPP_INLINE_VISIBILITY
427 unique_ptr(_Pp __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
429 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
430 : __ptr_(__u
.release(), _VSTD::forward
<deleter_type
>(__u
.get_deleter())) {}
432 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
433 reset(__u
.release());
434 __ptr_
.second() = _VSTD::forward
<deleter_type
>(__u
.get_deleter());
440 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
441 class = _EnableIfDeleterConvertible
<_Ep
> >
442 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
443 : __ptr_(__u
.release(), _VSTD::forward
<_Ep
>(__u
.get_deleter())) {}
447 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
448 class = _EnableIfDeleterAssignable
<_Ep
> >
449 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
450 reset(__u
.release());
451 __ptr_
.second() = _VSTD::forward
<_Ep
>(__u
.get_deleter());
455 #ifdef _LIBCPP_CXX03_LANG
456 unique_ptr(unique_ptr
const&) = delete;
457 unique_ptr
& operator=(unique_ptr
const&) = delete;
460 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
462 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
467 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
>
468 operator[](size_t __i
) const {
469 return __ptr_
.first()[__i
];
471 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
.first(); }
473 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{
474 return __ptr_
.second();
477 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
478 return __ptr_
.second();
480 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
481 return __ptr_
.first() != nullptr;
484 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
485 pointer __t
= __ptr_
.first();
486 __ptr_
.first() = pointer();
490 template <class _Pp
, __enable_if_t
<_CheckArrayPointerConversion
<_Pp
>::value
, int> = 0>
491 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
492 void reset(_Pp __p
) _NOEXCEPT
{
493 pointer __tmp
= __ptr_
.first();
494 __ptr_
.first() = __p
;
496 __ptr_
.second()(__tmp
);
499 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(nullptr_t
= nullptr) _NOEXCEPT
{
500 pointer __tmp
= __ptr_
.first();
501 __ptr_
.first() = nullptr;
503 __ptr_
.second()(__tmp
);
506 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{
507 __ptr_
.swap(__u
.__ptr_
);
511 template <class _Tp
, class _Dp
, __enable_if_t
<__is_swappable
<_Dp
>::value
, int> = 0>
512 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
514 swap(unique_ptr
<_Tp
, _Dp
>& __x
, unique_ptr
<_Tp
, _Dp
>& __y
) _NOEXCEPT
{
518 template <class _T1
, class _D1
, class _T2
, class _D2
>
519 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
520 operator==(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
521 return __x
.get() == __y
.get();
524 #if _LIBCPP_STD_VER <= 17
525 template <class _T1
, class _D1
, class _T2
, class _D2
>
526 inline _LIBCPP_INLINE_VISIBILITY
528 operator!=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {return !(__x
== __y
);}
531 template <class _T1
, class _D1
, class _T2
, class _D2
>
532 inline _LIBCPP_INLINE_VISIBILITY
534 operator< (const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
)
536 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
537 typedef typename unique_ptr
<_T2
, _D2
>::pointer _P2
;
538 typedef typename common_type
<_P1
, _P2
>::type _Vp
;
539 return less
<_Vp
>()(__x
.get(), __y
.get());
542 template <class _T1
, class _D1
, class _T2
, class _D2
>
543 inline _LIBCPP_INLINE_VISIBILITY
545 operator> (const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {return __y
< __x
;}
547 template <class _T1
, class _D1
, class _T2
, class _D2
>
548 inline _LIBCPP_INLINE_VISIBILITY
550 operator<=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {return !(__y
< __x
);}
552 template <class _T1
, class _D1
, class _T2
, class _D2
>
553 inline _LIBCPP_INLINE_VISIBILITY
555 operator>=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {return !(__x
< __y
);}
558 #if _LIBCPP_STD_VER >= 20
559 template <class _T1
, class _D1
, class _T2
, class _D2
>
560 requires three_way_comparable_with
<typename unique_ptr
<_T1
, _D1
>::pointer
,
561 typename unique_ptr
<_T2
, _D2
>::pointer
>
562 _LIBCPP_HIDE_FROM_ABI
563 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
,
564 typename unique_ptr
<_T2
, _D2
>::pointer
>
565 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
566 return compare_three_way()(__x
.get(), __y
.get());
570 template <class _T1
, class _D1
>
571 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
572 operator==(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
{
576 #if _LIBCPP_STD_VER <= 17
577 template <class _T1
, class _D1
>
578 inline _LIBCPP_INLINE_VISIBILITY
580 operator==(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
585 template <class _T1
, class _D1
>
586 inline _LIBCPP_INLINE_VISIBILITY
588 operator!=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
590 return static_cast<bool>(__x
);
593 template <class _T1
, class _D1
>
594 inline _LIBCPP_INLINE_VISIBILITY
596 operator!=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
598 return static_cast<bool>(__x
);
600 #endif // _LIBCPP_STD_VER <= 17
602 template <class _T1
, class _D1
>
603 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
604 operator<(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
605 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
606 return less
<_P1
>()(__x
.get(), nullptr);
609 template <class _T1
, class _D1
>
610 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
611 operator<(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
612 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
613 return less
<_P1
>()(nullptr, __x
.get());
616 template <class _T1
, class _D1
>
617 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
618 operator>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
619 return nullptr < __x
;
622 template <class _T1
, class _D1
>
623 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
624 operator>(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
625 return __x
< nullptr;
628 template <class _T1
, class _D1
>
629 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
630 operator<=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
631 return !(nullptr < __x
);
634 template <class _T1
, class _D1
>
635 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
636 operator<=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
637 return !(__x
< nullptr);
640 template <class _T1
, class _D1
>
641 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
642 operator>=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
643 return !(__x
< nullptr);
646 template <class _T1
, class _D1
>
647 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
648 operator>=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
649 return !(nullptr < __x
);
652 #if _LIBCPP_STD_VER >= 20
653 template <class _T1
, class _D1
>
654 requires three_way_comparable
<
655 typename unique_ptr
<_T1
, _D1
>::pointer
> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
656 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
>
657 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
658 return compare_three_way()(__x
.get(), static_cast<typename unique_ptr
<_T1
, _D1
>::pointer
>(nullptr));
662 #if _LIBCPP_STD_VER >= 14
667 typedef unique_ptr
<_Tp
> __unique_single
;
671 struct __unique_if
<_Tp
[]>
673 typedef unique_ptr
<_Tp
[]> __unique_array_unknown_bound
;
676 template<class _Tp
, size_t _Np
>
677 struct __unique_if
<_Tp
[_Np
]>
679 typedef void __unique_array_known_bound
;
682 template <class _Tp
, class... _Args
>
683 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_single
684 make_unique(_Args
&&... __args
) {
685 return unique_ptr
<_Tp
>(new _Tp(_VSTD::forward
<_Args
>(__args
)...));
689 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_array_unknown_bound
690 make_unique(size_t __n
) {
691 typedef __remove_extent_t
<_Tp
> _Up
;
692 return unique_ptr
<_Tp
>(new _Up
[__n
]());
695 template<class _Tp
, class... _Args
>
696 typename __unique_if
<_Tp
>::__unique_array_known_bound
697 make_unique(_Args
&&...) = delete;
699 #endif // _LIBCPP_STD_VER >= 14
701 #if _LIBCPP_STD_VER >= 20
704 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_single
705 make_unique_for_overwrite() {
706 return unique_ptr
<_Tp
>(new _Tp
);
710 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_array_unknown_bound
711 make_unique_for_overwrite(size_t __n
) {
712 return unique_ptr
<_Tp
>(new __remove_extent_t
<_Tp
>[__n
]);
715 template<class _Tp
, class... _Args
>
716 typename __unique_if
<_Tp
>::__unique_array_known_bound
make_unique_for_overwrite(_Args
&&...) = delete;
718 #endif // _LIBCPP_STD_VER >= 20
720 template <class _Tp
> struct _LIBCPP_TEMPLATE_VIS hash
;
722 template <class _Tp
, class _Dp
>
723 #ifdef _LIBCPP_CXX03_LANG
724 struct _LIBCPP_TEMPLATE_VIS hash
<unique_ptr
<_Tp
, _Dp
> >
726 struct _LIBCPP_TEMPLATE_VIS hash
<__enable_hash_helper
<
727 unique_ptr
<_Tp
, _Dp
>, typename unique_ptr
<_Tp
, _Dp
>::pointer
> >
730 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
731 _LIBCPP_DEPRECATED_IN_CXX17
typedef unique_ptr
<_Tp
, _Dp
> argument_type
;
732 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
735 _LIBCPP_INLINE_VISIBILITY
736 size_t operator()(const unique_ptr
<_Tp
, _Dp
>& __ptr
) const
738 typedef typename unique_ptr
<_Tp
, _Dp
>::pointer pointer
;
739 return hash
<pointer
>()(__ptr
.get());
743 _LIBCPP_END_NAMESPACE_STD
747 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H