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