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