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