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

source code of flutter_engine/third_party/libcxx/include/__memory/unique_ptr.h