xref: /freebsd/contrib/llvm-project/libcxx/include/__memory/unique_ptr.h (revision a50d73d5782a351ad83e8d1f84d11720a12e70d3)
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 
30 template <class _Tp>
31 struct _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 
52 template <class _Tp>
53 struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
54 private:
55   template <class _Up>
56   struct _EnableIfConvertible
57       : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
58 
59 public:
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 
80 template <class _Deleter>
81 struct __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 
88 template <class _Deleter>
89 struct __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 
95 template <class _Deleter>
96 struct __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 
108 template <class _Tp, class _Dp = default_delete<_Tp> >
109 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
110 public:
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 
118 private:
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 
164 public:
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(__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(__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 
315 template <class _Tp, class _Dp>
316 class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
317 public:
318   typedef _Tp element_type;
319   typedef _Dp deleter_type;
320   typedef typename __pointer<_Tp, deleter_type>::type pointer;
321 
322 private:
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 
386 public:
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
479 public:
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 
547 template <class _Tp, class _Dp>
548 inline _LIBCPP_INLINE_VISIBILITY
549 typename enable_if<
550     __is_swappable<_Dp>::value,
551     void
552 >::type
553 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
554 
555 template <class _T1, class _D1, class _T2, class _D2>
556 inline _LIBCPP_INLINE_VISIBILITY
557 bool
558 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
559 
560 template <class _T1, class _D1, class _T2, class _D2>
561 inline _LIBCPP_INLINE_VISIBILITY
562 bool
563 operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
564 
565 template <class _T1, class _D1, class _T2, class _D2>
566 inline _LIBCPP_INLINE_VISIBILITY
567 bool
568 operator< (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 
576 template <class _T1, class _D1, class _T2, class _D2>
577 inline _LIBCPP_INLINE_VISIBILITY
578 bool
579 operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
580 
581 template <class _T1, class _D1, class _T2, class _D2>
582 inline _LIBCPP_INLINE_VISIBILITY
583 bool
584 operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
585 
586 template <class _T1, class _D1, class _T2, class _D2>
587 inline _LIBCPP_INLINE_VISIBILITY
588 bool
589 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
590 
591 template <class _T1, class _D1>
592 inline _LIBCPP_INLINE_VISIBILITY
593 bool
594 operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
595 {
596     return !__x;
597 }
598 
599 template <class _T1, class _D1>
600 inline _LIBCPP_INLINE_VISIBILITY
601 bool
602 operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
603 {
604     return !__x;
605 }
606 
607 template <class _T1, class _D1>
608 inline _LIBCPP_INLINE_VISIBILITY
609 bool
610 operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
611 {
612     return static_cast<bool>(__x);
613 }
614 
615 template <class _T1, class _D1>
616 inline _LIBCPP_INLINE_VISIBILITY
617 bool
618 operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
619 {
620     return static_cast<bool>(__x);
621 }
622 
623 template <class _T1, class _D1>
624 inline _LIBCPP_INLINE_VISIBILITY
625 bool
626 operator<(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 
632 template <class _T1, class _D1>
633 inline _LIBCPP_INLINE_VISIBILITY
634 bool
635 operator<(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 
641 template <class _T1, class _D1>
642 inline _LIBCPP_INLINE_VISIBILITY
643 bool
644 operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
645 {
646     return nullptr < __x;
647 }
648 
649 template <class _T1, class _D1>
650 inline _LIBCPP_INLINE_VISIBILITY
651 bool
652 operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
653 {
654     return __x < nullptr;
655 }
656 
657 template <class _T1, class _D1>
658 inline _LIBCPP_INLINE_VISIBILITY
659 bool
660 operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
661 {
662     return !(nullptr < __x);
663 }
664 
665 template <class _T1, class _D1>
666 inline _LIBCPP_INLINE_VISIBILITY
667 bool
668 operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
669 {
670     return !(__x < nullptr);
671 }
672 
673 template <class _T1, class _D1>
674 inline _LIBCPP_INLINE_VISIBILITY
675 bool
676 operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
677 {
678     return !(__x < nullptr);
679 }
680 
681 template <class _T1, class _D1>
682 inline _LIBCPP_INLINE_VISIBILITY
683 bool
684 operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
685 {
686     return !(nullptr < __x);
687 }
688 
689 #if _LIBCPP_STD_VER > 11
690 
691 template<class _Tp>
692 struct __unique_if
693 {
694     typedef unique_ptr<_Tp> __unique_single;
695 };
696 
697 template<class _Tp>
698 struct __unique_if<_Tp[]>
699 {
700     typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
701 };
702 
703 template<class _Tp, size_t _Np>
704 struct __unique_if<_Tp[_Np]>
705 {
706     typedef void __unique_array_known_bound;
707 };
708 
709 template<class _Tp, class... _Args>
710 inline _LIBCPP_INLINE_VISIBILITY
711 typename __unique_if<_Tp>::__unique_single
712 make_unique(_Args&&... __args)
713 {
714     return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
715 }
716 
717 template<class _Tp>
718 inline _LIBCPP_INLINE_VISIBILITY
719 typename __unique_if<_Tp>::__unique_array_unknown_bound
720 make_unique(size_t __n)
721 {
722     typedef typename remove_extent<_Tp>::type _Up;
723     return unique_ptr<_Tp>(new _Up[__n]());
724 }
725 
726 template<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 
732 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
733 
734 template <class _Tp, class _Dp>
735 #ifdef _LIBCPP_CXX03_LANG
736 struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
737 #else
738 struct _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