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 <__cxx03/__compare/compare_three_way.h>
14 #include <__cxx03/__compare/compare_three_way_result.h>
15 #include <__cxx03/__compare/three_way_comparable.h>
16 #include <__cxx03/__config>
17 #include <__cxx03/__functional/hash.h>
18 #include <__cxx03/__functional/operations.h>
19 #include <__cxx03/__memory/allocator_traits.h> // __pointer
20 #include <__cxx03/__memory/auto_ptr.h>
21 #include <__cxx03/__memory/compressed_pair.h>
22 #include <__cxx03/__type_traits/add_lvalue_reference.h>
23 #include <__cxx03/__type_traits/common_type.h>
24 #include <__cxx03/__type_traits/conditional.h>
25 #include <__cxx03/__type_traits/dependent_type.h>
26 #include <__cxx03/__type_traits/integral_constant.h>
27 #include <__cxx03/__type_traits/is_array.h>
28 #include <__cxx03/__type_traits/is_assignable.h>
29 #include <__cxx03/__type_traits/is_constructible.h>
30 #include <__cxx03/__type_traits/is_convertible.h>
31 #include <__cxx03/__type_traits/is_function.h>
32 #include <__cxx03/__type_traits/is_pointer.h>
33 #include <__cxx03/__type_traits/is_reference.h>
34 #include <__cxx03/__type_traits/is_same.h>
35 #include <__cxx03/__type_traits/is_swappable.h>
36 #include <__cxx03/__type_traits/is_trivially_relocatable.h>
37 #include <__cxx03/__type_traits/is_void.h>
38 #include <__cxx03/__type_traits/remove_extent.h>
39 #include <__cxx03/__type_traits/remove_pointer.h>
40 #include <__cxx03/__type_traits/type_identity.h>
41 #include <__cxx03/__utility/declval.h>
42 #include <__cxx03/__utility/forward.h>
43 #include <__cxx03/__utility/move.h>
44 #include <__cxx03/cstddef>
46 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
47 # pragma GCC system_header
51 #include <__cxx03/__undef_macros>
53 _LIBCPP_BEGIN_NAMESPACE_STD
55 #ifndef _LIBCPP_CXX03_LANG
58 struct __is_noexcept_deref_or_void
{
59 static constexpr bool value
= noexcept(*std::declval
<_Ptr
>());
63 struct __is_noexcept_deref_or_void
<void*> : true_type
{};
67 struct _LIBCPP_TEMPLATE_VIS default_delete
{
68 static_assert(!is_function
<_Tp
>::value
, "default_delete cannot be instantiated for function types");
69 #ifndef _LIBCPP_CXX03_LANG
70 _LIBCPP_HIDE_FROM_ABI
constexpr default_delete() _NOEXCEPT
= default;
72 _LIBCPP_HIDE_FROM_ABI
default_delete() {}
74 template <class _Up
, __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
, int> = 0>
75 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
default_delete(const default_delete
<_Up
>&) _NOEXCEPT
{}
77 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void operator()(_Tp
* __ptr
) const _NOEXCEPT
{
78 static_assert(sizeof(_Tp
) >= 0, "cannot delete an incomplete type");
79 static_assert(!is_void
<_Tp
>::value
, "cannot delete an incomplete type");
85 struct _LIBCPP_TEMPLATE_VIS default_delete
<_Tp
[]> {
88 struct _EnableIfConvertible
: enable_if
<is_convertible
<_Up (*)[], _Tp (*)[]>::value
> {};
91 #ifndef _LIBCPP_CXX03_LANG
92 _LIBCPP_HIDE_FROM_ABI
constexpr default_delete() _NOEXCEPT
= default;
94 _LIBCPP_HIDE_FROM_ABI
default_delete() {}
98 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
99 default_delete(const default_delete
<_Up
[]>&, typename _EnableIfConvertible
<_Up
>::type
* = 0) _NOEXCEPT
{}
102 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible
<_Up
>::type
103 operator()(_Up
* __ptr
) const _NOEXCEPT
{
104 static_assert(sizeof(_Up
) >= 0, "cannot delete an incomplete type");
109 template <class _Deleter
>
110 struct __unique_ptr_deleter_sfinae
{
111 static_assert(!is_reference
<_Deleter
>::value
, "incorrect specialization");
112 typedef const _Deleter
& __lval_ref_type
;
113 typedef _Deleter
&& __good_rval_ref_type
;
114 typedef true_type __enable_rval_overload
;
117 template <class _Deleter
>
118 struct __unique_ptr_deleter_sfinae
<_Deleter
const&> {
119 typedef const _Deleter
& __lval_ref_type
;
120 typedef const _Deleter
&& __bad_rval_ref_type
;
121 typedef false_type __enable_rval_overload
;
124 template <class _Deleter
>
125 struct __unique_ptr_deleter_sfinae
<_Deleter
&> {
126 typedef _Deleter
& __lval_ref_type
;
127 typedef _Deleter
&& __bad_rval_ref_type
;
128 typedef false_type __enable_rval_overload
;
131 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
132 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
134 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
137 template <class _Tp
, class _Dp
= default_delete
<_Tp
> >
138 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
{
140 typedef _Tp element_type
;
141 typedef _Dp deleter_type
;
142 typedef _LIBCPP_NODEBUG typename __pointer
<_Tp
, deleter_type
>::type pointer
;
144 static_assert(!is_rvalue_reference
<deleter_type
>::value
, "the specified deleter type cannot be an rvalue reference");
146 // A unique_ptr contains the following members which may be trivially relocatable:
147 // - pointer : this may be trivially relocatable, so it's checked
148 // - deleter_type: this may be trivially relocatable, so it's checked
150 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
151 // references to itself. This means that the entire structure is trivially relocatable if its members are.
152 using __trivially_relocatable
= __conditional_t
<
153 __libcpp_is_trivially_relocatable
<pointer
>::value
&& __libcpp_is_trivially_relocatable
<deleter_type
>::value
,
158 __compressed_pair
<pointer
, deleter_type
> __ptr_
;
160 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
162 template <bool _Dummy
>
163 using _LValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
165 template <bool _Dummy
>
166 using _GoodRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
168 template <bool _Dummy
>
169 using _BadRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
171 template <bool _Dummy
, class _Deleter
= typename __dependent_type
< __type_identity
<deleter_type
>, _Dummy
>::type
>
172 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
173 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&& !is_pointer
<_Deleter
>::value
>;
175 template <class _ArgType
>
176 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
= __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
178 template <class _UPtr
, class _Up
>
179 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
=
180 __enable_if_t
< is_convertible
<typename
_UPtr::pointer
, pointer
>::value
&& !is_array
<_Up
>::value
>;
182 template <class _UDel
>
183 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
=
184 __enable_if_t
< (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
185 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
) >;
187 template <class _UDel
>
188 using _EnableIfDeleterAssignable
= __enable_if_t
< is_assignable
<_Dp
&, _UDel
&&>::value
>;
191 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
194 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
195 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
196 : __ptr_(__value_init_tag(), __value_init_tag()) {}
198 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
199 _LIBCPP_HIDE_FROM_ABI
200 _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(pointer __p
) _NOEXCEPT
: __ptr_(__p
, __value_init_tag()) {}
202 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
203 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(pointer __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
204 : __ptr_(__p
, __d
) {}
206 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(pointer __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
208 : __ptr_(__p
, std::move(__d
)) {
209 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
212 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> > >
213 _LIBCPP_HIDE_FROM_ABI
unique_ptr(pointer __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
216 : __ptr_(__u
.release(), std::forward
<deleter_type
>(__u
.get_deleter())) {}
220 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
221 class = _EnableIfDeleterConvertible
<_Ep
> >
222 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
223 : __ptr_(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter())) {}
225 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
227 __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&& is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
228 _LIBCPP_HIDE_FROM_ABI
unique_ptr(auto_ptr
<_Up
>&& __p
) _NOEXCEPT
: __ptr_(__p
.release(), __value_init_tag()) {}
231 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
232 reset(__u
.release());
233 __ptr_
.second() = std::forward
<deleter_type
>(__u
.get_deleter());
239 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
240 class = _EnableIfDeleterAssignable
<_Ep
> >
241 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
242 reset(__u
.release());
243 __ptr_
.second() = std::forward
<_Ep
>(__u
.get_deleter());
247 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
249 __enable_if_t
<is_convertible
<_Up
*, _Tp
*>::value
&& is_same
<_Dp
, default_delete
<_Tp
> >::value
, int> = 0>
250 _LIBCPP_HIDE_FROM_ABI unique_ptr
& operator=(auto_ptr
<_Up
> __p
) {
251 reset(__p
.release());
256 #ifdef _LIBCPP_CXX03_LANG
257 unique_ptr(unique_ptr
const&) = delete;
258 unique_ptr
& operator=(unique_ptr
const&) = delete;
261 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
268 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
> operator*() const
269 _NOEXCEPT_(__is_noexcept_deref_or_void
<pointer
>::value
) {
270 return *__ptr_
.first();
272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
operator->() const _NOEXCEPT
{ return __ptr_
.first(); }
273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
.first(); }
274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{ return __ptr_
.second(); }
275 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
276 return __ptr_
.second();
278 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
279 return __ptr_
.first() != nullptr;
282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
283 pointer __t
= __ptr_
.first();
284 __ptr_
.first() = pointer();
288 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(pointer __p
= pointer()) _NOEXCEPT
{
289 pointer __tmp
= __ptr_
.first();
290 __ptr_
.first() = __p
;
292 __ptr_
.second()(__tmp
);
295 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{ __ptr_
.swap(__u
.__ptr_
); }
298 template <class _Tp
, class _Dp
>
299 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr
<_Tp
[], _Dp
> {
301 typedef _Tp element_type
;
302 typedef _Dp deleter_type
;
303 typedef typename __pointer
<_Tp
, deleter_type
>::type pointer
;
305 // A unique_ptr contains the following members which may be trivially relocatable:
306 // - pointer : this may be trivially relocatable, so it's checked
307 // - deleter_type: this may be trivially relocatable, so it's checked
309 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
310 // references to itself. This means that the entire structure is trivially relocatable if its members are.
311 using __trivially_relocatable
= __conditional_t
<
312 __libcpp_is_trivially_relocatable
<pointer
>::value
&& __libcpp_is_trivially_relocatable
<deleter_type
>::value
,
317 __compressed_pair
<pointer
, deleter_type
> __ptr_
;
319 template <class _From
>
320 struct _CheckArrayPointerConversion
: is_same
<_From
, pointer
> {};
322 template <class _FromElem
>
323 struct _CheckArrayPointerConversion
<_FromElem
*>
324 : integral_constant
<bool,
325 is_same
<_FromElem
*, pointer
>::value
||
326 (is_same
<pointer
, element_type
*>::value
&&
327 is_convertible
<_FromElem (*)[], element_type (*)[]>::value
) > {};
329 typedef __unique_ptr_deleter_sfinae
<_Dp
> _DeleterSFINAE
;
331 template <bool _Dummy
>
332 using _LValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__lval_ref_type
;
334 template <bool _Dummy
>
335 using _GoodRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__good_rval_ref_type
;
337 template <bool _Dummy
>
338 using _BadRValRefType _LIBCPP_NODEBUG
= typename __dependent_type
<_DeleterSFINAE
, _Dummy
>::__bad_rval_ref_type
;
340 template <bool _Dummy
, class _Deleter
= typename __dependent_type
< __type_identity
<deleter_type
>, _Dummy
>::type
>
341 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG
=
342 __enable_if_t
<is_default_constructible
<_Deleter
>::value
&& !is_pointer
<_Deleter
>::value
>;
344 template <class _ArgType
>
345 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG
= __enable_if_t
<is_constructible
<deleter_type
, _ArgType
>::value
>;
348 using _EnableIfPointerConvertible _LIBCPP_NODEBUG
= __enable_if_t
< _CheckArrayPointerConversion
<_Pp
>::value
>;
350 template <class _UPtr
, class _Up
, class _ElemT
= typename
_UPtr::element_type
>
351 using _EnableIfMoveConvertible _LIBCPP_NODEBUG
=
352 __enable_if_t
< is_array
<_Up
>::value
&& is_same
<pointer
, element_type
*>::value
&&
353 is_same
<typename
_UPtr::pointer
, _ElemT
*>::value
&&
354 is_convertible
<_ElemT (*)[], element_type (*)[]>::value
>;
356 template <class _UDel
>
357 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG
=
358 __enable_if_t
< (is_reference
<_Dp
>::value
&& is_same
<_Dp
, _UDel
>::value
) ||
359 (!is_reference
<_Dp
>::value
&& is_convertible
<_UDel
, _Dp
>::value
) >;
361 template <class _UDel
>
362 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG
= __enable_if_t
< is_assignable
<_Dp
&, _UDel
&&>::value
>;
365 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
366 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr() _NOEXCEPT
: __ptr_(__value_init_tag(), __value_init_tag()) {}
368 template <bool _Dummy
= true, class = _EnableIfDeleterDefaultConstructible
<_Dummy
> >
369 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
unique_ptr(nullptr_t
) _NOEXCEPT
370 : __ptr_(__value_init_tag(), __value_init_tag()) {}
374 class = _EnableIfDeleterDefaultConstructible
<_Dummy
>,
375 class = _EnableIfPointerConvertible
<_Pp
> >
376 _LIBCPP_HIDE_FROM_ABI
377 _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit unique_ptr(_Pp __p
) _NOEXCEPT
: __ptr_(__p
, __value_init_tag()) {}
381 class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> >,
382 class = _EnableIfPointerConvertible
<_Pp
> >
383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
384 : __ptr_(__p
, __d
) {}
386 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_LValRefType
<_Dummy
> > >
387 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _LValRefType
<_Dummy
> __d
) _NOEXCEPT
388 : __ptr_(nullptr, __d
) {}
392 class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> >,
393 class = _EnableIfPointerConvertible
<_Pp
> >
394 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(_Pp __p
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
395 : __ptr_(__p
, std::move(__d
)) {
396 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
399 template <bool _Dummy
= true, class = _EnableIfDeleterConstructible
<_GoodRValRefType
<_Dummy
> > >
400 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(nullptr_t
, _GoodRValRefType
<_Dummy
> __d
) _NOEXCEPT
401 : __ptr_(nullptr, std::move(__d
)) {
402 static_assert(!is_reference
<deleter_type
>::value
, "rvalue deleter bound to reference");
407 class = _EnableIfDeleterConstructible
<_BadRValRefType
<_Dummy
> >,
408 class = _EnableIfPointerConvertible
<_Pp
> >
409 _LIBCPP_HIDE_FROM_ABI
unique_ptr(_Pp __p
, _BadRValRefType
<_Dummy
> __d
) = delete;
411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
&& __u
) _NOEXCEPT
412 : __ptr_(__u
.release(), std::forward
<deleter_type
>(__u
.get_deleter())) {}
414 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
&& __u
) _NOEXCEPT
{
415 reset(__u
.release());
416 __ptr_
.second() = std::forward
<deleter_type
>(__u
.get_deleter());
422 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
423 class = _EnableIfDeleterConvertible
<_Ep
> >
424 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
425 : __ptr_(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter())) {}
429 class = _EnableIfMoveConvertible
<unique_ptr
<_Up
, _Ep
>, _Up
>,
430 class = _EnableIfDeleterAssignable
<_Ep
> >
431 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(unique_ptr
<_Up
, _Ep
>&& __u
) _NOEXCEPT
{
432 reset(__u
.release());
433 __ptr_
.second() = std::forward
<_Ep
>(__u
.get_deleter());
437 #ifdef _LIBCPP_CXX03_LANG
438 unique_ptr(unique_ptr
const&) = delete;
439 unique_ptr
& operator=(unique_ptr
const&) = delete;
443 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
~unique_ptr() { reset(); }
445 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr
& operator=(nullptr_t
) _NOEXCEPT
{
450 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t
<_Tp
> operator[](size_t __i
) const {
451 return __ptr_
.first()[__i
];
453 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
get() const _NOEXCEPT
{ return __ptr_
.first(); }
455 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type
& get_deleter() _NOEXCEPT
{ return __ptr_
.second(); }
457 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
const deleter_type
& get_deleter() const _NOEXCEPT
{
458 return __ptr_
.second();
460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
explicit operator bool() const _NOEXCEPT
{
461 return __ptr_
.first() != nullptr;
464 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer
release() _NOEXCEPT
{
465 pointer __t
= __ptr_
.first();
466 __ptr_
.first() = pointer();
470 template <class _Pp
, __enable_if_t
<_CheckArrayPointerConversion
<_Pp
>::value
, int> = 0>
471 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(_Pp __p
) _NOEXCEPT
{
472 pointer __tmp
= __ptr_
.first();
473 __ptr_
.first() = __p
;
475 __ptr_
.second()(__tmp
);
478 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void reset(nullptr_t
= nullptr) _NOEXCEPT
{
479 pointer __tmp
= __ptr_
.first();
480 __ptr_
.first() = nullptr;
482 __ptr_
.second()(__tmp
);
485 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void swap(unique_ptr
& __u
) _NOEXCEPT
{ __ptr_
.swap(__u
.__ptr_
); }
488 template <class _Tp
, class _Dp
, __enable_if_t
<__is_swappable_v
<_Dp
>, int> = 0>
489 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
void
490 swap(unique_ptr
<_Tp
, _Dp
>& __x
, unique_ptr
<_Tp
, _Dp
>& __y
) _NOEXCEPT
{
494 template <class _T1
, class _D1
, class _T2
, class _D2
>
495 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
496 operator==(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
497 return __x
.get() == __y
.get();
500 #if _LIBCPP_STD_VER <= 17
501 template <class _T1
, class _D1
, class _T2
, class _D2
>
502 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
503 return !(__x
== __y
);
507 template <class _T1
, class _D1
, class _T2
, class _D2
>
508 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
509 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
510 typedef typename unique_ptr
<_T2
, _D2
>::pointer _P2
;
511 typedef typename common_type
<_P1
, _P2
>::type _Vp
;
512 return less
<_Vp
>()(__x
.get(), __y
.get());
515 template <class _T1
, class _D1
, class _T2
, class _D2
>
516 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
520 template <class _T1
, class _D1
, class _T2
, class _D2
>
521 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
525 template <class _T1
, class _D1
, class _T2
, class _D2
>
526 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
530 #if _LIBCPP_STD_VER >= 20
531 template <class _T1
, class _D1
, class _T2
, class _D2
>
532 requires three_way_comparable_with
<typename unique_ptr
<_T1
, _D1
>::pointer
, typename unique_ptr
<_T2
, _D2
>::pointer
>
533 _LIBCPP_HIDE_FROM_ABI
534 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
, typename unique_ptr
<_T2
, _D2
>::pointer
>
535 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, const unique_ptr
<_T2
, _D2
>& __y
) {
536 return compare_three_way()(__x
.get(), __y
.get());
540 template <class _T1
, class _D1
>
541 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool
542 operator==(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
{
546 #if _LIBCPP_STD_VER <= 17
547 template <class _T1
, class _D1
>
548 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
{
552 template <class _T1
, class _D1
>
553 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) _NOEXCEPT
{
554 return static_cast<bool>(__x
);
557 template <class _T1
, class _D1
>
558 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) _NOEXCEPT
{
559 return static_cast<bool>(__x
);
561 #endif // _LIBCPP_STD_VER <= 17
563 template <class _T1
, class _D1
>
564 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
565 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
566 return less
<_P1
>()(__x
.get(), nullptr);
569 template <class _T1
, class _D1
>
570 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
571 typedef typename unique_ptr
<_T1
, _D1
>::pointer _P1
;
572 return less
<_P1
>()(nullptr, __x
.get());
575 template <class _T1
, class _D1
>
576 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
577 return nullptr < __x
;
580 template <class _T1
, class _D1
>
581 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
582 return __x
< nullptr;
585 template <class _T1
, class _D1
>
586 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
587 return !(nullptr < __x
);
590 template <class _T1
, class _D1
>
591 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator<=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
592 return !(__x
< nullptr);
595 template <class _T1
, class _D1
>
596 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>=(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
597 return !(__x
< nullptr);
600 template <class _T1
, class _D1
>
601 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator>=(nullptr_t
, const unique_ptr
<_T1
, _D1
>& __x
) {
602 return !(nullptr < __x
);
605 #if _LIBCPP_STD_VER >= 20
606 template <class _T1
, class _D1
>
607 requires three_way_comparable
< typename unique_ptr
<_T1
, _D1
>::pointer
>
608 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t
<typename unique_ptr
<_T1
, _D1
>::pointer
>
609 operator<=>(const unique_ptr
<_T1
, _D1
>& __x
, nullptr_t
) {
610 return compare_three_way()(__x
.get(), static_cast<typename unique_ptr
<_T1
, _D1
>::pointer
>(nullptr));
614 #if _LIBCPP_STD_VER >= 14
618 typedef unique_ptr
<_Tp
> __unique_single
;
622 struct __unique_if
<_Tp
[]> {
623 typedef unique_ptr
<_Tp
[]> __unique_array_unknown_bound
;
626 template <class _Tp
, size_t _Np
>
627 struct __unique_if
<_Tp
[_Np
]> {
628 typedef void __unique_array_known_bound
;
631 template <class _Tp
, class... _Args
>
632 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_single
633 make_unique(_Args
&&... __args
) {
634 return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...));
638 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_array_unknown_bound
639 make_unique(size_t __n
) {
640 typedef __remove_extent_t
<_Tp
> _Up
;
641 return unique_ptr
<_Tp
>(new _Up
[__n
]());
644 template <class _Tp
, class... _Args
>
645 typename __unique_if
<_Tp
>::__unique_array_known_bound
make_unique(_Args
&&...) = delete;
647 #endif // _LIBCPP_STD_VER >= 14
649 #if _LIBCPP_STD_VER >= 20
652 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_single
653 make_unique_for_overwrite() {
654 return unique_ptr
<_Tp
>(new _Tp
);
658 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if
<_Tp
>::__unique_array_unknown_bound
659 make_unique_for_overwrite(size_t __n
) {
660 return unique_ptr
<_Tp
>(new __remove_extent_t
<_Tp
>[__n
]);
663 template <class _Tp
, class... _Args
>
664 typename __unique_if
<_Tp
>::__unique_array_known_bound
make_unique_for_overwrite(_Args
&&...) = delete;
666 #endif // _LIBCPP_STD_VER >= 20
669 struct _LIBCPP_TEMPLATE_VIS hash
;
671 template <class _Tp
, class _Dp
>
672 #ifdef _LIBCPP_CXX03_LANG
673 struct _LIBCPP_TEMPLATE_VIS hash
<unique_ptr
<_Tp
, _Dp
> >
675 struct _LIBCPP_TEMPLATE_VIS hash
<__enable_hash_helper
< unique_ptr
<_Tp
, _Dp
>, typename unique_ptr
<_Tp
, _Dp
>::pointer
> >
678 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
679 _LIBCPP_DEPRECATED_IN_CXX17
typedef unique_ptr
<_Tp
, _Dp
> argument_type
;
680 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
683 _LIBCPP_HIDE_FROM_ABI
size_t operator()(const unique_ptr
<_Tp
, _Dp
>& __ptr
) const {
684 typedef typename unique_ptr
<_Tp
, _Dp
>::pointer pointer
;
685 return hash
<pointer
>()(__ptr
.get());
689 _LIBCPP_END_NAMESPACE_STD
693 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H