Home | History | Annotate | Line # | Download | only in __memory
      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
     41   _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 
     49   _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