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