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
57template <class _Ptr>
58struct __is_noexcept_deref_or_void {
59 static constexpr bool value = noexcept(*std::declval<_Ptr>());
60};
61
62template <>
63struct __is_noexcept_deref_or_void<void*> : true_type {};
64#endif
65
66template <class _Tp>
67struct _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
84template <class _Tp>
85struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
86private:
87 template <class _Up>
88 struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {};
89
90public:
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
109template <class _Deleter>
110struct __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
117template <class _Deleter>
118struct __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
124template <class _Deleter>
125struct __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
137template <class _Tp, class _Dp = default_delete<_Tp> >
138class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
139public:
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
157private:
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
190public:
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
298template <class _Tp, class _Dp>
299class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
300public:
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
316private:
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
364public:
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
442public:
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
488template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0>
489inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
490swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {
491 __x.swap(__y);
492}
493
494template <class _T1, class _D1, class _T2, class _D2>
495inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
496operator==(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
501template <class _T1, class _D1, class _T2, class _D2>
502inline _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
507template <class _T1, class _D1, class _T2, class _D2>
508inline _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
515template <class _T1, class _D1, class _T2, class _D2>
516inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
517 return __y < __x;
518}
519
520template <class _T1, class _D1, class _T2, class _D2>
521inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
522 return !(__y < __x);
523}
524
525template <class _T1, class _D1, class _T2, class _D2>
526inline _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
531template <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
534compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>
535operator<=>(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
540template <class _T1, class _D1>
541inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
542operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
543 return !__x;
544}
545
546#if _LIBCPP_STD_VER <= 17
547template <class _T1, class _D1>
548inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {
549 return !__x;
550}
551
552template <class _T1, class _D1>
553inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
554 return static_cast<bool>(__x);
555}
556
557template <class _T1, class _D1>
558inline _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
563template <class _T1, class _D1>
564inline _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
569template <class _T1, class _D1>
570inline _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
575template <class _T1, class _D1>
576inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
577 return nullptr < __x;
578}
579
580template <class _T1, class _D1>
581inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
582 return __x < nullptr;
583}
584
585template <class _T1, class _D1>
586inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
587 return !(nullptr < __x);
588}
589
590template <class _T1, class _D1>
591inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
592 return !(__x < nullptr);
593}
594
595template <class _T1, class _D1>
596inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
597 return !(__x < nullptr);
598}
599
600template <class _T1, class _D1>
601inline _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
606template <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>
609operator<=>(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
616template <class _Tp>
617struct __unique_if {
618 typedef unique_ptr<_Tp> __unique_single;
619};
620
621template <class _Tp>
622struct __unique_if<_Tp[]> {
623 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
624};
625
626template <class _Tp, size_t _Np>
627struct __unique_if<_Tp[_Np]> {
628 typedef void __unique_array_known_bound;
629};
630
631template <class _Tp, class... _Args>
632inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single
633make_unique(_Args&&... __args) {
634 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
635}
636
637template <class _Tp>
638inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
639make_unique(size_t __n) {
640 typedef __remove_extent_t<_Tp> _Up;
641 return unique_ptr<_Tp>(new _Up[__n]());
642}
643
644template <class _Tp, class... _Args>
645typename __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
651template <class _Tp>
652_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single
653make_unique_for_overwrite() {
654 return unique_ptr<_Tp>(new _Tp);
655}
656
657template <class _Tp>
658_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
659make_unique_for_overwrite(size_t __n) {
660 return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]);
661}
662
663template <class _Tp, class... _Args>
664typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete;
665
666#endif // _LIBCPP_STD_VER >= 20
667
668template <class _Tp>
669struct _LIBCPP_TEMPLATE_VIS hash;
670
671template <class _Tp, class _Dp>
672#ifdef _LIBCPP_CXX03_LANG
673struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
674#else
675struct _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