Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / __memory / unique_ptr.h
blob93a77b76dbd824c07004c4cdd500c8f9d20b51b4
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
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>
16 #include <__config>
17 #include <__functional/hash.h>
18 #include <__functional/operations.h>
19 #include <__memory/allocator_traits.h> // __pointer
20 #include <__memory/auto_ptr.h>
21 #include <__memory/compressed_pair.h>
22 #include <__type_traits/add_lvalue_reference.h>
23 #include <__type_traits/common_type.h>
24 #include <__type_traits/dependent_type.h>
25 #include <__type_traits/integral_constant.h>
26 #include <__type_traits/is_array.h>
27 #include <__type_traits/is_assignable.h>
28 #include <__type_traits/is_constructible.h>
29 #include <__type_traits/is_convertible.h>
30 #include <__type_traits/is_default_constructible.h>
31 #include <__type_traits/is_function.h>
32 #include <__type_traits/is_pointer.h>
33 #include <__type_traits/is_reference.h>
34 #include <__type_traits/is_same.h>
35 #include <__type_traits/is_swappable.h>
36 #include <__type_traits/is_void.h>
37 #include <__type_traits/remove_extent.h>
38 #include <__type_traits/type_identity.h>
39 #include <__utility/forward.h>
40 #include <__utility/move.h>
41 #include <cstddef>
43 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
44 # pragma GCC system_header
45 #endif
47 _LIBCPP_PUSH_MACROS
48 #include <__undef_macros>
50 _LIBCPP_BEGIN_NAMESPACE_STD
52 template <class _Tp>
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;
58 #else
59 _LIBCPP_INLINE_VISIBILITY default_delete() {}
60 #endif
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");
68 delete __ptr;
72 template <class _Tp>
73 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
74 private:
75 template <class _Up>
76 struct _EnableIfConvertible
77 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
79 public:
80 #ifndef _LIBCPP_CXX03_LANG
81 _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
82 #else
83 _LIBCPP_INLINE_VISIBILITY default_delete() {}
84 #endif
86 template <class _Up>
87 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
88 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
90 template <class _Up>
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");
94 delete[] __ptr;
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__))
122 #else
123 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
124 #endif
126 template <class _Tp, class _Dp = default_delete<_Tp> >
127 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
128 public:
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");
136 private:
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
182 public:
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())) {}
216 template <class _Up,
217 class _Ep,
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()) {}
229 #endif
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());
234 return *this;
237 template <class _Up,
238 class _Ep,
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());
244 return *this;
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
251 unique_ptr&
252 operator=(auto_ptr<_Up> __p) {
253 reset(__p.release());
254 return *this;
256 #endif
258 #ifdef _LIBCPP_CXX03_LANG
259 unique_ptr(unique_ptr const&) = delete;
260 unique_ptr& operator=(unique_ptr const&) = delete;
261 #endif
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 {
266 reset();
267 return *this;
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();
290 return __t;
293 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {
294 pointer __tmp = __ptr_.first();
295 __ptr_.first() = __p;
296 if (__tmp)
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> {
308 public:
309 typedef _Tp element_type;
310 typedef _Dp deleter_type;
311 typedef typename __pointer<_Tp, deleter_type>::type pointer;
313 private:
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>;
352 template <class _Pp>
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
377 public:
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()) {}
388 template <class _Pp,
389 bool _Dummy = true,
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()) {}
395 template <class _Pp,
396 bool _Dummy = true,
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) {}
406 template <class _Pp,
407 bool _Dummy = true,
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());
435 return *this;
438 template <class _Up,
439 class _Ep,
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())) {}
445 template <class _Up,
446 class _Ep,
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());
452 return *this;
455 #ifdef _LIBCPP_CXX03_LANG
456 unique_ptr(unique_ptr const&) = delete;
457 unique_ptr& operator=(unique_ptr const&) = delete;
458 #endif
459 public:
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 {
463 reset();
464 return *this;
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();
487 return __t;
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;
495 if (__tmp)
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;
502 if (__tmp)
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
513 void
514 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {
515 __x.swap(__y);
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
527 bool
528 operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
529 #endif
531 template <class _T1, class _D1, class _T2, class _D2>
532 inline _LIBCPP_INLINE_VISIBILITY
533 bool
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
544 bool
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
549 bool
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
554 bool
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());
568 #endif
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 {
573 return !__x;
576 #if _LIBCPP_STD_VER <= 17
577 template <class _T1, class _D1>
578 inline _LIBCPP_INLINE_VISIBILITY
579 bool
580 operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
582 return !__x;
585 template <class _T1, class _D1>
586 inline _LIBCPP_INLINE_VISIBILITY
587 bool
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
595 bool
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));
660 #endif
662 #if _LIBCPP_STD_VER >= 14
664 template<class _Tp>
665 struct __unique_if
667 typedef unique_ptr<_Tp> __unique_single;
670 template<class _Tp>
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)...));
688 template <class _Tp>
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
703 template <class _Tp>
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);
709 template <class _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> >
725 #else
726 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
727 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
728 #endif
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;
733 #endif
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
745 _LIBCPP_POP_MACROS
747 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H