xref: /freebsd/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
11 #define _LIBCPP___MEMORY_UNIQUE_PTR_H
12 
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/conditional.h>
25 #include <__type_traits/dependent_type.h>
26 #include <__type_traits/integral_constant.h>
27 #include <__type_traits/is_array.h>
28 #include <__type_traits/is_assignable.h>
29 #include <__type_traits/is_constructible.h>
30 #include <__type_traits/is_convertible.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_trivially_relocatable.h>
37 #include <__type_traits/is_void.h>
38 #include <__type_traits/remove_extent.h>
39 #include <__type_traits/remove_pointer.h>
40 #include <__type_traits/type_identity.h>
41 #include <__utility/declval.h>
42 #include <__utility/forward.h>
43 #include <__utility/move.h>
44 #include <cstddef>
45 
46 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
47 #  pragma GCC system_header
48 #endif
49 
50 _LIBCPP_PUSH_MACROS
51 #include <__undef_macros>
52 
53 _LIBCPP_BEGIN_NAMESPACE_STD
54 
55 #ifndef _LIBCPP_CXX03_LANG
56 
57 template <class _Ptr>
58 struct __is_noexcept_deref_or_void {
59   static constexpr bool value = noexcept(*std::declval<_Ptr>());
60 };
61 
62 template <>
63 struct __is_noexcept_deref_or_void<void*> : true_type {};
64 #endif
65 
66 template <class _Tp>
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;
71 #else
72   _LIBCPP_HIDE_FROM_ABI default_delete() {}
73 #endif
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 {}
76 
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");
80     delete __ptr;
81   }
82 };
83 
84 template <class _Tp>
85 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
86 private:
87   template <class _Up>
88   struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {};
89 
90 public:
91 #ifndef _LIBCPP_CXX03_LANG
92   _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default;
93 #else
94   _LIBCPP_HIDE_FROM_ABI default_delete() {}
95 #endif
96 
97   template <class _Up>
98   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
99   default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
100 
101   template <class _Up>
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");
105     delete[] __ptr;
106   }
107 };
108 
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;
115 };
116 
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;
122 };
123 
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;
129 };
130 
131 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
132 #  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
133 #else
134 #  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
135 #endif
136 
137 template <class _Tp, class _Dp = default_delete<_Tp> >
138 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
139 public:
140   typedef _Tp element_type;
141   typedef _Dp deleter_type;
142   typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer;
143 
144   static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");
145 
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
149   //
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,
154       unique_ptr,
155       void>;
156 
157 private:
158   __compressed_pair<pointer, deleter_type> __ptr_;
159 
160   typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
161 
162   template <bool _Dummy>
163   using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
164 
165   template <bool _Dummy>
166   using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
167 
168   template <bool _Dummy>
169   using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
170 
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>;
174 
175   template <class _ArgType>
176   using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
177 
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 >;
181 
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) >;
186 
187   template <class _UDel>
188   using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
189 
190 public:
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()) {}
193 
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()) {}
197 
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()) {}
201 
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) {}
205 
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");
210   }
211 
212   template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
213   _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
214 
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())) {}
217 
218   template <class _Up,
219             class _Ep,
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())) {}
224 
225 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
226   template <class _Up,
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()) {}
229 #endif
230 
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());
234     return *this;
235   }
236 
237   template <class _Up,
238             class _Ep,
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());
244     return *this;
245   }
246 
247 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
248   template <class _Up,
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());
252     return *this;
253   }
254 #endif
255 
256 #ifdef _LIBCPP_CXX03_LANG
257   unique_ptr(unique_ptr const&)            = delete;
258   unique_ptr& operator=(unique_ptr const&) = delete;
259 #endif
260 
261   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
262 
263   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
264     reset();
265     return *this;
266   }
267 
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();
271   }
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();
277   }
278   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
279     return __ptr_.first() != nullptr;
280   }
281 
282   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
283     pointer __t    = __ptr_.first();
284     __ptr_.first() = pointer();
285     return __t;
286   }
287 
288   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {
289     pointer __tmp  = __ptr_.first();
290     __ptr_.first() = __p;
291     if (__tmp)
292       __ptr_.second()(__tmp);
293   }
294 
295   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); }
296 };
297 
298 template <class _Tp, class _Dp>
299 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
300 public:
301   typedef _Tp element_type;
302   typedef _Dp deleter_type;
303   typedef typename __pointer<_Tp, deleter_type>::type pointer;
304 
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
308   //
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,
313       unique_ptr,
314       void>;
315 
316 private:
317   __compressed_pair<pointer, deleter_type> __ptr_;
318 
319   template <class _From>
320   struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
321 
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) > {};
328 
329   typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
330 
331   template <bool _Dummy>
332   using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
333 
334   template <bool _Dummy>
335   using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
336 
337   template <bool _Dummy>
338   using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
339 
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>;
343 
344   template <class _ArgType>
345   using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
346 
347   template <class _Pp>
348   using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;
349 
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 >;
355 
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) >;
360 
361   template <class _UDel>
362   using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
363 
364 public:
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()) {}
367 
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()) {}
371 
372   template <class _Pp,
373             bool _Dummy = true,
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()) {}
378 
379   template <class _Pp,
380             bool _Dummy = true,
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) {}
385 
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) {}
389 
390   template <class _Pp,
391             bool _Dummy = true,
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");
397   }
398 
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");
403   }
404 
405   template <class _Pp,
406             bool _Dummy = true,
407             class       = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
408             class       = _EnableIfPointerConvertible<_Pp> >
409   _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
410 
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())) {}
413 
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());
417     return *this;
418   }
419 
420   template <class _Up,
421             class _Ep,
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())) {}
426 
427   template <class _Up,
428             class _Ep,
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());
434     return *this;
435   }
436 
437 #ifdef _LIBCPP_CXX03_LANG
438   unique_ptr(unique_ptr const&)            = delete;
439   unique_ptr& operator=(unique_ptr const&) = delete;
440 #endif
441 
442 public:
443   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
444 
445   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
446     reset();
447     return *this;
448   }
449 
450   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const {
451     return __ptr_.first()[__i];
452   }
453   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); }
454 
455   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); }
456 
457   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
458     return __ptr_.second();
459   }
460   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
461     return __ptr_.first() != nullptr;
462   }
463 
464   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
465     pointer __t    = __ptr_.first();
466     __ptr_.first() = pointer();
467     return __t;
468   }
469 
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;
474     if (__tmp)
475       __ptr_.second()(__tmp);
476   }
477 
478   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT {
479     pointer __tmp  = __ptr_.first();
480     __ptr_.first() = nullptr;
481     if (__tmp)
482       __ptr_.second()(__tmp);
483   }
484 
485   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); }
486 };
487 
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 {
491   __x.swap(__y);
492 }
493 
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();
498 }
499 
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);
504 }
505 #endif
506 
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());
513 }
514 
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) {
517   return __y < __x;
518 }
519 
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) {
522   return !(__y < __x);
523 }
524 
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) {
527   return !(__x < __y);
528 }
529 
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());
537 }
538 #endif
539 
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 {
543   return !__x;
544 }
545 
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 {
549   return !__x;
550 }
551 
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);
555 }
556 
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);
560 }
561 #endif // _LIBCPP_STD_VER <= 17
562 
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);
567 }
568 
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());
573 }
574 
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;
578 }
579 
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;
583 }
584 
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);
588 }
589 
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);
593 }
594 
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);
598 }
599 
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);
603 }
604 
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));
611 }
612 #endif
613 
614 #if _LIBCPP_STD_VER >= 14
615 
616 template <class _Tp>
617 struct __unique_if {
618   typedef unique_ptr<_Tp> __unique_single;
619 };
620 
621 template <class _Tp>
622 struct __unique_if<_Tp[]> {
623   typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
624 };
625 
626 template <class _Tp, size_t _Np>
627 struct __unique_if<_Tp[_Np]> {
628   typedef void __unique_array_known_bound;
629 };
630 
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)...));
635 }
636 
637 template <class _Tp>
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]());
642 }
643 
644 template <class _Tp, class... _Args>
645 typename __unique_if<_Tp>::__unique_array_known_bound make_unique(_Args&&...) = delete;
646 
647 #endif // _LIBCPP_STD_VER >= 14
648 
649 #if _LIBCPP_STD_VER >= 20
650 
651 template <class _Tp>
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);
655 }
656 
657 template <class _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]);
661 }
662 
663 template <class _Tp, class... _Args>
664 typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete;
665 
666 #endif // _LIBCPP_STD_VER >= 20
667 
668 template <class _Tp>
669 struct _LIBCPP_TEMPLATE_VIS hash;
670 
671 template <class _Tp, class _Dp>
672 #ifdef _LIBCPP_CXX03_LANG
673 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
674 #else
675 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
676 #endif
677 {
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;
681 #endif
682 
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());
686   }
687 };
688 
689 _LIBCPP_END_NAMESPACE_STD
690 
691 _LIBCPP_POP_MACROS
692 
693 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H
694