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