1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H 11fe6060f1SDimitry Andric #define _LIBCPP___MEMORY_UNIQUE_PTR_H 12fe6060f1SDimitry Andric 13bdd1243dSDimitry Andric #include <__compare/compare_three_way.h> 14bdd1243dSDimitry Andric #include <__compare/compare_three_way_result.h> 15bdd1243dSDimitry Andric #include <__compare/three_way_comparable.h> 16fe6060f1SDimitry Andric #include <__config> 17fe6060f1SDimitry Andric #include <__functional/hash.h> 18fe6060f1SDimitry Andric #include <__functional/operations.h> 19fe6060f1SDimitry Andric #include <__memory/allocator_traits.h> // __pointer 2081ad6265SDimitry Andric #include <__memory/auto_ptr.h> 21fe6060f1SDimitry Andric #include <__memory/compressed_pair.h> 22bdd1243dSDimitry Andric #include <__type_traits/add_lvalue_reference.h> 23bdd1243dSDimitry Andric #include <__type_traits/common_type.h> 24*0fca6ea1SDimitry Andric #include <__type_traits/conditional.h> 25bdd1243dSDimitry Andric #include <__type_traits/dependent_type.h> 26bdd1243dSDimitry Andric #include <__type_traits/integral_constant.h> 27bdd1243dSDimitry Andric #include <__type_traits/is_array.h> 28bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h> 29bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h> 30bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h> 31bdd1243dSDimitry Andric #include <__type_traits/is_function.h> 32bdd1243dSDimitry Andric #include <__type_traits/is_pointer.h> 33bdd1243dSDimitry Andric #include <__type_traits/is_reference.h> 34bdd1243dSDimitry Andric #include <__type_traits/is_same.h> 35bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h> 36*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_relocatable.h> 37bdd1243dSDimitry Andric #include <__type_traits/is_void.h> 38bdd1243dSDimitry Andric #include <__type_traits/remove_extent.h> 39*0fca6ea1SDimitry Andric #include <__type_traits/remove_pointer.h> 40bdd1243dSDimitry Andric #include <__type_traits/type_identity.h> 41*0fca6ea1SDimitry Andric #include <__utility/declval.h> 42fe6060f1SDimitry Andric #include <__utility/forward.h> 4381ad6265SDimitry Andric #include <__utility/move.h> 44fe6060f1SDimitry Andric #include <cstddef> 45fe6060f1SDimitry Andric 46fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 47fe6060f1SDimitry Andric # pragma GCC system_header 48fe6060f1SDimitry Andric #endif 49fe6060f1SDimitry Andric 5006c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 5106c3fb27SDimitry Andric #include <__undef_macros> 5206c3fb27SDimitry Andric 53fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 54fe6060f1SDimitry Andric 55*0fca6ea1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 56*0fca6ea1SDimitry Andric 57*0fca6ea1SDimitry Andric template <class _Ptr> 58*0fca6ea1SDimitry Andric struct __is_noexcept_deref_or_void { 59*0fca6ea1SDimitry Andric static constexpr bool value = noexcept(*std::declval<_Ptr>()); 60*0fca6ea1SDimitry Andric }; 61*0fca6ea1SDimitry Andric 62*0fca6ea1SDimitry Andric template <> 63*0fca6ea1SDimitry Andric struct __is_noexcept_deref_or_void<void*> : true_type {}; 64*0fca6ea1SDimitry Andric #endif 65*0fca6ea1SDimitry Andric 66fe6060f1SDimitry Andric template <class _Tp> 67fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS default_delete { 68cb14a3feSDimitry Andric static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types"); 69fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 705f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; 71fe6060f1SDimitry Andric #else 725f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI default_delete() {} 73fe6060f1SDimitry Andric #endif 745f757f3fSDimitry Andric template <class _Up, __enable_if_t<is_convertible<_Up*, _Tp*>::value, int> = 0> 75cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(const default_delete<_Up>&) _NOEXCEPT {} 76fe6060f1SDimitry Andric 775f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { 7881ad6265SDimitry Andric static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); 7981ad6265SDimitry Andric static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); 80fe6060f1SDimitry Andric delete __ptr; 81fe6060f1SDimitry Andric } 82fe6060f1SDimitry Andric }; 83fe6060f1SDimitry Andric 84fe6060f1SDimitry Andric template <class _Tp> 85fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { 86fe6060f1SDimitry Andric private: 87fe6060f1SDimitry Andric template <class _Up> 88cb14a3feSDimitry Andric struct _EnableIfConvertible : enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value> {}; 89fe6060f1SDimitry Andric 90fe6060f1SDimitry Andric public: 91fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 925f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr default_delete() _NOEXCEPT = default; 93fe6060f1SDimitry Andric #else 945f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI default_delete() {} 95fe6060f1SDimitry Andric #endif 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric template <class _Up> 985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 99bdd1243dSDimitry Andric default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} 100fe6060f1SDimitry Andric 101fe6060f1SDimitry Andric template <class _Up> 1025f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type 103fe6060f1SDimitry Andric operator()(_Up* __ptr) const _NOEXCEPT { 10481ad6265SDimitry Andric static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); 105fe6060f1SDimitry Andric delete[] __ptr; 106fe6060f1SDimitry Andric } 107fe6060f1SDimitry Andric }; 108fe6060f1SDimitry Andric 109fe6060f1SDimitry Andric template <class _Deleter> 110fe6060f1SDimitry Andric struct __unique_ptr_deleter_sfinae { 111fe6060f1SDimitry Andric static_assert(!is_reference<_Deleter>::value, "incorrect specialization"); 112fe6060f1SDimitry Andric typedef const _Deleter& __lval_ref_type; 113fe6060f1SDimitry Andric typedef _Deleter&& __good_rval_ref_type; 114fe6060f1SDimitry Andric typedef true_type __enable_rval_overload; 115fe6060f1SDimitry Andric }; 116fe6060f1SDimitry Andric 117fe6060f1SDimitry Andric template <class _Deleter> 118fe6060f1SDimitry Andric struct __unique_ptr_deleter_sfinae<_Deleter const&> { 119fe6060f1SDimitry Andric typedef const _Deleter& __lval_ref_type; 120fe6060f1SDimitry Andric typedef const _Deleter&& __bad_rval_ref_type; 121fe6060f1SDimitry Andric typedef false_type __enable_rval_overload; 122fe6060f1SDimitry Andric }; 123fe6060f1SDimitry Andric 124fe6060f1SDimitry Andric template <class _Deleter> 125fe6060f1SDimitry Andric struct __unique_ptr_deleter_sfinae<_Deleter&> { 126fe6060f1SDimitry Andric typedef _Deleter& __lval_ref_type; 127fe6060f1SDimitry Andric typedef _Deleter&& __bad_rval_ref_type; 128fe6060f1SDimitry Andric typedef false_type __enable_rval_overload; 129fe6060f1SDimitry Andric }; 130fe6060f1SDimitry Andric 131fe6060f1SDimitry Andric #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI) 13206c3fb27SDimitry Andric # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) 133fe6060f1SDimitry Andric #else 134fe6060f1SDimitry Andric # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI 135fe6060f1SDimitry Andric #endif 136fe6060f1SDimitry Andric 137fe6060f1SDimitry Andric template <class _Tp, class _Dp = default_delete<_Tp> > 138fe6060f1SDimitry Andric class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr { 139fe6060f1SDimitry Andric public: 140fe6060f1SDimitry Andric typedef _Tp element_type; 141fe6060f1SDimitry Andric typedef _Dp deleter_type; 142349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer; 143fe6060f1SDimitry Andric 144cb14a3feSDimitry Andric static_assert(!is_rvalue_reference<deleter_type>::value, "the specified deleter type cannot be an rvalue reference"); 145fe6060f1SDimitry Andric 146*0fca6ea1SDimitry Andric // A unique_ptr contains the following members which may be trivially relocatable: 147*0fca6ea1SDimitry Andric // - pointer : this may be trivially relocatable, so it's checked 148*0fca6ea1SDimitry Andric // - deleter_type: this may be trivially relocatable, so it's checked 149*0fca6ea1SDimitry Andric // 150*0fca6ea1SDimitry Andric // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no 151*0fca6ea1SDimitry Andric // references to itself. This means that the entire structure is trivially relocatable if its members are. 152*0fca6ea1SDimitry Andric using __trivially_relocatable = __conditional_t< 153*0fca6ea1SDimitry Andric __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, 154*0fca6ea1SDimitry Andric unique_ptr, 155*0fca6ea1SDimitry Andric void>; 156*0fca6ea1SDimitry Andric 157fe6060f1SDimitry Andric private: 158fe6060f1SDimitry Andric __compressed_pair<pointer, deleter_type> __ptr_; 159fe6060f1SDimitry Andric 160349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; 161fe6060f1SDimitry Andric 162fe6060f1SDimitry Andric template <bool _Dummy> 163cb14a3feSDimitry Andric using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; 164fe6060f1SDimitry Andric 165fe6060f1SDimitry Andric template <bool _Dummy> 166cb14a3feSDimitry Andric using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; 167fe6060f1SDimitry Andric 168fe6060f1SDimitry Andric template <bool _Dummy> 169cb14a3feSDimitry Andric using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; 170fe6060f1SDimitry Andric 171cb14a3feSDimitry Andric template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type> 172349cc55cSDimitry Andric using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = 173cb14a3feSDimitry Andric __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>; 174fe6060f1SDimitry Andric 175fe6060f1SDimitry Andric template <class _ArgType> 176cb14a3feSDimitry Andric using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric template <class _UPtr, class _Up> 179cb14a3feSDimitry Andric using _EnableIfMoveConvertible _LIBCPP_NODEBUG = 180cb14a3feSDimitry Andric __enable_if_t< is_convertible<typename _UPtr::pointer, pointer>::value && !is_array<_Up>::value >; 181fe6060f1SDimitry Andric 182fe6060f1SDimitry Andric template <class _UDel> 183cb14a3feSDimitry Andric using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = 184cb14a3feSDimitry Andric __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 185cb14a3feSDimitry Andric (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >; 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric template <class _UDel> 188cb14a3feSDimitry Andric using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric public: 191cb14a3feSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 192cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 193fe6060f1SDimitry Andric 194cb14a3feSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 195cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT 196cb14a3feSDimitry Andric : __ptr_(__value_init_tag(), __value_init_tag()) {} 197fe6060f1SDimitry Andric 198bdd1243dSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 199*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 200*0fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} 201fe6060f1SDimitry Andric 202bdd1243dSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > 2035f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT 204fe6060f1SDimitry Andric : __ptr_(__p, __d) {} 205fe6060f1SDimitry Andric 206bdd1243dSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > 207cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 208cb14a3feSDimitry Andric : __ptr_(__p, std::move(__d)) { 209cb14a3feSDimitry Andric static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference"); 210fe6060f1SDimitry Andric } 211fe6060f1SDimitry Andric 212cb14a3feSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > > 213cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; 214fe6060f1SDimitry Andric 2155f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 2165f757f3fSDimitry Andric : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} 217fe6060f1SDimitry Andric 218bdd1243dSDimitry Andric template <class _Up, 219bdd1243dSDimitry Andric class _Ep, 220fe6060f1SDimitry Andric class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 221bdd1243dSDimitry Andric class = _EnableIfDeleterConvertible<_Ep> > 2225f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 2235f757f3fSDimitry Andric : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} 224fe6060f1SDimitry Andric 225fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 226cb14a3feSDimitry Andric template <class _Up, 227cb14a3feSDimitry Andric __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0> 228cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI unique_ptr(auto_ptr<_Up>&& __p) _NOEXCEPT : __ptr_(__p.release(), __value_init_tag()) {} 229fe6060f1SDimitry Andric #endif 230fe6060f1SDimitry Andric 2315f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 232fe6060f1SDimitry Andric reset(__u.release()); 2335f757f3fSDimitry Andric __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); 234fe6060f1SDimitry Andric return *this; 235fe6060f1SDimitry Andric } 236fe6060f1SDimitry Andric 237bdd1243dSDimitry Andric template <class _Up, 238bdd1243dSDimitry Andric class _Ep, 239fe6060f1SDimitry Andric class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 240bdd1243dSDimitry Andric class = _EnableIfDeleterAssignable<_Ep> > 2415f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 242fe6060f1SDimitry Andric reset(__u.release()); 2435f757f3fSDimitry Andric __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); 244fe6060f1SDimitry Andric return *this; 245fe6060f1SDimitry Andric } 246fe6060f1SDimitry Andric 247fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 248cb14a3feSDimitry Andric template <class _Up, 249cb14a3feSDimitry Andric __enable_if_t<is_convertible<_Up*, _Tp*>::value && is_same<_Dp, default_delete<_Tp> >::value, int> = 0> 250cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI unique_ptr& operator=(auto_ptr<_Up> __p) { 251fe6060f1SDimitry Andric reset(__p.release()); 252fe6060f1SDimitry Andric return *this; 253fe6060f1SDimitry Andric } 254fe6060f1SDimitry Andric #endif 255fe6060f1SDimitry Andric 256fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 257fe6060f1SDimitry Andric unique_ptr(unique_ptr const&) = delete; 258fe6060f1SDimitry Andric unique_ptr& operator=(unique_ptr const&) = delete; 259fe6060f1SDimitry Andric #endif 260fe6060f1SDimitry Andric 2615f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 262fe6060f1SDimitry Andric 2635f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 264fe6060f1SDimitry Andric reset(); 265fe6060f1SDimitry Andric return *this; 266fe6060f1SDimitry Andric } 267fe6060f1SDimitry Andric 268*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const 269*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_noexcept_deref_or_void<pointer>::value) { 270fe6060f1SDimitry Andric return *__ptr_.first(); 271fe6060f1SDimitry Andric } 272cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_.first(); } 2735f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 274cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } 2755f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 276fe6060f1SDimitry Andric return __ptr_.second(); 277fe6060f1SDimitry Andric } 2785f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 279fe6060f1SDimitry Andric return __ptr_.first() != nullptr; 280fe6060f1SDimitry Andric } 281fe6060f1SDimitry Andric 2825f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { 283fe6060f1SDimitry Andric pointer __t = __ptr_.first(); 284fe6060f1SDimitry Andric __ptr_.first() = pointer(); 285fe6060f1SDimitry Andric return __t; 286fe6060f1SDimitry Andric } 287fe6060f1SDimitry Andric 2885f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT { 289fe6060f1SDimitry Andric pointer __tmp = __ptr_.first(); 290fe6060f1SDimitry Andric __ptr_.first() = __p; 291fe6060f1SDimitry Andric if (__tmp) 292fe6060f1SDimitry Andric __ptr_.second()(__tmp); 293fe6060f1SDimitry Andric } 294fe6060f1SDimitry Andric 295cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } 296fe6060f1SDimitry Andric }; 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric template <class _Tp, class _Dp> 299fe6060f1SDimitry Andric class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { 300fe6060f1SDimitry Andric public: 301fe6060f1SDimitry Andric typedef _Tp element_type; 302fe6060f1SDimitry Andric typedef _Dp deleter_type; 303fe6060f1SDimitry Andric typedef typename __pointer<_Tp, deleter_type>::type pointer; 304fe6060f1SDimitry Andric 305*0fca6ea1SDimitry Andric // A unique_ptr contains the following members which may be trivially relocatable: 306*0fca6ea1SDimitry Andric // - pointer : this may be trivially relocatable, so it's checked 307*0fca6ea1SDimitry Andric // - deleter_type: this may be trivially relocatable, so it's checked 308*0fca6ea1SDimitry Andric // 309*0fca6ea1SDimitry Andric // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no 310*0fca6ea1SDimitry Andric // references to itself. This means that the entire structure is trivially relocatable if its members are. 311*0fca6ea1SDimitry Andric using __trivially_relocatable = __conditional_t< 312*0fca6ea1SDimitry Andric __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, 313*0fca6ea1SDimitry Andric unique_ptr, 314*0fca6ea1SDimitry Andric void>; 315*0fca6ea1SDimitry Andric 316fe6060f1SDimitry Andric private: 317fe6060f1SDimitry Andric __compressed_pair<pointer, deleter_type> __ptr_; 318fe6060f1SDimitry Andric 319fe6060f1SDimitry Andric template <class _From> 320fe6060f1SDimitry Andric struct _CheckArrayPointerConversion : is_same<_From, pointer> {}; 321fe6060f1SDimitry Andric 322fe6060f1SDimitry Andric template <class _FromElem> 323fe6060f1SDimitry Andric struct _CheckArrayPointerConversion<_FromElem*> 324fe6060f1SDimitry Andric : integral_constant<bool, 325fe6060f1SDimitry Andric is_same<_FromElem*, pointer>::value || 326fe6060f1SDimitry Andric (is_same<pointer, element_type*>::value && 327cb14a3feSDimitry Andric is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {}; 328fe6060f1SDimitry Andric 329fe6060f1SDimitry Andric typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; 330fe6060f1SDimitry Andric 331fe6060f1SDimitry Andric template <bool _Dummy> 332cb14a3feSDimitry Andric using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; 333fe6060f1SDimitry Andric 334fe6060f1SDimitry Andric template <bool _Dummy> 335cb14a3feSDimitry Andric using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; 336fe6060f1SDimitry Andric 337fe6060f1SDimitry Andric template <bool _Dummy> 338cb14a3feSDimitry Andric using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; 339fe6060f1SDimitry Andric 340cb14a3feSDimitry Andric template <bool _Dummy, class _Deleter = typename __dependent_type< __type_identity<deleter_type>, _Dummy>::type> 341349cc55cSDimitry Andric using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = 342cb14a3feSDimitry Andric __enable_if_t<is_default_constructible<_Deleter>::value && !is_pointer<_Deleter>::value>; 343fe6060f1SDimitry Andric 344fe6060f1SDimitry Andric template <class _ArgType> 345cb14a3feSDimitry Andric using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = __enable_if_t<is_constructible<deleter_type, _ArgType>::value>; 346fe6060f1SDimitry Andric 347fe6060f1SDimitry Andric template <class _Pp> 348cb14a3feSDimitry Andric using _EnableIfPointerConvertible _LIBCPP_NODEBUG = __enable_if_t< _CheckArrayPointerConversion<_Pp>::value >; 349fe6060f1SDimitry Andric 350cb14a3feSDimitry Andric template <class _UPtr, class _Up, class _ElemT = typename _UPtr::element_type> 351cb14a3feSDimitry Andric using _EnableIfMoveConvertible _LIBCPP_NODEBUG = 352cb14a3feSDimitry Andric __enable_if_t< is_array<_Up>::value && is_same<pointer, element_type*>::value && 353fe6060f1SDimitry Andric is_same<typename _UPtr::pointer, _ElemT*>::value && 354cb14a3feSDimitry Andric is_convertible<_ElemT (*)[], element_type (*)[]>::value >; 355fe6060f1SDimitry Andric 356fe6060f1SDimitry Andric template <class _UDel> 357cb14a3feSDimitry Andric using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = 358cb14a3feSDimitry Andric __enable_if_t< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || 359cb14a3feSDimitry Andric (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >; 360fe6060f1SDimitry Andric 361fe6060f1SDimitry Andric template <class _UDel> 362cb14a3feSDimitry Andric using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; 363fe6060f1SDimitry Andric 364fe6060f1SDimitry Andric public: 365cb14a3feSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 366cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} 367fe6060f1SDimitry Andric 368cb14a3feSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > 369cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT 370cb14a3feSDimitry Andric : __ptr_(__value_init_tag(), __value_init_tag()) {} 371fe6060f1SDimitry Andric 372bdd1243dSDimitry Andric template <class _Pp, 373bdd1243dSDimitry Andric bool _Dummy = true, 374fe6060f1SDimitry Andric class = _EnableIfDeleterDefaultConstructible<_Dummy>, 375fe6060f1SDimitry Andric class = _EnableIfPointerConvertible<_Pp> > 376*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 377*0fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} 378fe6060f1SDimitry Andric 379bdd1243dSDimitry Andric template <class _Pp, 380bdd1243dSDimitry Andric bool _Dummy = true, 381fe6060f1SDimitry Andric class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >, 382fe6060f1SDimitry Andric class = _EnableIfPointerConvertible<_Pp> > 3835f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT 384fe6060f1SDimitry Andric : __ptr_(__p, __d) {} 385fe6060f1SDimitry Andric 386bdd1243dSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > 3875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT 388fe6060f1SDimitry Andric : __ptr_(nullptr, __d) {} 389fe6060f1SDimitry Andric 390bdd1243dSDimitry Andric template <class _Pp, 391bdd1243dSDimitry Andric bool _Dummy = true, 392fe6060f1SDimitry Andric class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >, 393fe6060f1SDimitry Andric class = _EnableIfPointerConvertible<_Pp> > 3945f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 3955f757f3fSDimitry Andric : __ptr_(__p, std::move(__d)) { 396cb14a3feSDimitry Andric static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference"); 397fe6060f1SDimitry Andric } 398fe6060f1SDimitry Andric 399bdd1243dSDimitry Andric template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > 4005f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT 4015f757f3fSDimitry Andric : __ptr_(nullptr, std::move(__d)) { 402cb14a3feSDimitry Andric static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference"); 403fe6060f1SDimitry Andric } 404fe6060f1SDimitry Andric 405cb14a3feSDimitry Andric template <class _Pp, 406cb14a3feSDimitry Andric bool _Dummy = true, 407fe6060f1SDimitry Andric class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >, 408fe6060f1SDimitry Andric class = _EnableIfPointerConvertible<_Pp> > 409cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; 410fe6060f1SDimitry Andric 4115f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT 4125f757f3fSDimitry Andric : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {} 413fe6060f1SDimitry Andric 4145f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { 415fe6060f1SDimitry Andric reset(__u.release()); 4165f757f3fSDimitry Andric __ptr_.second() = std::forward<deleter_type>(__u.get_deleter()); 417fe6060f1SDimitry Andric return *this; 418fe6060f1SDimitry Andric } 419fe6060f1SDimitry Andric 420bdd1243dSDimitry Andric template <class _Up, 421bdd1243dSDimitry Andric class _Ep, 422fe6060f1SDimitry Andric class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 423bdd1243dSDimitry Andric class = _EnableIfDeleterConvertible<_Ep> > 4245f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT 4255f757f3fSDimitry Andric : __ptr_(__u.release(), std::forward<_Ep>(__u.get_deleter())) {} 426fe6060f1SDimitry Andric 427bdd1243dSDimitry Andric template <class _Up, 428bdd1243dSDimitry Andric class _Ep, 429fe6060f1SDimitry Andric class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, 430bdd1243dSDimitry Andric class = _EnableIfDeleterAssignable<_Ep> > 4315f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { 432fe6060f1SDimitry Andric reset(__u.release()); 4335f757f3fSDimitry Andric __ptr_.second() = std::forward<_Ep>(__u.get_deleter()); 434fe6060f1SDimitry Andric return *this; 435fe6060f1SDimitry Andric } 436fe6060f1SDimitry Andric 437fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 438fe6060f1SDimitry Andric unique_ptr(unique_ptr const&) = delete; 439fe6060f1SDimitry Andric unique_ptr& operator=(unique_ptr const&) = delete; 440fe6060f1SDimitry Andric #endif 441cb14a3feSDimitry Andric 442fe6060f1SDimitry Andric public: 4435f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } 444fe6060f1SDimitry Andric 4455f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { 446fe6060f1SDimitry Andric reset(); 447fe6060f1SDimitry Andric return *this; 448fe6060f1SDimitry Andric } 449fe6060f1SDimitry Andric 450cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const { 451fe6060f1SDimitry Andric return __ptr_.first()[__i]; 452fe6060f1SDimitry Andric } 4535f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } 454fe6060f1SDimitry Andric 455cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } 456fe6060f1SDimitry Andric 4575f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { 458fe6060f1SDimitry Andric return __ptr_.second(); 459fe6060f1SDimitry Andric } 4605f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { 461fe6060f1SDimitry Andric return __ptr_.first() != nullptr; 462fe6060f1SDimitry Andric } 463fe6060f1SDimitry Andric 4645f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { 465fe6060f1SDimitry Andric pointer __t = __ptr_.first(); 466fe6060f1SDimitry Andric __ptr_.first() = pointer(); 467fe6060f1SDimitry Andric return __t; 468fe6060f1SDimitry Andric } 469fe6060f1SDimitry Andric 4705f757f3fSDimitry Andric template <class _Pp, __enable_if_t<_CheckArrayPointerConversion<_Pp>::value, int> = 0> 471cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(_Pp __p) _NOEXCEPT { 472fe6060f1SDimitry Andric pointer __tmp = __ptr_.first(); 473fe6060f1SDimitry Andric __ptr_.first() = __p; 474fe6060f1SDimitry Andric if (__tmp) 475fe6060f1SDimitry Andric __ptr_.second()(__tmp); 476fe6060f1SDimitry Andric } 477fe6060f1SDimitry Andric 4785f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { 479fe6060f1SDimitry Andric pointer __tmp = __ptr_.first(); 480fe6060f1SDimitry Andric __ptr_.first() = nullptr; 481fe6060f1SDimitry Andric if (__tmp) 482fe6060f1SDimitry Andric __ptr_.second()(__tmp); 483fe6060f1SDimitry Andric } 484fe6060f1SDimitry Andric 485cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } 486fe6060f1SDimitry Andric }; 487fe6060f1SDimitry Andric 488*0fca6ea1SDimitry Andric template <class _Tp, class _Dp, __enable_if_t<__is_swappable_v<_Dp>, int> = 0> 489cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void 490bdd1243dSDimitry Andric swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { 491bdd1243dSDimitry Andric __x.swap(__y); 492bdd1243dSDimitry Andric } 493fe6060f1SDimitry Andric 494fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 4955f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 496bdd1243dSDimitry Andric operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 497bdd1243dSDimitry Andric return __x.get() == __y.get(); 498bdd1243dSDimitry Andric } 499fe6060f1SDimitry Andric 500bdd1243dSDimitry Andric #if _LIBCPP_STD_VER <= 17 501fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 502cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 503cb14a3feSDimitry Andric return !(__x == __y); 504cb14a3feSDimitry Andric } 505bdd1243dSDimitry Andric #endif 506fe6060f1SDimitry Andric 507fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 508cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 509fe6060f1SDimitry Andric typedef typename unique_ptr<_T1, _D1>::pointer _P1; 510fe6060f1SDimitry Andric typedef typename unique_ptr<_T2, _D2>::pointer _P2; 511fe6060f1SDimitry Andric typedef typename common_type<_P1, _P2>::type _Vp; 512fe6060f1SDimitry Andric return less<_Vp>()(__x.get(), __y.get()); 513fe6060f1SDimitry Andric } 514fe6060f1SDimitry Andric 515fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 516cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 517cb14a3feSDimitry Andric return __y < __x; 518cb14a3feSDimitry Andric } 519fe6060f1SDimitry Andric 520fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 521cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 522cb14a3feSDimitry Andric return !(__y < __x); 523cb14a3feSDimitry Andric } 524fe6060f1SDimitry Andric 525fe6060f1SDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 526cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 527cb14a3feSDimitry Andric return !(__x < __y); 528cb14a3feSDimitry Andric } 529bdd1243dSDimitry Andric 53006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 531bdd1243dSDimitry Andric template <class _T1, class _D1, class _T2, class _D2> 532cb14a3feSDimitry Andric requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer> 533bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI 534cb14a3feSDimitry Andric compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer, typename unique_ptr<_T2, _D2>::pointer> 535bdd1243dSDimitry Andric operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { 536bdd1243dSDimitry Andric return compare_three_way()(__x.get(), __y.get()); 537bdd1243dSDimitry Andric } 538bdd1243dSDimitry Andric #endif 539bdd1243dSDimitry Andric 540fe6060f1SDimitry Andric template <class _T1, class _D1> 5415f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool 542bdd1243dSDimitry Andric operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 543fe6060f1SDimitry Andric return !__x; 544fe6060f1SDimitry Andric } 545fe6060f1SDimitry Andric 546bdd1243dSDimitry Andric #if _LIBCPP_STD_VER <= 17 547fe6060f1SDimitry Andric template <class _T1, class _D1> 548cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { 549fe6060f1SDimitry Andric return !__x; 550fe6060f1SDimitry Andric } 551fe6060f1SDimitry Andric 552fe6060f1SDimitry Andric template <class _T1, class _D1> 553cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { 554fe6060f1SDimitry Andric return static_cast<bool>(__x); 555fe6060f1SDimitry Andric } 556fe6060f1SDimitry Andric 557fe6060f1SDimitry Andric template <class _T1, class _D1> 558cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { 559fe6060f1SDimitry Andric return static_cast<bool>(__x); 560fe6060f1SDimitry Andric } 561bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER <= 17 562fe6060f1SDimitry Andric 563fe6060f1SDimitry Andric template <class _T1, class _D1> 564cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 565fe6060f1SDimitry Andric typedef typename unique_ptr<_T1, _D1>::pointer _P1; 566fe6060f1SDimitry Andric return less<_P1>()(__x.get(), nullptr); 567fe6060f1SDimitry Andric } 568fe6060f1SDimitry Andric 569fe6060f1SDimitry Andric template <class _T1, class _D1> 570cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 571fe6060f1SDimitry Andric typedef typename unique_ptr<_T1, _D1>::pointer _P1; 572fe6060f1SDimitry Andric return less<_P1>()(nullptr, __x.get()); 573fe6060f1SDimitry Andric } 574fe6060f1SDimitry Andric 575fe6060f1SDimitry Andric template <class _T1, class _D1> 576cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 577fe6060f1SDimitry Andric return nullptr < __x; 578fe6060f1SDimitry Andric } 579fe6060f1SDimitry Andric 580fe6060f1SDimitry Andric template <class _T1, class _D1> 581cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 582fe6060f1SDimitry Andric return __x < nullptr; 583fe6060f1SDimitry Andric } 584fe6060f1SDimitry Andric 585fe6060f1SDimitry Andric template <class _T1, class _D1> 586cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 587fe6060f1SDimitry Andric return !(nullptr < __x); 588fe6060f1SDimitry Andric } 589fe6060f1SDimitry Andric 590fe6060f1SDimitry Andric template <class _T1, class _D1> 591cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 592fe6060f1SDimitry Andric return !(__x < nullptr); 593fe6060f1SDimitry Andric } 594fe6060f1SDimitry Andric 595fe6060f1SDimitry Andric template <class _T1, class _D1> 596cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 597fe6060f1SDimitry Andric return !(__x < nullptr); 598fe6060f1SDimitry Andric } 599fe6060f1SDimitry Andric 600fe6060f1SDimitry Andric template <class _T1, class _D1> 601cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { 602fe6060f1SDimitry Andric return !(nullptr < __x); 603fe6060f1SDimitry Andric } 604fe6060f1SDimitry Andric 60506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 606bdd1243dSDimitry Andric template <class _T1, class _D1> 607cb14a3feSDimitry Andric requires three_way_comparable< typename unique_ptr<_T1, _D1>::pointer> 608cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> 609bdd1243dSDimitry Andric operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { 610bdd1243dSDimitry Andric return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr)); 611bdd1243dSDimitry Andric } 612bdd1243dSDimitry Andric #endif 613bdd1243dSDimitry Andric 61406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 615fe6060f1SDimitry Andric 616fe6060f1SDimitry Andric template <class _Tp> 617cb14a3feSDimitry Andric struct __unique_if { 618fe6060f1SDimitry Andric typedef unique_ptr<_Tp> __unique_single; 619fe6060f1SDimitry Andric }; 620fe6060f1SDimitry Andric 621fe6060f1SDimitry Andric template <class _Tp> 622cb14a3feSDimitry Andric struct __unique_if<_Tp[]> { 623fe6060f1SDimitry Andric typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; 624fe6060f1SDimitry Andric }; 625fe6060f1SDimitry Andric 626fe6060f1SDimitry Andric template <class _Tp, size_t _Np> 627cb14a3feSDimitry Andric struct __unique_if<_Tp[_Np]> { 628fe6060f1SDimitry Andric typedef void __unique_array_known_bound; 629fe6060f1SDimitry Andric }; 630fe6060f1SDimitry Andric 631fe6060f1SDimitry Andric template <class _Tp, class... _Args> 6325f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 633bdd1243dSDimitry Andric make_unique(_Args&&... __args) { 6345f757f3fSDimitry Andric return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); 635fe6060f1SDimitry Andric } 636fe6060f1SDimitry Andric 637fe6060f1SDimitry Andric template <class _Tp> 6385f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 639bdd1243dSDimitry Andric make_unique(size_t __n) { 640bdd1243dSDimitry Andric typedef __remove_extent_t<_Tp> _Up; 641fe6060f1SDimitry Andric return unique_ptr<_Tp>(new _Up[__n]()); 642fe6060f1SDimitry Andric } 643fe6060f1SDimitry Andric 644fe6060f1SDimitry Andric template <class _Tp, class... _Args> 645cb14a3feSDimitry Andric typename __unique_if<_Tp>::__unique_array_known_bound make_unique(_Args&&...) = delete; 646fe6060f1SDimitry Andric 64706c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 648fe6060f1SDimitry Andric 649bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 20 650bdd1243dSDimitry Andric 651bdd1243dSDimitry Andric template <class _Tp> 652bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single 653bdd1243dSDimitry Andric make_unique_for_overwrite() { 654bdd1243dSDimitry Andric return unique_ptr<_Tp>(new _Tp); 655bdd1243dSDimitry Andric } 656bdd1243dSDimitry Andric 657bdd1243dSDimitry Andric template <class _Tp> 658bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound 659bdd1243dSDimitry Andric make_unique_for_overwrite(size_t __n) { 660bdd1243dSDimitry Andric return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]); 661bdd1243dSDimitry Andric } 662bdd1243dSDimitry Andric 663bdd1243dSDimitry Andric template <class _Tp, class... _Args> 664bdd1243dSDimitry Andric typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete; 665bdd1243dSDimitry Andric 666bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 20 667bdd1243dSDimitry Andric 668cb14a3feSDimitry Andric template <class _Tp> 669cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash; 670fe6060f1SDimitry Andric 671fe6060f1SDimitry Andric template <class _Tp, class _Dp> 672fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 673fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> > 674fe6060f1SDimitry Andric #else 675cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > 676fe6060f1SDimitry Andric #endif 677fe6060f1SDimitry Andric { 678fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 679fe6060f1SDimitry Andric _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; 680fe6060f1SDimitry Andric _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 681fe6060f1SDimitry Andric #endif 682fe6060f1SDimitry Andric 683cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { 684fe6060f1SDimitry Andric typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; 685fe6060f1SDimitry Andric return hash<pointer>()(__ptr.get()); 686fe6060f1SDimitry Andric } 687fe6060f1SDimitry Andric }; 688fe6060f1SDimitry Andric 689fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 690fe6060f1SDimitry Andric 69106c3fb27SDimitry Andric _LIBCPP_POP_MACROS 69206c3fb27SDimitry Andric 693fe6060f1SDimitry Andric #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H 694