[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / libcxx / include / __memory / unique_ptr.h
blob28c62e13566e249d1fd78c35b3b1cb6116bc8e55
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 <__assert>
14 #include <__compare/compare_three_way.h>
15 #include <__compare/compare_three_way_result.h>
16 #include <__compare/three_way_comparable.h>
17 #include <__config>
18 #include <__cstddef/nullptr_t.h>
19 #include <__cstddef/size_t.h>
20 #include <__functional/hash.h>
21 #include <__functional/operations.h>
22 #include <__memory/allocator_traits.h> // __pointer
23 #include <__memory/array_cookie.h>
24 #include <__memory/auto_ptr.h>
25 #include <__memory/compressed_pair.h>
26 #include <__memory/pointer_traits.h>
27 #include <__type_traits/add_lvalue_reference.h>
28 #include <__type_traits/common_type.h>
29 #include <__type_traits/conditional.h>
30 #include <__type_traits/dependent_type.h>
31 #include <__type_traits/enable_if.h>
32 #include <__type_traits/integral_constant.h>
33 #include <__type_traits/is_array.h>
34 #include <__type_traits/is_assignable.h>
35 #include <__type_traits/is_bounded_array.h>
36 #include <__type_traits/is_constant_evaluated.h>
37 #include <__type_traits/is_constructible.h>
38 #include <__type_traits/is_convertible.h>
39 #include <__type_traits/is_function.h>
40 #include <__type_traits/is_pointer.h>
41 #include <__type_traits/is_reference.h>
42 #include <__type_traits/is_same.h>
43 #include <__type_traits/is_swappable.h>
44 #include <__type_traits/is_trivially_relocatable.h>
45 #include <__type_traits/is_unbounded_array.h>
46 #include <__type_traits/is_void.h>
47 #include <__type_traits/remove_extent.h>
48 #include <__type_traits/type_identity.h>
49 #include <__utility/declval.h>
50 #include <__utility/forward.h>
51 #include <__utility/move.h>
52 #include <__utility/private_constructor_tag.h>
53 #include <cstdint>
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 # pragma GCC system_header
57 #endif
59 _LIBCPP_PUSH_MACROS
60 #include <__undef_macros>
62 _LIBCPP_BEGIN_NAMESPACE_STD
64 template <class _Tp>
65 struct _LIBCPP_TEMPLATE_VIS default_delete {
66 static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types");
67 #ifndef _LIBCPP_CXX03_LANG
68 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default;
69 #else
70 _LIBCPP_HIDE_FROM_ABI default_delete() {}
71 #endif
72 template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0>
73 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up>&) _NOEXCEPT {}
75 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT {
76 static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
77 static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");
78 delete __ptr;
82 template <class _Tp>
83 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
84 private:
85 template <class _Up>
86 struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {};
88 public:
89 #ifndef _LIBCPP_CXX03_LANG
90 _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default;
91 #else
92 _LIBCPP_HIDE_FROM_ABI default_delete() {}
93 #endif
95 template <class _Up>
96 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
97 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
99 template <class _Up>
100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type
101 operator()(_Up* __ptr) const _NOEXCEPT {
102 static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");
103 delete[] __ptr;
107 template <class _Deleter>
108 struct __is_default_deleter : false_type {};
110 template <class _Tp>
111 struct __is_default_deleter<default_delete<_Tp> > : true_type {};
113 template <class _Deleter>
114 struct __unique_ptr_deleter_sfinae {
115 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
116 typedef const _Deleter& __lval_ref_type;
117 typedef _Deleter&& __good_rval_ref_type;
118 typedef true_type __enable_rval_overload;
121 template <class _Deleter>
122 struct __unique_ptr_deleter_sfinae<_Deleter const&> {
123 typedef const _Deleter& __lval_ref_type;
124 typedef const _Deleter&& __bad_rval_ref_type;
125 typedef false_type __enable_rval_overload;
128 template <class _Deleter>
129 struct __unique_ptr_deleter_sfinae<_Deleter&> {
130 typedef _Deleter& __lval_ref_type;
131 typedef _Deleter&& __bad_rval_ref_type;
132 typedef false_type __enable_rval_overload;
135 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
136 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
137 #else
138 # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
139 #endif
141 template <class _Tp, class _Dp = default_delete<_Tp> >
142 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
143 public:
144 typedef _Tp element_type;
145 typedef _Dp deleter_type;
146 typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer;
148 static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");
150 // A unique_ptr contains the following members which may be trivially relocatable:
151 // - pointer : this may be trivially relocatable, so it's checked
152 // - deleter_type: this may be trivially relocatable, so it's checked
154 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
155 // references to itself. This means that the entire structure is trivially relocatable if its members are.
156 using __trivially_relocatable = __conditional_t<
157 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
158 unique_ptr,
159 void>;
161 private:
162 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
164 typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
166 template <bool _Dummy>
167 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
169 template <bool _Dummy>
170 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
172 template <bool _Dummy>
173 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
175 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
176 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
177 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
179 template <class _ArgType>
180 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
182 template <class _UPtr, class _Up>
183 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
184 __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >;
186 template <class _UDel>
187 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =
188 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
189 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;
191 template <class _UDel>
192 using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
194 public:
195 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
196 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
198 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
199 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
201 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT
203 : __ptr_(__p),
204 __deleter_() {}
206 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
208 : __ptr_(__p),
209 __deleter_(__d) {}
211 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
213 : __ptr_(__p),
214 __deleter_(std::move(__d)) {
215 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
218 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
219 _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
221 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
222 : __ptr_(__u.release()),
223 __deleter_(std::forward<deleter_type>(__u.get_deleter())) {}
225 template <class _Up,
226 class _Ep,
227 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
228 class = _EnableIfDeleterConvertible<_Ep> >
229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
230 : __ptr_(__u.release()),
231 __deleter_(std::forward<_Ep>(__u.get_deleter())) {}
233 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
234 template <class _Up,
235 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>
236 _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release()), __deleter_() {}
237 #endif
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
240 reset(__u.release());
241 __deleter_ = std::forward<deleter_type>(__u.get_deleter());
242 return *this;
245 template <class _Up,
246 class _Ep,
247 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
248 class = _EnableIfDeleterAssignable<_Ep> >
249 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
250 reset(__u.release());
251 __deleter_ = std::forward<_Ep>(__u.get_deleter());
252 return *this;
255 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
256 template <class _Up,
257 __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>
258 _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) {
259 reset(__p.release());
260 return *this;
262 #endif
264 #ifdef _LIBCPP_CXX03_LANG
265 unique_ptr(unique_ptr const&) = delete;
266 unique_ptr& operator=(unique_ptr const&) = delete;
267 #endif
269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
272 reset();
273 return *this;
276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
277 _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
278 return *__ptr_;
280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
281 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
284 return __deleter_;
286 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
287 return __ptr_ != nullptr;
290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
291 pointer __t = __ptr_;
292 __ptr_ = pointer();
293 return __t;
296 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {
297 pointer __tmp = __ptr_;
298 __ptr_ = __p;
299 if (__tmp)
300 __deleter_(__tmp);
303 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
304 using std::swap;
305 swap(__ptr_, __u.__ptr_);
306 swap(__deleter_, __u.__deleter_);
310 // Bounds checking in unique_ptr<T[]>
311 // ==================================
313 // We provide some helper classes that allow bounds checking when accessing a unique_ptr<T[]>.
314 // There are a few cases where bounds checking can be implemented:
316 // 1. When an array cookie (see [1]) exists at the beginning of the array allocation, we are
317 // able to reuse that cookie to extract the size of the array and perform bounds checking.
318 // An array cookie is a size inserted at the beginning of the allocation by the compiler.
319 // That size is inserted implicitly when doing `new T[n]` in some cases (as of writing this
320 // exactly when the array elements are not trivially destructible), and its main purpose is
321 // to allow the runtime to destroy the `n` array elements when doing `delete[] array`.
322 // When we are able to use array cookies, we reuse information already available in the
323 // current runtime, so bounds checking does not require changing libc++'s ABI.
325 // However, note that we cannot assume the presence of an array cookie when a custom deleter
326 // is used, because the unique_ptr could have been created from an allocation that wasn't
327 // obtained via `new T[n]` (since it may not be deleted with `delete[] arr`).
329 // 2. When the "bounded unique_ptr" ABI configuration (controlled by `_LIBCPP_ABI_BOUNDED_UNIQUE_PTR`)
330 // is enabled, we store the size of the allocation (when it is known) so we can check it when
331 // indexing into the `unique_ptr`. That changes the layout of `std::unique_ptr<T[]>`, which is
332 // an ABI break from the default configuration.
334 // Note that even under this ABI configuration, we can't always know the size of the unique_ptr.
335 // Indeed, the size of the allocation can only be known when the unique_ptr is created via
336 // make_unique or a similar API. For example, it can't be known when constructed from an arbitrary
337 // pointer, in which case we are not able to check the bounds on access:
339 // unique_ptr<T[], MyDeleter> ptr(new T[3]);
341 // When we don't know the size of the allocation via the API used to create the unique_ptr, we
342 // try to fall back to using an array cookie when available.
344 // Finally, note that when this ABI configuration is enabled, we have no choice but to always
345 // make space for the size to be stored in the unique_ptr. Indeed, while we might want to avoid
346 // storing the size when an array cookie is available, knowing whether an array cookie is available
347 // requires the type stored in the unique_ptr to be complete, while unique_ptr can normally
348 // accommodate incomplete types.
350 // (1) Implementation where we rely on the array cookie to know the size of the allocation, if
351 // an array cookie exists.
352 struct __unique_ptr_array_bounds_stateless {
353 __unique_ptr_array_bounds_stateless() = default;
354 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stateless(size_t) {}
356 template <class _Deleter,
357 class _Tp,
358 __enable_if_t<__is_default_deleter<_Deleter>::value && __has_array_cookie<_Tp>::value, int> = 0>
359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
360 // In constant expressions, we can't check the array cookie so we just pretend that the index
361 // is in-bounds. The compiler catches invalid accesses anyway.
362 if (__libcpp_is_constant_evaluated())
363 return true;
364 size_t __cookie = std::__get_array_cookie(__ptr);
365 return __index < __cookie;
368 template <class _Deleter,
369 class _Tp,
370 __enable_if_t<!__is_default_deleter<_Deleter>::value || !__has_array_cookie<_Tp>::value, int> = 0>
371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t) const {
372 return true; // If we don't have an array cookie, we assume the access is in-bounds
376 // (2) Implementation where we store the size in the class whenever we have it.
378 // Semantically, we'd need to store the size as an optional<size_t>. However, since that
379 // is really heavy weight, we instead store a size_t and use SIZE_MAX as a magic value
380 // meaning that we don't know the size.
381 struct __unique_ptr_array_bounds_stored {
382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __unique_ptr_array_bounds_stored() : __size_(SIZE_MAX) {}
383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __unique_ptr_array_bounds_stored(size_t __size) : __size_(__size) {}
385 // Use the array cookie if there's one
386 template <class _Deleter,
387 class _Tp,
388 __enable_if_t<__is_default_deleter<_Deleter>::value && __has_array_cookie<_Tp>::value, int> = 0>
389 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
390 if (__libcpp_is_constant_evaluated())
391 return true;
392 size_t __cookie = std::__get_array_cookie(__ptr);
393 return __index < __cookie;
396 // Otherwise, fall back on the stored size (if any)
397 template <class _Deleter,
398 class _Tp,
399 __enable_if_t<!__is_default_deleter<_Deleter>::value || !__has_array_cookie<_Tp>::value, int> = 0>
400 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t __index) const {
401 return __index < __size_;
404 private:
405 size_t __size_;
408 template <class _Tp, class _Dp>
409 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
410 public:
411 typedef _Tp element_type;
412 typedef _Dp deleter_type;
413 typedef typename __pointer<_Tp, deleter_type>::type pointer;
415 // A unique_ptr contains the following members which may be trivially relocatable:
416 // - pointer: this may be trivially relocatable, so it's checked
417 // - deleter_type: this may be trivially relocatable, so it's checked
418 // - (optionally) size: this is trivially relocatable
420 // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no
421 // references to itself. This means that the entire structure is trivially relocatable if its members are.
422 using __trivially_relocatable = __conditional_t<
423 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
424 unique_ptr,
425 void>;
427 private:
428 template <class _Up, class _OtherDeleter>
429 friend class unique_ptr;
431 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
432 #ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
433 using _BoundsChecker = __unique_ptr_array_bounds_stored;
434 #else
435 using _BoundsChecker = __unique_ptr_array_bounds_stateless;
436 #endif
437 _LIBCPP_NO_UNIQUE_ADDRESS _BoundsChecker __checker_;
439 template <class _From>
440 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
442 template <class _FromElem>
443 struct _CheckArrayPointerConversion<_FromElem*>
444 : integral_constant<bool,
445 is_same<_FromElem*, pointer>::value ||
446 (is_same<pointer, element_type*>::value &&
447 is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {};
449 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
451 template <bool _Dummy>
452 using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
454 template <bool _Dummy>
455 using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
457 template <bool _Dummy>
458 using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
460 template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>
461 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =
462 __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;
464 template <class _ArgType>
465 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;
467 template <class _Pp>
468 using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;
470 template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type>
471 using _EnableIfMoveConvertible _LIBCPP_NODEBUG =
472 __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value &&
473 is_same<typename _UPtr::pointer, _ElemT*>::value &&
474 is_convertible<_ElemT (*)[], element_type (*)[]>::value >;
476 template <class _UDel>
477 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =
478 __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
479 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;
481 template <class _UDel>
482 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;
484 public:
485 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
486 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(), __deleter_() {}
488 template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
489 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(), __deleter_() {}
491 template <class _Pp,
492 bool _Dummy = true,
493 class = _EnableIfDeleterDefaultConstructible<_Dummy>,
494 class = _EnableIfPointerConvertible<_Pp> >
495 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT
496 : __ptr_(__p),
497 __deleter_() {}
499 // Private constructor used by make_unique & friends to pass the size that was allocated
500 template <class _Tag, class _Ptr, __enable_if_t<is_same<_Tag, __private_constructor_tag>::value, int> = 0>
501 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Tag, _Ptr __ptr, size_t __size) _NOEXCEPT
502 : __ptr_(__ptr),
503 __checker_(__size) {}
505 template <class _Pp,
506 bool _Dummy = true,
507 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
508 class = _EnableIfPointerConvertible<_Pp> >
509 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
510 : __ptr_(__p),
511 __deleter_(__d) {}
513 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
514 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
515 : __ptr_(nullptr),
516 __deleter_(__d) {}
518 template <class _Pp,
519 bool _Dummy = true,
520 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
521 class = _EnableIfPointerConvertible<_Pp> >
522 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
523 : __ptr_(__p),
524 __deleter_(std::move(__d)) {
525 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
528 template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
529 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
530 : __ptr_(nullptr),
531 __deleter_(std::move(__d)) {
532 static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
535 template <class _Pp,
536 bool _Dummy = true,
537 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
538 class = _EnableIfPointerConvertible<_Pp> >
539 _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
541 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
542 : __ptr_(__u.release()),
543 __deleter_(std::forward<deleter_type>(__u.get_deleter())),
544 __checker_(std::move(__u.__checker_)) {}
546 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
547 reset(__u.release());
548 __deleter_ = std::forward<deleter_type>(__u.get_deleter());
549 __checker_ = std::move(__u.__checker_);
550 return *this;
553 template <class _Up,
554 class _Ep,
555 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
556 class = _EnableIfDeleterConvertible<_Ep> >
557 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
558 : __ptr_(__u.release()),
559 __deleter_(std::forward<_Ep>(__u.get_deleter())),
560 __checker_(std::move(__u.__checker_)) {}
562 template <class _Up,
563 class _Ep,
564 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
565 class = _EnableIfDeleterAssignable<_Ep> >
566 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
567 reset(__u.release());
568 __deleter_ = std::forward<_Ep>(__u.get_deleter());
569 __checker_ = std::move(__u.__checker_);
570 return *this;
573 #ifdef _LIBCPP_CXX03_LANG
574 unique_ptr(unique_ptr const&) = delete;
575 unique_ptr& operator=(unique_ptr const&) = delete;
576 #endif
578 public:
579 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
581 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
582 reset();
583 return *this;
586 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const {
587 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__checker_.__in_bounds<deleter_type>(std::__to_address(__ptr_), __i),
588 "unique_ptr<T[]>::operator[](index): index out of range");
589 return __ptr_[__i];
591 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
593 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
595 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
596 return __deleter_;
598 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
599 return __ptr_ != nullptr;
602 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
603 pointer __t = __ptr_;
604 __ptr_ = pointer();
605 // The deleter and the optional bounds-checker are left unchanged. The bounds-checker
606 // will be reinitialized appropriately when/if the unique_ptr gets assigned-to or reset.
607 return __t;
610 template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0>
611 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(_Pp __p) _NOEXCEPT {
612 pointer __tmp = __ptr_;
613 __ptr_ = __p;
614 __checker_ = _BoundsChecker();
615 if (__tmp)
616 __deleter_(__tmp);
619 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT {
620 pointer __tmp = __ptr_;
621 __ptr_ = nullptr;
622 __checker_ = _BoundsChecker();
623 if (__tmp)
624 __deleter_(__tmp);
627 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
628 using std::swap;
629 swap(__ptr_, __u.__ptr_);
630 swap(__deleter_, __u.__deleter_);
631 swap(__checker_, __u.__checker_);
635 template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0>
636 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
637 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {
638 __x.swap(__y);
641 template <class _T1, class _D1, class _T2, class _D2>
642 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
643 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
644 return __x.get() == __y.get();
647 #if _LIBCPP_STD_VER <= 17
648 template <class _T1, class _D1, class _T2, class _D2>
649 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
650 return !(__x == __y);
652 #endif
654 template <class _T1, class _D1, class _T2, class _D2>
655 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
656 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
657 typedef typename unique_ptr<_T2, _D2>::pointer _P2;
658 typedef typename common_type<_P1, _P2>::type _Vp;
659 return less<_Vp>()(__x.get(), __y.get());
662 template <class _T1, class _D1, class _T2, class _D2>
663 inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
664 return __y < __x;
667 template <class _T1, class _D1, class _T2, class _D2>
668 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
669 return !(__y < __x);
672 template <class _T1, class _D1, class _T2, class _D2>
673 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
674 return !(__x < __y);
677 #if _LIBCPP_STD_VER >= 20
678 template <class _T1, class _D1, class _T2, class _D2>
679 requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>
680 _LIBCPP_HIDE_FROM_ABI
681 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer>
682 operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
683 return compare_three_way()(__x.get(), __y.get());
685 #endif
687 template <class _T1, class _D1>
688 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
689 operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
690 return !__x;
693 #if _LIBCPP_STD_VER <= 17
694 template <class _T1, class _D1>
695 inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {
696 return !__x;
699 template <class _T1, class _D1>
700 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
701 return static_cast<bool>(__x);
704 template <class _T1, class _D1>
705 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {
706 return static_cast<bool>(__x);
708 #endif // _LIBCPP_STD_VER <= 17
710 template <class _T1, class _D1>
711 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
712 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
713 return less<_P1>()(__x.get(), nullptr);
716 template <class _T1, class _D1>
717 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
718 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
719 return less<_P1>()(nullptr, __x.get());
722 template <class _T1, class _D1>
723 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
724 return nullptr < __x;
727 template <class _T1, class _D1>
728 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
729 return __x < nullptr;
732 template <class _T1, class _D1>
733 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
734 return !(nullptr < __x);
737 template <class _T1, class _D1>
738 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
739 return !(__x < nullptr);
742 template <class _T1, class _D1>
743 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
744 return !(__x < nullptr);
747 template <class _T1, class _D1>
748 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
749 return !(nullptr < __x);
752 #if _LIBCPP_STD_VER >= 20
753 template <class _T1, class _D1>
754 requires three_way_comparable< typename unique_ptr<_T1, _D1>::pointer>
755 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>
756 operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
757 return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr));
759 #endif
761 #if _LIBCPP_STD_VER >= 14
763 template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
764 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
765 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
768 template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
769 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
770 typedef __remove_extent_t<_Tp> _Up;
771 return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
774 template <class _Tp, class... _Args, enable_if_t<__is_bounded_array_v<_Tp>, int> = 0>
775 void make_unique(_Args&&...) = delete;
777 #endif // _LIBCPP_STD_VER >= 14
779 #if _LIBCPP_STD_VER >= 20
781 template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
782 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
783 return unique_ptr<_Tp>(new _Tp);
786 template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
787 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
788 return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
791 template <class _Tp, class... _Args, enable_if_t<is_bounded_array_v<_Tp>, int> = 0>
792 void make_unique_for_overwrite(_Args&&...) = delete;
794 #endif // _LIBCPP_STD_VER >= 20
796 template <class _Tp>
797 struct _LIBCPP_TEMPLATE_VIS hash;
799 template <class _Tp, class _Dp>
800 #ifdef _LIBCPP_CXX03_LANG
801 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
802 #else
803 struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
804 #endif
806 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
807 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
808 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
809 #endif
811 _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
812 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
813 return hash<pointer>()(__ptr.get());
817 _LIBCPP_END_NAMESPACE_STD
819 _LIBCPP_POP_MACROS
821 #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H