[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / libcxx / include / __cxx03 / __memory / unique_ptr.h
blob2576b6b37e7cb49fb2c68b96ed92561fe74a6ce2
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 <__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
48 #endif
50 _LIBCPP_PUSH_MACROS
51 #include <__cxx03/__undef_macros>
53 _LIBCPP_BEGIN_NAMESPACE_STD
55 #ifndef _LIBCPP_CXX03_LANG
57 template <class _Ptr>
58 struct __is_noexcept_deref_or_void {
59 static constexpr bool value = noexcept(*std::declval<_Ptr>());
62 template <>
63 struct __is_noexcept_deref_or_void<void*> : true_type {};
64 #endif
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 {}
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;
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> {};
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
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 {}
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;
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__))
133 #else
134 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
135 #endif
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;
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,
154 unique_ptr,
155 void>;
157 private:
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 >;
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()) {}
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())) {}
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())) {}
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
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;
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;
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;
254 #endif
256 #ifdef _LIBCPP_CXX03_LANG
257 unique_ptr(unique_ptr const&) = delete;
258 unique_ptr& operator=(unique_ptr const&) = delete;
259 #endif
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 {
264 reset();
265 return *this;
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();
285 return __t;
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);
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> {
300 public:
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,
313 unique_ptr,
314 void>;
316 private:
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>;
347 template <class _Pp>
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 >;
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()) {}
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()) {}
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()) {}
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) {}
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) {}
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");
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");
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;
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());
417 return *this;
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())) {}
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;
437 #ifdef _LIBCPP_CXX03_LANG
438 unique_ptr(unique_ptr const&) = delete;
439 unique_ptr& operator=(unique_ptr const&) = delete;
440 #endif
442 public:
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 {
446 reset();
447 return *this;
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();
467 return __t;
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);
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);
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 {
491 __x.swap(__y);
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);
505 #endif
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) {
517 return __y < __x;
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);
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);
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());
538 #endif
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;
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;
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));
612 #endif
614 #if _LIBCPP_STD_VER >= 14
616 template <class _Tp>
617 struct __unique_if {
618 typedef unique_ptr<_Tp> __unique_single;
621 template <class _Tp>
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)...));
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]());
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
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);
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]);
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
668 template <class _Tp>
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> >
674 #else
675 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
676 #endif
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
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
691 _LIBCPP_POP_MACROS
693 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H