brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.1 KiB · 2a9b330 Raw
554 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H11#define _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H12 13#include <__cxx03/__config>14#include <__cxx03/__functional/hash.h>15#include <__cxx03/__functional/operations.h>16#include <__cxx03/__memory/allocator_traits.h> // __pointer17#include <__cxx03/__memory/auto_ptr.h>18#include <__cxx03/__memory/compressed_pair.h>19#include <__cxx03/__type_traits/add_lvalue_reference.h>20#include <__cxx03/__type_traits/common_type.h>21#include <__cxx03/__type_traits/conditional.h>22#include <__cxx03/__type_traits/dependent_type.h>23#include <__cxx03/__type_traits/integral_constant.h>24#include <__cxx03/__type_traits/is_array.h>25#include <__cxx03/__type_traits/is_assignable.h>26#include <__cxx03/__type_traits/is_constructible.h>27#include <__cxx03/__type_traits/is_convertible.h>28#include <__cxx03/__type_traits/is_function.h>29#include <__cxx03/__type_traits/is_pointer.h>30#include <__cxx03/__type_traits/is_reference.h>31#include <__cxx03/__type_traits/is_same.h>32#include <__cxx03/__type_traits/is_swappable.h>33#include <__cxx03/__type_traits/is_trivially_relocatable.h>34#include <__cxx03/__type_traits/is_void.h>35#include <__cxx03/__type_traits/remove_extent.h>36#include <__cxx03/__type_traits/remove_pointer.h>37#include <__cxx03/__type_traits/type_identity.h>38#include <__cxx03/__utility/declval.h>39#include <__cxx03/__utility/forward.h>40#include <__cxx03/__utility/move.h>41#include <__cxx03/cstddef>42 43#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)44#  pragma GCC system_header45#endif46 47_LIBCPP_PUSH_MACROS48#include <__cxx03/__undef_macros>49 50_LIBCPP_BEGIN_NAMESPACE_STD51 52template <class _Tp>53struct _LIBCPP_TEMPLATE_VIS default_delete {54  static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types");55  _LIBCPP_HIDE_FROM_ABI default_delete() {}56  template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0>57  _LIBCPP_HIDE_FROM_ABI default_delete(const default_delete<_Up>&) _NOEXCEPT {}58 59  _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __ptr) const _NOEXCEPT {60    static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");61    static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");62    delete __ptr;63  }64};65 66template <class _Tp>67struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {68private:69  template <class _Up>70  struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {};71 72public:73  _LIBCPP_HIDE_FROM_ABI default_delete() {}74 75  template <class _Up>76  _LIBCPP_HIDE_FROM_ABI77  default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}78 79  template <class _Up>80  _LIBCPP_HIDE_FROM_ABI typename _EnableIfConvertible<_Up>::type operator()(_Up* __ptr) const _NOEXCEPT {81    static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");82    delete[] __ptr;83  }84};85 86template <class _Deleter>87struct __unique_ptr_deleter_sfinae {88  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");89  typedef const _Deleter& __lval_ref_type;90  typedef _Deleter&& __good_rval_ref_type;91  typedef true_type __enable_rval_overload;92};93 94template <class _Deleter>95struct __unique_ptr_deleter_sfinae<_Deleter const&> {96  typedef const _Deleter& __lval_ref_type;97  typedef const _Deleter&& __bad_rval_ref_type;98  typedef false_type __enable_rval_overload;99};100 101template <class _Deleter>102struct __unique_ptr_deleter_sfinae<_Deleter&> {103  typedef _Deleter& __lval_ref_type;104  typedef _Deleter&& __bad_rval_ref_type;105  typedef false_type __enable_rval_overload;106};107 108#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)109#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))110#else111#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI112#endif113 114template <class _Tp, class _Dp = default_delete<_Tp> >115class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {116public:117  typedef _Tp element_type;118  typedef _Dp deleter_type;119  typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer;120 121  static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference");122 123  // A unique_ptr contains the following members which may be trivially relocatable:124  // - pointer : this may be trivially relocatable, so it's checked125  // - deleter_type: this may be trivially relocatable, so it's checked126  //127  // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no128  // references to itself. This means that the entire structure is trivially relocatable if its members are.129  using __trivially_relocatable = __conditional_t<130      __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,131      unique_ptr,132      void>;133 134private:135  __compressed_pair<pointer, deleter_type> __ptr_;136 137  typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;138 139  template <bool _Dummy>140  using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;141 142  template <bool _Dummy>143  using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;144 145  template <bool _Dummy>146  using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;147 148  template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>149  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =150      __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;151 152  template <class _ArgType>153  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;154 155  template <class _UPtr, class _Up>156  using _EnableIfMoveConvertible _LIBCPP_NODEBUG =157      __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >;158 159  template <class _UDel>160  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =161      __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||162                     (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;163 164  template <class _UDel>165  using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;166 167public:168  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >169  _LIBCPP_HIDE_FROM_ABI unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}170 171  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >172  _LIBCPP_HIDE_FROM_ABI unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}173 174  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >175  _LIBCPP_HIDE_FROM_ABI explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {}176 177  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >178  _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {}179 180  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >181  _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, std::move(__d)) {182    static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");183  }184 185  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >186  _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;187 188  _LIBCPP_HIDE_FROM_ABI unique_ptr(unique_ptr&& __u) _NOEXCEPT189      : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {}190 191  template <class _Up,192            class _Ep,193            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,194            class = _EnableIfDeleterConvertible<_Ep> >195  _LIBCPP_HIDE_FROM_ABI unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT196      : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {}197 198  template <class _Up,199            __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>200  _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release(), __value_init_tag()) {}201 202  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {203    reset(__u.release());204    __ptr_.second() = std::forward<deleter_type>(__u.get_deleter());205    return *this;206  }207 208  template <class _Up,209            class _Ep,210            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,211            class = _EnableIfDeleterAssignable<_Ep> >212  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {213    reset(__u.release());214    __ptr_.second() = std::forward<_Ep>(__u.get_deleter());215    return *this;216  }217 218  template <class _Up,219            __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0>220  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) {221    reset(__p.release());222    return *this;223  }224 225  unique_ptr(unique_ptr const&)            = delete;226  unique_ptr& operator=(unique_ptr const&) = delete;227 228  _LIBCPP_HIDE_FROM_ABI ~unique_ptr() { reset(); }229 230  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(nullptr_t) _NOEXCEPT {231    reset();232    return *this;233  }234 235  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Tp> operator*() const { return *__ptr_.first(); }236  _LIBCPP_HIDE_FROM_ABI pointer operator->() const _NOEXCEPT { return __ptr_.first(); }237  _LIBCPP_HIDE_FROM_ABI pointer get() const _NOEXCEPT { return __ptr_.first(); }238  _LIBCPP_HIDE_FROM_ABI deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); }239  _LIBCPP_HIDE_FROM_ABI const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); }240  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; }241 242  _LIBCPP_HIDE_FROM_ABI pointer release() _NOEXCEPT {243    pointer __t    = __ptr_.first();244    __ptr_.first() = pointer();245    return __t;246  }247 248  _LIBCPP_HIDE_FROM_ABI void reset(pointer __p = pointer()) _NOEXCEPT {249    pointer __tmp  = __ptr_.first();250    __ptr_.first() = __p;251    if (__tmp)252      __ptr_.second()(__tmp);253  }254 255  _LIBCPP_HIDE_FROM_ABI void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); }256};257 258template <class _Tp, class _Dp>259class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {260public:261  typedef _Tp element_type;262  typedef _Dp deleter_type;263  typedef typename __pointer<_Tp, deleter_type>::type pointer;264 265  // A unique_ptr contains the following members which may be trivially relocatable:266  // - pointer : this may be trivially relocatable, so it's checked267  // - deleter_type: this may be trivially relocatable, so it's checked268  //269  // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no270  // references to itself. This means that the entire structure is trivially relocatable if its members are.271  using __trivially_relocatable = __conditional_t<272      __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,273      unique_ptr,274      void>;275 276private:277  __compressed_pair<pointer, deleter_type> __ptr_;278 279  template <class _From>280  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};281 282  template <class _FromElem>283  struct _CheckArrayPointerConversion<_FromElem*>284      : integral_constant<bool,285                          is_same<_FromElem*, pointer>::value ||286                              (is_same<pointer, element_type*>::value &&287                               is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {};288 289  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;290 291  template <bool _Dummy>292  using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;293 294  template <bool _Dummy>295  using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;296 297  template <bool _Dummy>298  using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;299 300  template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type>301  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG =302      __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>;303 304  template <class _ArgType>305  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>;306 307  template <class _Pp>308  using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >;309 310  template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type>311  using _EnableIfMoveConvertible _LIBCPP_NODEBUG =312      __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value &&313                     is_same<typename _UPtr::pointer, _ElemT*>::value &&314                     is_convertible<_ElemT (*)[], element_type (*)[]>::value >;315 316  template <class _UDel>317  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG =318      __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||319                     (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >;320 321  template <class _UDel>322  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >;323 324public:325  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >326  _LIBCPP_HIDE_FROM_ABI unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}327 328  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >329  _LIBCPP_HIDE_FROM_ABI unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}330 331  template <class _Pp,332            bool _Dummy = true,333            class       = _EnableIfDeleterDefaultConstructible<_Dummy>,334            class       = _EnableIfPointerConvertible<_Pp> >335  _LIBCPP_HIDE_FROM_ABI explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {}336 337  template <class _Pp,338            bool _Dummy = true,339            class       = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,340            class       = _EnableIfPointerConvertible<_Pp> >341  _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {}342 343  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >344  _LIBCPP_HIDE_FROM_ABI unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, __d) {}345 346  template <class _Pp,347            bool _Dummy = true,348            class       = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,349            class       = _EnableIfPointerConvertible<_Pp> >350  _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, std::move(__d)) {351    static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");352  }353 354  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >355  _LIBCPP_HIDE_FROM_ABI unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT356      : __ptr_(nullptr, std::move(__d)) {357    static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");358  }359 360  template <class _Pp,361            bool _Dummy = true,362            class       = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,363            class       = _EnableIfPointerConvertible<_Pp> >364  _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;365 366  _LIBCPP_HIDE_FROM_ABI unique_ptr(unique_ptr&& __u) _NOEXCEPT367      : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {}368 369  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {370    reset(__u.release());371    __ptr_.second() = std::forward<deleter_type>(__u.get_deleter());372    return *this;373  }374 375  template <class _Up,376            class _Ep,377            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,378            class = _EnableIfDeleterConvertible<_Ep> >379  _LIBCPP_HIDE_FROM_ABI unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT380      : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {}381 382  template <class _Up,383            class _Ep,384            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,385            class = _EnableIfDeleterAssignable<_Ep> >386  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {387    reset(__u.release());388    __ptr_.second() = std::forward<_Ep>(__u.get_deleter());389    return *this;390  }391 392  unique_ptr(unique_ptr const&)            = delete;393  unique_ptr& operator=(unique_ptr const&) = delete;394 395public:396  _LIBCPP_HIDE_FROM_ABI ~unique_ptr() { reset(); }397 398  _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(nullptr_t) _NOEXCEPT {399    reset();400    return *this;401  }402 403  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Tp> operator[](size_t __i) const { return __ptr_.first()[__i]; }404  _LIBCPP_HIDE_FROM_ABI pointer get() const _NOEXCEPT { return __ptr_.first(); }405 406  _LIBCPP_HIDE_FROM_ABI deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); }407 408  _LIBCPP_HIDE_FROM_ABI const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); }409  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; }410 411  _LIBCPP_HIDE_FROM_ABI pointer release() _NOEXCEPT {412    pointer __t    = __ptr_.first();413    __ptr_.first() = pointer();414    return __t;415  }416 417  template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0>418  _LIBCPP_HIDE_FROM_ABI void reset(_Pp __p) _NOEXCEPT {419    pointer __tmp  = __ptr_.first();420    __ptr_.first() = __p;421    if (__tmp)422      __ptr_.second()(__tmp);423  }424 425  _LIBCPP_HIDE_FROM_ABI void reset(nullptr_t = nullptr) _NOEXCEPT {426    pointer __tmp  = __ptr_.first();427    __ptr_.first() = nullptr;428    if (__tmp)429      __ptr_.second()(__tmp);430  }431 432  _LIBCPP_HIDE_FROM_ABI void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); }433};434 435template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0>436inline _LIBCPP_HIDE_FROM_ABI void swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {437  __x.swap(__y);438}439 440template <class _T1, class _D1, class _T2, class _D2>441inline _LIBCPP_HIDE_FROM_ABI bool operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {442  return __x.get() == __y.get();443}444 445template <class _T1, class _D1, class _T2, class _D2>446inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {447  return !(__x == __y);448}449 450template <class _T1, class _D1, class _T2, class _D2>451inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {452  typedef typename unique_ptr<_T1, _D1>::pointer _P1;453  typedef typename unique_ptr<_T2, _D2>::pointer _P2;454  typedef typename common_type<_P1, _P2>::type _Vp;455  return less<_Vp>()(__x.get(), __y.get());456}457 458template <class _T1, class _D1, class _T2, class _D2>459inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {460  return __y < __x;461}462 463template <class _T1, class _D1, class _T2, class _D2>464inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {465  return !(__y < __x);466}467 468template <class _T1, class _D1, class _T2, class _D2>469inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {470  return !(__x < __y);471}472 473template <class _T1, class _D1>474inline _LIBCPP_HIDE_FROM_ABI bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {475  return !__x;476}477 478template <class _T1, class _D1>479inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {480  return !__x;481}482 483template <class _T1, class _D1>484inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {485  return static_cast<bool>(__x);486}487 488template <class _T1, class _D1>489inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT {490  return static_cast<bool>(__x);491}492 493template <class _T1, class _D1>494inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) {495  typedef typename unique_ptr<_T1, _D1>::pointer _P1;496  return less<_P1>()(__x.get(), nullptr);497}498 499template <class _T1, class _D1>500inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) {501  typedef typename unique_ptr<_T1, _D1>::pointer _P1;502  return less<_P1>()(nullptr, __x.get());503}504 505template <class _T1, class _D1>506inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {507  return nullptr < __x;508}509 510template <class _T1, class _D1>511inline _LIBCPP_HIDE_FROM_ABI bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {512  return __x < nullptr;513}514 515template <class _T1, class _D1>516inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {517  return !(nullptr < __x);518}519 520template <class _T1, class _D1>521inline _LIBCPP_HIDE_FROM_ABI bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {522  return !(__x < nullptr);523}524 525template <class _T1, class _D1>526inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {527  return !(__x < nullptr);528}529 530template <class _T1, class _D1>531inline _LIBCPP_HIDE_FROM_ABI bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {532  return !(nullptr < __x);533}534 535template <class _Tp>536struct _LIBCPP_TEMPLATE_VIS hash;537 538template <class _Tp, class _Dp>539struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > {540  typedef unique_ptr<_Tp, _Dp> argument_type;541  typedef size_t result_type;542 543  _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {544    typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;545    return hash<pointer>()(__ptr.get());546  }547};548 549_LIBCPP_END_NAMESPACE_STD550 551_LIBCPP_POP_MACROS552 553#endif // _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H554