1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H |
11 | #define _LIBCPP___MEMORY_UNIQUE_PTR_H |
12 | |
13 | #include <__compare/compare_three_way.h> |
14 | #include <__compare/compare_three_way_result.h> |
15 | #include <__compare/three_way_comparable.h> |
16 | #include <__config> |
17 | #include <__functional/hash.h> |
18 | #include <__functional/operations.h> |
19 | #include <__memory/allocator_traits.h> // __pointer |
20 | #include <__memory/auto_ptr.h> |
21 | #include <__memory/compressed_pair.h> |
22 | #include <__type_traits/add_lvalue_reference.h> |
23 | #include <__type_traits/common_type.h> |
24 | #include <__type_traits/conditional.h> |
25 | #include <__type_traits/dependent_type.h> |
26 | #include <__type_traits/integral_constant.h> |
27 | #include <__type_traits/is_array.h> |
28 | #include <__type_traits/is_assignable.h> |
29 | #include <__type_traits/is_constructible.h> |
30 | #include <__type_traits/is_convertible.h> |
31 | #include <__type_traits/is_function.h> |
32 | #include <__type_traits/is_pointer.h> |
33 | #include <__type_traits/is_reference.h> |
34 | #include <__type_traits/is_same.h> |
35 | #include <__type_traits/is_swappable.h> |
36 | #include <__type_traits/is_trivially_relocatable.h> |
37 | #include <__type_traits/is_void.h> |
38 | #include <__type_traits/remove_extent.h> |
39 | #include <__type_traits/remove_pointer.h> |
40 | #include <__type_traits/type_identity.h> |
41 | #include <__utility/declval.h> |
42 | #include <__utility/forward.h> |
43 | #include <__utility/move.h> |
44 | #include <cstddef> |
45 | |
46 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
47 | # pragma GCC system_header |
48 | #endif |
49 | |
50 | _LIBCPP_PUSH_MACROS |
51 | #include <__undef_macros> |
52 | |
53 | _LIBCPP_BEGIN_NAMESPACE_STD |
54 | |
55 | #ifndef _LIBCPP_CXX03_LANG |
56 | |
57 | template <class _Ptr> |
58 | struct __is_noexcept_deref_or_void { |
59 | static constexpr bool value = noexcept(*std::declval<_Ptr>()); |
60 | }; |
61 | |
62 | template <> |
63 | struct __is_noexcept_deref_or_void<void*> : true_type {}; |
64 | #endif |
65 | |
66 | template <class _Tp> |
67 | struct _LIBCPP_TEMPLATE_VIS default_delete { |
68 | static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types" ); |
69 | #ifndef _LIBCPP_CXX03_LANG |
70 | _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; |
71 | #else |
72 | _LIBCPP_HIDE_FROM_ABI default_delete() {} |
73 | #endif |
74 | template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0> |
75 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up>&) _NOEXCEPT {} |
76 | |
77 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { |
78 | static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type" ); |
79 | static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type" ); |
80 | delete __ptr; |
81 | } |
82 | }; |
83 | |
84 | template <class _Tp> |
85 | struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { |
86 | private: |
87 | template <class _Up> |
88 | struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {}; |
89 | |
90 | public: |
91 | #ifndef _LIBCPP_CXX03_LANG |
92 | _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; |
93 | #else |
94 | _LIBCPP_HIDE_FROM_ABI default_delete() {} |
95 | #endif |
96 | |
97 | template <class _Up> |
98 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 |
99 | default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} |
100 | |
101 | template <class _Up> |
102 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type |
103 | operator()(_Up* __ptr) const _NOEXCEPT { |
104 | static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type" ); |
105 | delete[] __ptr; |
106 | } |
107 | }; |
108 | |
109 | template <class _Deleter> |
110 | struct __unique_ptr_deleter_sfinae { |
111 | static_assert(!is_reference<_Deleter>::value, "incorrect specialization" ); |
112 | typedef const _Deleter& __lval_ref_type; |
113 | typedef _Deleter&& __good_rval_ref_type; |
114 | typedef true_type __enable_rval_overload; |
115 | }; |
116 | |
117 | template <class _Deleter> |
118 | struct __unique_ptr_deleter_sfinae<_Deleter const&> { |
119 | typedef const _Deleter& __lval_ref_type; |
120 | typedef const _Deleter&& __bad_rval_ref_type; |
121 | typedef false_type __enable_rval_overload; |
122 | }; |
123 | |
124 | template <class _Deleter> |
125 | struct __unique_ptr_deleter_sfinae<_Deleter&> { |
126 | typedef _Deleter& __lval_ref_type; |
127 | typedef _Deleter&& __bad_rval_ref_type; |
128 | typedef false_type __enable_rval_overload; |
129 | }; |
130 | |
131 | #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI) |
132 | # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) |
133 | #else |
134 | # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI |
135 | #endif |
136 | |
137 | template <class _Tp, class _Dp = default_delete<_Tp> > |
138 | class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { |
139 | public: |
140 | typedef _Tp element_type; |
141 | typedef _Dp deleter_type; |
142 | typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer; |
143 | |
144 | static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference" ); |
145 | |
146 | // A unique_ptr contains the following members which may be trivially relocatable: |
147 | // - pointer : this may be trivially relocatable, so it's checked |
148 | // - deleter_type: this may be trivially relocatable, so it's checked |
149 | // |
150 | // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no |
151 | // references to itself. This means that the entire structure is trivially relocatable if its members are. |
152 | using __trivially_relocatable = __conditional_t< |
153 | __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, |
154 | unique_ptr, |
155 | void>; |
156 | |
157 | private: |
158 | __compressed_pair<pointer, deleter_type> __ptr_; |
159 | |
160 | typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; |
161 | |
162 | template <bool _Dummy> |
163 | using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; |
164 | |
165 | template <bool _Dummy> |
166 | using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; |
167 | |
168 | template <bool _Dummy> |
169 | using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; |
170 | |
171 | template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type> |
172 | using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = |
173 | __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>; |
174 | |
175 | template <class _ArgType> |
176 | using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; |
177 | |
178 | template <class _UPtr, class _Up> |
179 | using _EnableIfMoveConvertible _LIBCPP_NODEBUG = |
180 | __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >; |
181 | |
182 | template <class _UDel> |
183 | using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = |
184 | __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || |
185 | (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >; |
186 | |
187 | template <class _UDel> |
188 | using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; |
189 | |
190 | public: |
191 | template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > |
192 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} |
193 | |
194 | template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > |
195 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT |
196 | : __ptr_(__value_init_tag(), __value_init_tag()) {} |
197 | |
198 | template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > |
199 | _LIBCPP_HIDE_FROM_ABI |
200 | _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} |
201 | |
202 | template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > |
203 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT |
204 | : __ptr_(__p, __d) {} |
205 | |
206 | template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > |
207 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT |
208 | : __ptr_(__p, std::move(__d)) { |
209 | static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference" ); |
210 | } |
211 | |
212 | template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > > |
213 | _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; |
214 | |
215 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT |
216 | : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} |
217 | |
218 | template <class _Up, |
219 | class _Ep, |
220 | class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, |
221 | class = _EnableIfDeleterConvertible<_Ep> > |
222 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT |
223 | : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} |
224 | |
225 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
226 | template <class _Up, |
227 | __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0> |
228 | _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release(), __value_init_tag()) {} |
229 | #endif |
230 | |
231 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { |
232 | reset(__u.release()); |
233 | __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); |
234 | return *this; |
235 | } |
236 | |
237 | template <class _Up, |
238 | class _Ep, |
239 | class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, |
240 | class = _EnableIfDeleterAssignable<_Ep> > |
241 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { |
242 | reset(__u.release()); |
243 | __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); |
244 | return *this; |
245 | } |
246 | |
247 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
248 | template <class _Up, |
249 | __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0> |
250 | _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) { |
251 | reset(__p.release()); |
252 | return *this; |
253 | } |
254 | #endif |
255 | |
256 | #ifdef _LIBCPP_CXX03_LANG |
257 | unique_ptr(unique_ptr const&) = delete; |
258 | unique_ptr& operator=(unique_ptr const&) = delete; |
259 | #endif |
260 | |
261 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } |
262 | |
263 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { |
264 | reset(); |
265 | return *this; |
266 | } |
267 | |
268 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const |
269 | _NOEXCEPT_(__is_noexcept_deref_or_void<pointer>::value) { |
270 | return *__ptr_.first(); |
271 | } |
272 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_.first(); } |
273 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } |
274 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } |
275 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { |
276 | return __ptr_.second(); |
277 | } |
278 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { |
279 | return __ptr_.first() != nullptr; |
280 | } |
281 | |
282 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { |
283 | pointer __t = __ptr_.first(); |
284 | __ptr_.first() = pointer(); |
285 | return __t; |
286 | } |
287 | |
288 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT { |
289 | pointer __tmp = __ptr_.first(); |
290 | __ptr_.first() = __p; |
291 | if (__tmp) |
292 | __ptr_.second()(__tmp); |
293 | } |
294 | |
295 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } |
296 | }; |
297 | |
298 | template <class _Tp, class _Dp> |
299 | class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { |
300 | public: |
301 | typedef _Tp element_type; |
302 | typedef _Dp deleter_type; |
303 | typedef typename __pointer<_Tp, deleter_type>::type pointer; |
304 | |
305 | // A unique_ptr contains the following members which may be trivially relocatable: |
306 | // - pointer : this may be trivially relocatable, so it's checked |
307 | // - deleter_type: this may be trivially relocatable, so it's checked |
308 | // |
309 | // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no |
310 | // references to itself. This means that the entire structure is trivially relocatable if its members are. |
311 | using __trivially_relocatable = __conditional_t< |
312 | __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, |
313 | unique_ptr, |
314 | void>; |
315 | |
316 | private: |
317 | __compressed_pair<pointer, deleter_type> __ptr_; |
318 | |
319 | template <class _From> |
320 | struct _CheckArrayPointerConversion : is_same<_From, pointer> {}; |
321 | |
322 | template <class _FromElem> |
323 | struct _CheckArrayPointerConversion<_FromElem*> |
324 | : integral_constant<bool, |
325 | is_same<_FromElem*, pointer>::value || |
326 | (is_same<pointer, element_type*>::value && |
327 | is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {}; |
328 | |
329 | typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; |
330 | |
331 | template <bool _Dummy> |
332 | using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; |
333 | |
334 | template <bool _Dummy> |
335 | using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; |
336 | |
337 | template <bool _Dummy> |
338 | using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; |
339 | |
340 | template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type> |
341 | using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = |
342 | __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>; |
343 | |
344 | template <class _ArgType> |
345 | using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; |
346 | |
347 | template <class _Pp> |
348 | using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >; |
349 | |
350 | template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type> |
351 | using _EnableIfMoveConvertible _LIBCPP_NODEBUG = |
352 | __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value && |
353 | is_same<typename _UPtr::pointer, _ElemT*>::value && |
354 | is_convertible<_ElemT (*)[], element_type (*)[]>::value >; |
355 | |
356 | template <class _UDel> |
357 | using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = |
358 | __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || |
359 | (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >; |
360 | |
361 | template <class _UDel> |
362 | using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; |
363 | |
364 | public: |
365 | template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > |
366 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} |
367 | |
368 | template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > |
369 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT |
370 | : __ptr_(__value_init_tag(), __value_init_tag()) {} |
371 | |
372 | template <class _Pp, |
373 | bool _Dummy = true, |
374 | class = _EnableIfDeleterDefaultConstructible<_Dummy>, |
375 | class = _EnableIfPointerConvertible<_Pp> > |
376 | _LIBCPP_HIDE_FROM_ABI |
377 | _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} |
378 | |
379 | template <class _Pp, |
380 | bool _Dummy = true, |
381 | class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >, |
382 | class = _EnableIfPointerConvertible<_Pp> > |
383 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT |
384 | : __ptr_(__p, __d) {} |
385 | |
386 | template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > |
387 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT |
388 | : __ptr_(nullptr, __d) {} |
389 | |
390 | template <class _Pp, |
391 | bool _Dummy = true, |
392 | class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >, |
393 | class = _EnableIfPointerConvertible<_Pp> > |
394 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT |
395 | : __ptr_(__p, std::move(__d)) { |
396 | static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference" ); |
397 | } |
398 | |
399 | template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > |
400 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT |
401 | : __ptr_(nullptr, std::move(__d)) { |
402 | static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference" ); |
403 | } |
404 | |
405 | template <class _Pp, |
406 | bool _Dummy = true, |
407 | class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >, |
408 | class = _EnableIfPointerConvertible<_Pp> > |
409 | _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; |
410 | |
411 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT |
412 | : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} |
413 | |
414 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { |
415 | reset(__u.release()); |
416 | __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); |
417 | return *this; |
418 | } |
419 | |
420 | template <class _Up, |
421 | class _Ep, |
422 | class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, |
423 | class = _EnableIfDeleterConvertible<_Ep> > |
424 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT |
425 | : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} |
426 | |
427 | template <class _Up, |
428 | class _Ep, |
429 | class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, |
430 | class = _EnableIfDeleterAssignable<_Ep> > |
431 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { |
432 | reset(__u.release()); |
433 | __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); |
434 | return *this; |
435 | } |
436 | |
437 | #ifdef _LIBCPP_CXX03_LANG |
438 | unique_ptr(unique_ptr const&) = delete; |
439 | unique_ptr& operator=(unique_ptr const&) = delete; |
440 | #endif |
441 | |
442 | public: |
443 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } |
444 | |
445 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { |
446 | reset(); |
447 | return *this; |
448 | } |
449 | |
450 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const { |
451 | return __ptr_.first()[__i]; |
452 | } |
453 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } |
454 | |
455 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } |
456 | |
457 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { |
458 | return __ptr_.second(); |
459 | } |
460 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { |
461 | return __ptr_.first() != nullptr; |
462 | } |
463 | |
464 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { |
465 | pointer __t = __ptr_.first(); |
466 | __ptr_.first() = pointer(); |
467 | return __t; |
468 | } |
469 | |
470 | template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0> |
471 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(_Pp __p) _NOEXCEPT { |
472 | pointer __tmp = __ptr_.first(); |
473 | __ptr_.first() = __p; |
474 | if (__tmp) |
475 | __ptr_.second()(__tmp); |
476 | } |
477 | |
478 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { |
479 | pointer __tmp = __ptr_.first(); |
480 | __ptr_.first() = nullptr; |
481 | if (__tmp) |
482 | __ptr_.second()(__tmp); |
483 | } |
484 | |
485 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } |
486 | }; |
487 | |
488 | template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0> |
489 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void |
490 | swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { |
491 | __x.swap(__y); |
492 | } |
493 | |
494 | template <class _T1, class _D1, class _T2, class _D2> |
495 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool |
496 | operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
497 | return __x.get() == __y.get(); |
498 | } |
499 | |
500 | #if _LIBCPP_STD_VER <= 17 |
501 | template <class _T1, class _D1, class _T2, class _D2> |
502 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
503 | return !(__x == __y); |
504 | } |
505 | #endif |
506 | |
507 | template <class _T1, class _D1, class _T2, class _D2> |
508 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
509 | typedef typename unique_ptr<_T1, _D1>::pointer _P1; |
510 | typedef typename unique_ptr<_T2, _D2>::pointer _P2; |
511 | typedef typename common_type<_P1, _P2>::type _Vp; |
512 | return less<_Vp>()(__x.get(), __y.get()); |
513 | } |
514 | |
515 | template <class _T1, class _D1, class _T2, class _D2> |
516 | inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
517 | return __y < __x; |
518 | } |
519 | |
520 | template <class _T1, class _D1, class _T2, class _D2> |
521 | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
522 | return !(__y < __x); |
523 | } |
524 | |
525 | template <class _T1, class _D1, class _T2, class _D2> |
526 | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
527 | return !(__x < __y); |
528 | } |
529 | |
530 | #if _LIBCPP_STD_VER >= 20 |
531 | template <class _T1, class _D1, class _T2, class _D2> |
532 | requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer> |
533 | _LIBCPP_HIDE_FROM_ABI |
534 | compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer> |
535 | operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { |
536 | return compare_three_way()(__x.get(), __y.get()); |
537 | } |
538 | #endif |
539 | |
540 | template <class _T1, class _D1> |
541 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool |
542 | operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { |
543 | return !__x; |
544 | } |
545 | |
546 | #if _LIBCPP_STD_VER <= 17 |
547 | template <class _T1, class _D1> |
548 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { |
549 | return !__x; |
550 | } |
551 | |
552 | template <class _T1, class _D1> |
553 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { |
554 | return static_cast<bool>(__x); |
555 | } |
556 | |
557 | template <class _T1, class _D1> |
558 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { |
559 | return static_cast<bool>(__x); |
560 | } |
561 | #endif // _LIBCPP_STD_VER <= 17 |
562 | |
563 | template <class _T1, class _D1> |
564 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
565 | typedef typename unique_ptr<_T1, _D1>::pointer _P1; |
566 | return less<_P1>()(__x.get(), nullptr); |
567 | } |
568 | |
569 | template <class _T1, class _D1> |
570 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { |
571 | typedef typename unique_ptr<_T1, _D1>::pointer _P1; |
572 | return less<_P1>()(nullptr, __x.get()); |
573 | } |
574 | |
575 | template <class _T1, class _D1> |
576 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
577 | return nullptr < __x; |
578 | } |
579 | |
580 | template <class _T1, class _D1> |
581 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { |
582 | return __x < nullptr; |
583 | } |
584 | |
585 | template <class _T1, class _D1> |
586 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
587 | return !(nullptr < __x); |
588 | } |
589 | |
590 | template <class _T1, class _D1> |
591 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { |
592 | return !(__x < nullptr); |
593 | } |
594 | |
595 | template <class _T1, class _D1> |
596 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
597 | return !(__x < nullptr); |
598 | } |
599 | |
600 | template <class _T1, class _D1> |
601 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { |
602 | return !(nullptr < __x); |
603 | } |
604 | |
605 | #if _LIBCPP_STD_VER >= 20 |
606 | template <class _T1, class _D1> |
607 | requires three_way_comparable< typename unique_ptr<_T1, _D1>::pointer> |
608 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> |
609 | operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
610 | return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr)); |
611 | } |
612 | #endif |
613 | |
614 | #if _LIBCPP_STD_VER >= 14 |
615 | |
616 | template <class _Tp> |
617 | struct __unique_if { |
618 | typedef unique_ptr<_Tp> __unique_single; |
619 | }; |
620 | |
621 | template <class _Tp> |
622 | struct __unique_if<_Tp[]> { |
623 | typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; |
624 | }; |
625 | |
626 | template <class _Tp, size_t _Np> |
627 | struct __unique_if<_Tp[_Np]> { |
628 | typedef void __unique_array_known_bound; |
629 | }; |
630 | |
631 | template <class _Tp, class... _Args> |
632 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single |
633 | make_unique(_Args&&... __args) { |
634 | return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); |
635 | } |
636 | |
637 | template <class _Tp> |
638 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound |
639 | make_unique(size_t __n) { |
640 | typedef __remove_extent_t<_Tp> _Up; |
641 | return unique_ptr<_Tp>(new _Up[__n]()); |
642 | } |
643 | |
644 | template <class _Tp, class... _Args> |
645 | typename __unique_if<_Tp>::__unique_array_known_bound make_unique(_Args&&...) = delete; |
646 | |
647 | #endif // _LIBCPP_STD_VER >= 14 |
648 | |
649 | #if _LIBCPP_STD_VER >= 20 |
650 | |
651 | template <class _Tp> |
652 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single |
653 | make_unique_for_overwrite() { |
654 | return unique_ptr<_Tp>(new _Tp); |
655 | } |
656 | |
657 | template <class _Tp> |
658 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound |
659 | make_unique_for_overwrite(size_t __n) { |
660 | return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); |
661 | } |
662 | |
663 | template <class _Tp, class... _Args> |
664 | typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; |
665 | |
666 | #endif // _LIBCPP_STD_VER >= 20 |
667 | |
668 | template <class _Tp> |
669 | struct _LIBCPP_TEMPLATE_VIS hash; |
670 | |
671 | template <class _Tp, class _Dp> |
672 | #ifdef _LIBCPP_CXX03_LANG |
673 | struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > |
674 | #else |
675 | struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > |
676 | #endif |
677 | { |
678 | #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) |
679 | _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; |
680 | _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; |
681 | #endif |
682 | |
683 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { |
684 | typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; |
685 | return hash<pointer>()(__ptr.get()); |
686 | } |
687 | }; |
688 | |
689 | _LIBCPP_END_NAMESPACE_STD |
690 | |
691 | _LIBCPP_POP_MACROS |
692 | |
693 | #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H |
694 | |