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