]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/unique_ptr.h
c++: Fix a pasto in the PR120471 fix [PR120940]
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / unique_ptr.h
CommitLineData
083b7f28 1
ca0f8fd1
PC
2// unique_ptr implementation -*- C++ -*-
3
6441eb6d 4// Copyright (C) 2008-2025 Free Software Foundation, Inc.
ca0f8fd1
PC
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
748086b7 9// Free Software Foundation; either version 3, or (at your option)
ca0f8fd1
PC
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
748086b7
JJ
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
ca0f8fd1 25
f910786b 26/** @file bits/unique_ptr.h
ca0f8fd1 27 * This is an internal header file, included by other library headers.
f910786b 28 * Do not attempt to use it directly. @headername{memory}
ca0f8fd1
PC
29 */
30
31#ifndef _UNIQUE_PTR_H
32#define _UNIQUE_PTR_H 1
33
ca0f8fd1 34#include <bits/c++config.h>
adad2a7d 35#include <debug/assertions.h>
ca0f8fd1 36#include <type_traits>
ca0f8fd1 37#include <tuple>
c05986b9 38#include <bits/stl_function.h>
6964bb3e 39#include <bits/functional_hash.h>
cf0fded5 40#if __cplusplus >= 202002L
5b074864 41# include <compare>
cf0fded5 42# if _GLIBCXX_HOSTED
462a7f45 43# include <bits/ostream.h>
cf0fded5 44# endif
5b074864 45#endif
ca0f8fd1 46
12ffa228
BK
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
ca0f8fd1 50
5b9daa7e
BK
51 /**
52 * @addtogroup pointer_abstractions
53 * @{
54 */
55
6e48db73 56#if _GLIBCXX_USE_DEPRECATED
a2c0a194
JW
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
6e48db73 59 template<typename> class auto_ptr;
a2c0a194 60#pragma GCC diagnostic pop
6e48db73
JW
61#endif
62
a2784022
JW
63 /** Primary template of default_delete, used by unique_ptr for single objects
64 *
65 * @headerfile memory
66 * @since C++11
67 */
94a86be0 68 template<typename _Tp>
ca0f8fd1 69 struct default_delete
be9d3d73 70 {
05a4261b 71 /// Default constructor
525fe1cf 72 constexpr default_delete() noexcept = default;
ca0f8fd1 73
05a4261b
JW
74 /** @brief Converting constructor.
75 *
302b6996
JW
76 * Allows conversion from a deleter for objects of another type, `_Up`,
77 * only if `_Up*` is convertible to `_Tp*`.
05a4261b 78 */
7fb65a87
JW
79 template<typename _Up,
80 typename = _Require<is_convertible<_Up*, _Tp*>>>
2fbdcf5e 81 _GLIBCXX23_CONSTEXPR
525fe1cf 82 default_delete(const default_delete<_Up>&) noexcept { }
ca0f8fd1 83
302b6996 84 /// Calls `delete __ptr`
2fbdcf5e 85 _GLIBCXX23_CONSTEXPR
be9d3d73
PC
86 void
87 operator()(_Tp* __ptr) const
88 {
8d52ed5c
JW
89 static_assert(!is_void<_Tp>::value,
90 "can't delete pointer to incomplete type");
be9d3d73
PC
91 static_assert(sizeof(_Tp)>0,
92 "can't delete pointer to incomplete type");
93 delete __ptr;
94 }
ca0f8fd1
PC
95 };
96
97 // _GLIBCXX_RESOLVE_LIB_DEFECTS
98 // DR 740 - omit specialization for array objects with a compile time length
302b6996 99
a2784022
JW
100 /** Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
101 *
102 * @headerfile memory
103 * @since C++11
104 */
94a86be0 105 template<typename _Tp>
ca0f8fd1
PC
106 struct default_delete<_Tp[]>
107 {
23df8534 108 public:
05a4261b 109 /// Default constructor
525fe1cf 110 constexpr default_delete() noexcept = default;
be9d3d73 111
05a4261b
JW
112 /** @brief Converting constructor.
113 *
114 * Allows conversion from a deleter for arrays of another type, such as
302b6996 115 * a const-qualified version of `_Tp`.
05a4261b 116 *
302b6996
JW
117 * Conversions from types derived from `_Tp` are not allowed because
118 * it is undefined to `delete[]` an array of derived types through a
05a4261b
JW
119 * pointer to the base type.
120 */
7fb65a87
JW
121 template<typename _Up,
122 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
2fbdcf5e 123 _GLIBCXX23_CONSTEXPR
23df8534
JW
124 default_delete(const default_delete<_Up[]>&) noexcept { }
125
302b6996 126 /// Calls `delete[] __ptr`
f3344569 127 template<typename _Up>
2fbdcf5e 128 _GLIBCXX23_CONSTEXPR
7fb65a87 129 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
f3344569 130 operator()(_Up* __ptr) const
7fb65a87
JW
131 {
132 static_assert(sizeof(_Tp)>0,
133 "can't delete pointer to incomplete type");
134 delete [] __ptr;
135 }
ca0f8fd1
PC
136 };
137
302b6996
JW
138 /// @cond undocumented
139
1b18663e 140 // Manages the pointer and deleter of a unique_ptr
e182393e
JW
141 template <typename _Tp, typename _Dp>
142 class __uniq_ptr_impl
ca0f8fd1 143 {
e182393e
JW
144 template <typename _Up, typename _Ep, typename = void>
145 struct _Ptr
146 {
147 using type = _Up*;
148 };
149
150 template <typename _Up, typename _Ep>
151 struct
152 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
153 {
154 using type = typename remove_reference<_Ep>::type::pointer;
155 };
7b65808d 156
e182393e 157 public:
13086769
VV
158 using _DeleterConstraint = enable_if<
159 __and_<__not_<is_pointer<_Dp>>,
160 is_default_constructible<_Dp>>::value>;
161
e182393e 162 using pointer = typename _Ptr<_Tp, _Dp>::type;
7b65808d 163
86fc6ec9
JW
164 static_assert( !is_rvalue_reference<_Dp>::value,
165 "unique_ptr's deleter type must be a function object type"
166 " or an lvalue reference type" );
86fc6ec9 167
e182393e 168 __uniq_ptr_impl() = default;
2fbdcf5e 169 _GLIBCXX23_CONSTEXPR
e182393e 170 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
7b65808d 171
e182393e 172 template<typename _Del>
2fbdcf5e
JW
173 _GLIBCXX23_CONSTEXPR
174 __uniq_ptr_impl(pointer __p, _Del&& __d)
e182393e 175 : _M_t(__p, std::forward<_Del>(__d)) { }
7b65808d 176
2fbdcf5e 177 _GLIBCXX23_CONSTEXPR
1b18663e
JW
178 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
179 : _M_t(std::move(__u._M_t))
180 { __u._M_ptr() = nullptr; }
181
2fbdcf5e 182 _GLIBCXX23_CONSTEXPR
1b18663e
JW
183 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
184 {
185 reset(__u.release());
186 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
187 return *this;
188 }
189
2fbdcf5e 190 _GLIBCXX23_CONSTEXPR
869107c9 191 pointer& _M_ptr() noexcept { return std::get<0>(_M_t); }
2fbdcf5e 192 _GLIBCXX23_CONSTEXPR
869107c9 193 pointer _M_ptr() const noexcept { return std::get<0>(_M_t); }
2fbdcf5e 194 _GLIBCXX23_CONSTEXPR
869107c9 195 _Dp& _M_deleter() noexcept { return std::get<1>(_M_t); }
2fbdcf5e 196 _GLIBCXX23_CONSTEXPR
869107c9 197 const _Dp& _M_deleter() const noexcept { return std::get<1>(_M_t); }
94a86be0 198
2fbdcf5e 199 _GLIBCXX23_CONSTEXPR
1b18663e
JW
200 void reset(pointer __p) noexcept
201 {
202 const pointer __old_p = _M_ptr();
203 _M_ptr() = __p;
204 if (__old_p)
205 _M_deleter()(__old_p);
206 }
207
2fbdcf5e 208 _GLIBCXX23_CONSTEXPR
1b18663e
JW
209 pointer release() noexcept
210 {
211 pointer __p = _M_ptr();
212 _M_ptr() = nullptr;
213 return __p;
214 }
215
2fbdcf5e 216 _GLIBCXX23_CONSTEXPR
9962493c
JW
217 void
218 swap(__uniq_ptr_impl& __rhs) noexcept
219 {
220 using std::swap;
221 swap(this->_M_ptr(), __rhs._M_ptr());
222 swap(this->_M_deleter(), __rhs._M_deleter());
223 }
224
e182393e
JW
225 private:
226 tuple<pointer, _Dp> _M_t;
227 };
1b18663e
JW
228
229 // Defines move construction + assignment as either defaulted or deleted.
230 template <typename _Tp, typename _Dp,
231 bool = is_move_constructible<_Dp>::value,
232 bool = is_move_assignable<_Dp>::value>
233 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
234 {
235 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
236 __uniq_ptr_data(__uniq_ptr_data&&) = default;
237 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
238 };
239
240 template <typename _Tp, typename _Dp>
241 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
242 {
243 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
244 __uniq_ptr_data(__uniq_ptr_data&&) = default;
245 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
246 };
247
248 template <typename _Tp, typename _Dp>
249 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
250 {
251 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
252 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
253 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
254 };
255
256 template <typename _Tp, typename _Dp>
257 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
258 {
259 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
260 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
261 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
262 };
302b6996 263 /// @endcond
e182393e 264
4fb471af
JW
265 // 20.7.1.2 unique_ptr for single objects.
266
267 /// A move-only smart pointer that manages unique ownership of a resource.
30b300de 268 /// @headerfile memory
4fb471af 269 /// @since C++11
e182393e
JW
270 template <typename _Tp, typename _Dp = default_delete<_Tp>>
271 class unique_ptr
272 {
86fc6ec9
JW
273 template <typename _Up>
274 using _DeleterConstraint =
275 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
13086769 276
1b18663e 277 __uniq_ptr_data<_Tp, _Dp> _M_t;
ca0f8fd1 278
e182393e
JW
279 public:
280 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
281 using element_type = _Tp;
282 using deleter_type = _Dp;
f3344569 283
86fc6ec9 284 private:
f3344569
VV
285 // helper template for detecting a safe conversion from another
286 // unique_ptr
287 template<typename _Up, typename _Ep>
288 using __safe_conversion_up = __and_<
949fdadb
JW
289 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
290 __not_<is_array<_Up>>
291 >;
f3344569 292
86fc6ec9 293 public:
37d5c6ba 294 // Constructors.
05a4261b
JW
295
296 /// Default constructor, creates a unique_ptr that owns nothing.
86fc6ec9 297 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
13086769
VV
298 constexpr unique_ptr() noexcept
299 : _M_t()
c3ba63c3 300 { }
ca0f8fd1 301
05a4261b
JW
302 /** Takes ownership of a pointer.
303 *
304 * @param __p A pointer to an object of @c element_type
305 *
306 * The deleter will be value-initialized.
307 */
86fc6ec9 308 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
2fbdcf5e 309 _GLIBCXX23_CONSTEXPR
13086769
VV
310 explicit
311 unique_ptr(pointer __p) noexcept
312 : _M_t(__p)
313 { }
ca0f8fd1 314
05a4261b
JW
315 /** Takes ownership of a pointer.
316 *
317 * @param __p A pointer to an object of @c element_type
318 * @param __d A reference to a deleter.
319 *
320 * The deleter will be initialized with @p __d
321 */
86fc6ec9
JW
322 template<typename _Del = deleter_type,
323 typename = _Require<is_copy_constructible<_Del>>>
2fbdcf5e 324 _GLIBCXX23_CONSTEXPR
86fc6ec9
JW
325 unique_ptr(pointer __p, const deleter_type& __d) noexcept
326 : _M_t(__p, __d) { }
ca0f8fd1 327
05a4261b
JW
328 /** Takes ownership of a pointer.
329 *
330 * @param __p A pointer to an object of @c element_type
86fc6ec9 331 * @param __d An rvalue reference to a (non-reference) deleter.
05a4261b
JW
332 *
333 * The deleter will be initialized with @p std::move(__d)
334 */
86fc6ec9
JW
335 template<typename _Del = deleter_type,
336 typename = _Require<is_move_constructible<_Del>>>
2fbdcf5e 337 _GLIBCXX23_CONSTEXPR
86fc6ec9
JW
338 unique_ptr(pointer __p,
339 __enable_if_t<!is_lvalue_reference<_Del>::value,
340 _Del&&> __d) noexcept
341 : _M_t(__p, std::move(__d))
342 { }
343
344 template<typename _Del = deleter_type,
345 typename _DelUnref = typename remove_reference<_Del>::type>
2fbdcf5e 346 _GLIBCXX23_CONSTEXPR
86fc6ec9
JW
347 unique_ptr(pointer,
348 __enable_if_t<is_lvalue_reference<_Del>::value,
349 _DelUnref&&>) = delete;
ca0f8fd1 350
05a4261b 351 /// Creates a unique_ptr that owns nothing.
86fc6ec9 352 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
c3ba63c3
JW
353 constexpr unique_ptr(nullptr_t) noexcept
354 : _M_t()
355 { }
6d00745b 356
37d5c6ba 357 // Move constructors.
05a4261b
JW
358
359 /// Move constructor.
1b18663e 360 unique_ptr(unique_ptr&&) = default;
ca0f8fd1 361
05a4261b
JW
362 /** @brief Converting constructor from another type
363 *
364 * Requires that the pointer owned by @p __u is convertible to the
365 * type of pointer owned by this object, @p __u does not own an array,
366 * and @p __u has a compatible deleter type.
367 */
23df8534 368 template<typename _Up, typename _Ep, typename = _Require<
f3344569 369 __safe_conversion_up<_Up, _Ep>,
a09bb4a8
JW
370 __conditional_t<is_reference<_Dp>::value,
371 is_same<_Ep, _Dp>,
372 is_convertible<_Ep, _Dp>>>>
2fbdcf5e 373 _GLIBCXX23_CONSTEXPR
525fe1cf 374 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
da8111a0 375 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
ca0f8fd1
PC
376 { }
377
e1bcd685 378#if _GLIBCXX_USE_DEPRECATED
a2c0a194
JW
379#pragma GCC diagnostic push
380#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
05a4261b 381 /// Converting constructor from @c auto_ptr
a001d515
JW
382 template<typename _Up,
383 typename = _Require<is_convertible<_Up*, pointer>,
384 is_same<_Dp, default_delete<_Tp>>>>
6e48db73 385 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
a2c0a194 386#pragma GCC diagnostic pop
5aadb69b
PC
387#endif
388
05a4261b 389 /// Destructor, invokes the deleter if the stored pointer is not null.
2fbdcf5e
JW
390#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
391 constexpr
392#endif
6d79ba30
JW
393 ~unique_ptr() noexcept
394 {
a12c16de
JW
395 static_assert(__is_invocable<deleter_type&, pointer>::value,
396 "unique_ptr's deleter must be invocable with a pointer");
e182393e 397 auto& __ptr = _M_t._M_ptr();
6d79ba30 398 if (__ptr != nullptr)
a12c16de 399 get_deleter()(std::move(__ptr));
6d79ba30
JW
400 __ptr = pointer();
401 }
5aadb69b 402
37d5c6ba 403 // Assignment.
05a4261b
JW
404
405 /** @brief Move assignment operator.
406 *
1b18663e 407 * Invokes the deleter if this object owns a pointer.
05a4261b 408 */
1b18663e 409 unique_ptr& operator=(unique_ptr&&) = default;
ca0f8fd1 410
05a4261b
JW
411 /** @brief Assignment from another type.
412 *
413 * @param __u The object to transfer ownership from, which owns a
414 * convertible pointer to a non-array object.
415 *
1b18663e 416 * Invokes the deleter if this object owns a pointer.
05a4261b 417 */
23df8534 418 template<typename _Up, typename _Ep>
2fbdcf5e 419 _GLIBCXX23_CONSTEXPR
f3344569
VV
420 typename enable_if< __and_<
421 __safe_conversion_up<_Up, _Ep>,
422 is_assignable<deleter_type&, _Ep&&>
423 >::value,
424 unique_ptr&>::type
525fe1cf 425 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
ca0f8fd1 426 {
94a86be0 427 reset(__u.release());
da8111a0 428 get_deleter() = std::forward<_Ep>(__u.get_deleter());
94a86be0
BK
429 return *this;
430 }
ca0f8fd1 431
05a4261b 432 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
2fbdcf5e 433 _GLIBCXX23_CONSTEXPR
ca0f8fd1 434 unique_ptr&
525fe1cf 435 operator=(nullptr_t) noexcept
ca0f8fd1
PC
436 {
437 reset();
438 return *this;
439 }
440
37d5c6ba 441 // Observers.
05a4261b
JW
442
443 /// Dereference the stored pointer.
2fbdcf5e 444 _GLIBCXX23_CONSTEXPR
23df8534 445 typename add_lvalue_reference<element_type>::type
17bc3848 446 operator*() const noexcept(noexcept(*std::declval<pointer>()))
ca0f8fd1 447 {
8ff7ff1a
JW
448#if _GLIBCXX_USE_BUILTIN_TRAIT(__reference_converts_from_temporary)
449 // _GLIBCXX_RESOLVE_LIB_DEFECTS
450 // 4148. unique_ptr::operator* should not allow dangling references
451 using _ResT = typename add_lvalue_reference<element_type>::type;
452 using _DerefT = decltype(*get());
453 static_assert(!__reference_converts_from_temporary(_ResT, _DerefT),
454 "operator* must not return a dangling reference");
455#endif
2f1e8e7c 456 __glibcxx_assert(get() != pointer());
ca0f8fd1
PC
457 return *get();
458 }
459
05a4261b 460 /// Return the stored pointer.
2fbdcf5e 461 _GLIBCXX23_CONSTEXPR
ca0f8fd1 462 pointer
525fe1cf 463 operator->() const noexcept
ca0f8fd1 464 {
93023f35 465 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
ca0f8fd1
PC
466 return get();
467 }
468
05a4261b 469 /// Return the stored pointer.
2fbdcf5e 470 _GLIBCXX23_CONSTEXPR
ca0f8fd1 471 pointer
525fe1cf 472 get() const noexcept
e182393e 473 { return _M_t._M_ptr(); }
ca0f8fd1 474
05a4261b 475 /// Return a reference to the stored deleter.
2fbdcf5e 476 _GLIBCXX23_CONSTEXPR
2ba34efc 477 deleter_type&
525fe1cf 478 get_deleter() noexcept
e182393e 479 { return _M_t._M_deleter(); }
ca0f8fd1 480
05a4261b 481 /// Return a reference to the stored deleter.
2fbdcf5e 482 _GLIBCXX23_CONSTEXPR
2ba34efc 483 const deleter_type&
525fe1cf 484 get_deleter() const noexcept
e182393e 485 { return _M_t._M_deleter(); }
ca0f8fd1 486
05a4261b 487 /// Return @c true if the stored pointer is not null.
2fbdcf5e 488 _GLIBCXX23_CONSTEXPR
525fe1cf 489 explicit operator bool() const noexcept
3e2e1976 490 { return get() == pointer() ? false : true; }
ca0f8fd1 491
37d5c6ba 492 // Modifiers.
05a4261b
JW
493
494 /// Release ownership of any stored pointer.
2fbdcf5e 495 _GLIBCXX23_CONSTEXPR
ca0f8fd1 496 pointer
525fe1cf 497 release() noexcept
1b18663e 498 { return _M_t.release(); }
ca0f8fd1 499
05a4261b
JW
500 /** @brief Replace the stored pointer.
501 *
502 * @param __p The new pointer to store.
503 *
504 * The deleter will be invoked if a pointer is already owned.
505 */
2fbdcf5e 506 _GLIBCXX23_CONSTEXPR
ca0f8fd1 507 void
525fe1cf 508 reset(pointer __p = pointer()) noexcept
ca0f8fd1 509 {
a12c16de
JW
510 static_assert(__is_invocable<deleter_type&, pointer>::value,
511 "unique_ptr's deleter must be invocable with a pointer");
1b18663e 512 _M_t.reset(std::move(__p));
ca0f8fd1
PC
513 }
514
05a4261b 515 /// Exchange the pointer and deleter with another object.
2fbdcf5e 516 _GLIBCXX23_CONSTEXPR
ca0f8fd1 517 void
525fe1cf 518 swap(unique_ptr& __u) noexcept
0d5f7a16 519 {
9962493c
JW
520 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
521 _M_t.swap(__u._M_t);
ca0f8fd1
PC
522 }
523
37d5c6ba 524 // Disable copy from lvalue.
0d5f7a16 525 unique_ptr(const unique_ptr&) = delete;
0d5f7a16 526 unique_ptr& operator=(const unique_ptr&) = delete;
c7f6537d
JW
527
528 private:
529#ifdef __glibcxx_out_ptr
530 template<typename, typename, typename...>
531 friend class out_ptr_t;
532 template<typename, typename, typename...>
533 friend class inout_ptr_t;
534#endif
ca0f8fd1 535 };
94a86be0 536
4fb471af 537 // 20.7.1.3 unique_ptr for array objects with a runtime length
ca0f8fd1
PC
538 // [unique.ptr.runtime]
539 // _GLIBCXX_RESOLVE_LIB_DEFECTS
540 // DR 740 - omit specialization for array objects with a compile time length
4fb471af
JW
541
542 /// A move-only smart pointer that manages unique ownership of an array.
30b300de 543 /// @headerfile memory
4fb471af 544 /// @since C++11
8fe286ea
PC
545 template<typename _Tp, typename _Dp>
546 class unique_ptr<_Tp[], _Dp>
ca0f8fd1 547 {
13086769
VV
548 template <typename _Up>
549 using _DeleterConstraint =
550 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
551
1b18663e 552 __uniq_ptr_data<_Tp, _Dp> _M_t;
23df8534 553
23df8534
JW
554 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
555 template<typename _Up>
556 using __is_derived_Tp
557 = __and_< is_base_of<_Tp, _Up>,
9ca14715 558 __not_<is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up>>> >;
23df8534 559
ca0f8fd1 560 public:
e182393e
JW
561 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
562 using element_type = _Tp;
563 using deleter_type = _Dp;
94a86be0 564
f3344569
VV
565 // helper template for detecting a safe conversion from another
566 // unique_ptr
567 template<typename _Up, typename _Ep,
949fdadb
JW
568 typename _UPtr = unique_ptr<_Up, _Ep>,
569 typename _UP_pointer = typename _UPtr::pointer,
570 typename _UP_element_type = typename _UPtr::element_type>
f3344569
VV
571 using __safe_conversion_up = __and_<
572 is_array<_Up>,
573 is_same<pointer, element_type*>,
949fdadb
JW
574 is_same<_UP_pointer, _UP_element_type*>,
575 is_convertible<_UP_element_type(*)[], element_type(*)[]>
f3344569
VV
576 >;
577
578 // helper template for detecting a safe conversion from a raw pointer
579 template<typename _Up>
580 using __safe_conversion_raw = __and_<
581 __or_<__or_<is_same<_Up, pointer>,
582 is_same<_Up, nullptr_t>>,
583 __and_<is_pointer<_Up>,
584 is_same<pointer, element_type*>,
585 is_convertible<
586 typename remove_pointer<_Up>::type(*)[],
587 element_type(*)[]>
588 >
589 >
590 >;
591
37d5c6ba 592 // Constructors.
05a4261b
JW
593
594 /// Default constructor, creates a unique_ptr that owns nothing.
86fc6ec9 595 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
13086769
VV
596 constexpr unique_ptr() noexcept
597 : _M_t()
c3ba63c3 598 { }
ca0f8fd1 599
05a4261b
JW
600 /** Takes ownership of a pointer.
601 *
f3344569
VV
602 * @param __p A pointer to an array of a type safely convertible
603 * to an array of @c element_type
05a4261b
JW
604 *
605 * The deleter will be value-initialized.
606 */
f3344569 607 template<typename _Up,
13086769
VV
608 typename _Vp = _Dp,
609 typename = _DeleterConstraint<_Vp>,
610 typename = typename enable_if<
f3344569 611 __safe_conversion_raw<_Up>::value, bool>::type>
2fbdcf5e 612 _GLIBCXX23_CONSTEXPR
13086769
VV
613 explicit
614 unique_ptr(_Up __p) noexcept
615 : _M_t(__p)
616 { }
23df8534 617
05a4261b
JW
618 /** Takes ownership of a pointer.
619 *
f3344569
VV
620 * @param __p A pointer to an array of a type safely convertible
621 * to an array of @c element_type
05a4261b
JW
622 * @param __d A reference to a deleter.
623 *
624 * The deleter will be initialized with @p __d
625 */
86fc6ec9
JW
626 template<typename _Up, typename _Del = deleter_type,
627 typename = _Require<__safe_conversion_raw<_Up>,
628 is_copy_constructible<_Del>>>
2fbdcf5e
JW
629 _GLIBCXX23_CONSTEXPR
630 unique_ptr(_Up __p, const deleter_type& __d) noexcept
631 : _M_t(__p, __d) { }
ca0f8fd1 632
05a4261b
JW
633 /** Takes ownership of a pointer.
634 *
f3344569
VV
635 * @param __p A pointer to an array of a type safely convertible
636 * to an array of @c element_type
05a4261b
JW
637 * @param __d A reference to a deleter.
638 *
639 * The deleter will be initialized with @p std::move(__d)
640 */
86fc6ec9
JW
641 template<typename _Up, typename _Del = deleter_type,
642 typename = _Require<__safe_conversion_raw<_Up>,
643 is_move_constructible<_Del>>>
2fbdcf5e 644 _GLIBCXX23_CONSTEXPR
86fc6ec9
JW
645 unique_ptr(_Up __p,
646 __enable_if_t<!is_lvalue_reference<_Del>::value,
647 _Del&&> __d) noexcept
648 : _M_t(std::move(__p), std::move(__d))
649 { }
650
651 template<typename _Up, typename _Del = deleter_type,
652 typename _DelUnref = typename remove_reference<_Del>::type,
653 typename = _Require<__safe_conversion_raw<_Up>>>
654 unique_ptr(_Up,
655 __enable_if_t<is_lvalue_reference<_Del>::value,
656 _DelUnref&&>) = delete;
ca0f8fd1 657
05a4261b 658 /// Move constructor.
1b18663e 659 unique_ptr(unique_ptr&&) = default;
ca0f8fd1 660
05a4261b 661 /// Creates a unique_ptr that owns nothing.
86fc6ec9 662 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
c3ba63c3
JW
663 constexpr unique_ptr(nullptr_t) noexcept
664 : _M_t()
665 { }
23df8534 666
949fdadb
JW
667 template<typename _Up, typename _Ep, typename = _Require<
668 __safe_conversion_up<_Up, _Ep>,
a09bb4a8
JW
669 __conditional_t<is_reference<_Dp>::value,
670 is_same<_Ep, _Dp>,
671 is_convertible<_Ep, _Dp>>>>
2fbdcf5e 672 _GLIBCXX23_CONSTEXPR
525fe1cf 673 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
da8111a0 674 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
ca0f8fd1
PC
675 { }
676
05a4261b 677 /// Destructor, invokes the deleter if the stored pointer is not null.
2fbdcf5e
JW
678#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
679 constexpr
680#endif
6d79ba30
JW
681 ~unique_ptr()
682 {
e182393e 683 auto& __ptr = _M_t._M_ptr();
6d79ba30
JW
684 if (__ptr != nullptr)
685 get_deleter()(__ptr);
686 __ptr = pointer();
687 }
ca0f8fd1 688
37d5c6ba 689 // Assignment.
05a4261b
JW
690
691 /** @brief Move assignment operator.
692 *
1b18663e 693 * Invokes the deleter if this object owns a pointer.
05a4261b 694 */
ca0f8fd1 695 unique_ptr&
1b18663e 696 operator=(unique_ptr&&) = default;
ca0f8fd1 697
05a4261b
JW
698 /** @brief Assignment from another type.
699 *
700 * @param __u The object to transfer ownership from, which owns a
701 * convertible pointer to an array object.
702 *
1b18663e 703 * Invokes the deleter if this object owns a pointer.
05a4261b 704 */
94a86be0 705 template<typename _Up, typename _Ep>
2fbdcf5e 706 _GLIBCXX23_CONSTEXPR
23df8534 707 typename
f3344569
VV
708 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
709 is_assignable<deleter_type&, _Ep&&>
710 >::value,
711 unique_ptr&>::type
525fe1cf 712 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
ca0f8fd1 713 {
94a86be0 714 reset(__u.release());
da8111a0 715 get_deleter() = std::forward<_Ep>(__u.get_deleter());
94a86be0
BK
716 return *this;
717 }
ca0f8fd1 718
05a4261b 719 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
2fbdcf5e 720 _GLIBCXX23_CONSTEXPR
ca0f8fd1 721 unique_ptr&
525fe1cf 722 operator=(nullptr_t) noexcept
ca0f8fd1
PC
723 {
724 reset();
725 return *this;
726 }
727
37d5c6ba 728 // Observers.
05a4261b
JW
729
730 /// Access an element of owned array.
2fbdcf5e 731 _GLIBCXX23_CONSTEXPR
94a86be0
BK
732 typename std::add_lvalue_reference<element_type>::type
733 operator[](size_t __i) const
ca0f8fd1 734 {
2f1e8e7c 735 __glibcxx_assert(get() != pointer());
ca0f8fd1
PC
736 return get()[__i];
737 }
738
05a4261b 739 /// Return the stored pointer.
2fbdcf5e 740 _GLIBCXX23_CONSTEXPR
ca0f8fd1 741 pointer
525fe1cf 742 get() const noexcept
e182393e 743 { return _M_t._M_ptr(); }
ca0f8fd1 744
05a4261b 745 /// Return a reference to the stored deleter.
2fbdcf5e 746 _GLIBCXX23_CONSTEXPR
94a86be0 747 deleter_type&
525fe1cf 748 get_deleter() noexcept
e182393e 749 { return _M_t._M_deleter(); }
ca0f8fd1 750
05a4261b 751 /// Return a reference to the stored deleter.
2fbdcf5e 752 _GLIBCXX23_CONSTEXPR
2ba34efc 753 const deleter_type&
525fe1cf 754 get_deleter() const noexcept
e182393e 755 { return _M_t._M_deleter(); }
ca0f8fd1 756
05a4261b 757 /// Return @c true if the stored pointer is not null.
2fbdcf5e 758 _GLIBCXX23_CONSTEXPR
525fe1cf 759 explicit operator bool() const noexcept
3e2e1976 760 { return get() == pointer() ? false : true; }
94a86be0 761
37d5c6ba 762 // Modifiers.
05a4261b
JW
763
764 /// Release ownership of any stored pointer.
2fbdcf5e 765 _GLIBCXX23_CONSTEXPR
ca0f8fd1 766 pointer
525fe1cf 767 release() noexcept
1b18663e 768 { return _M_t.release(); }
ca0f8fd1 769
05a4261b
JW
770 /** @brief Replace the stored pointer.
771 *
772 * @param __p The new pointer to store.
773 *
774 * The deleter will be invoked if a pointer is already owned.
775 */
f3344569
VV
776 template <typename _Up,
777 typename = _Require<
778 __or_<is_same<_Up, pointer>,
779 __and_<is_same<pointer, element_type*>,
780 is_pointer<_Up>,
781 is_convertible<
782 typename remove_pointer<_Up>::type(*)[],
783 element_type(*)[]
784 >
785 >
786 >
787 >>
2fbdcf5e 788 _GLIBCXX23_CONSTEXPR
ca0f8fd1 789 void
f3344569 790 reset(_Up __p) noexcept
1b18663e 791 { _M_t.reset(std::move(__p)); }
ca0f8fd1 792
2fbdcf5e 793 _GLIBCXX23_CONSTEXPR
f3344569 794 void reset(nullptr_t = nullptr) noexcept
1b18663e 795 { reset(pointer()); }
0d5f7a16 796
05a4261b 797 /// Exchange the pointer and deleter with another object.
2fbdcf5e 798 _GLIBCXX23_CONSTEXPR
ca0f8fd1 799 void
525fe1cf 800 swap(unique_ptr& __u) noexcept
ca0f8fd1 801 {
9962493c
JW
802 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
803 _M_t.swap(__u._M_t);
ca0f8fd1
PC
804 }
805
37d5c6ba 806 // Disable copy from lvalue.
0d5f7a16
PC
807 unique_ptr(const unique_ptr&) = delete;
808 unique_ptr& operator=(const unique_ptr&) = delete;
c7f6537d
JW
809
810 private:
811#ifdef __glibcxx_out_ptr
812 template<typename, typename, typename...> friend class out_ptr_t;
813 template<typename, typename, typename...> friend class inout_ptr_t;
814#endif
525fe1cf 815 };
94a86be0 816
adc03d72
JW
817 /// @{
818 /// @relates unique_ptr
efa9d8ee 819
302b6996 820 /// Swap overload for unique_ptr
94a86be0 821 template<typename _Tp, typename _Dp>
6b9539e2
DK
822 inline
823#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
824 // Constrained free swap overload, see p0185r1
2fbdcf5e 825 _GLIBCXX23_CONSTEXPR
6b9539e2
DK
826 typename enable_if<__is_swappable<_Dp>::value>::type
827#else
828 void
829#endif
8fe286ea 830 swap(unique_ptr<_Tp, _Dp>& __x,
525fe1cf 831 unique_ptr<_Tp, _Dp>& __y) noexcept
ca0f8fd1
PC
832 { __x.swap(__y); }
833
a2863bde
VV
834#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
835 template<typename _Tp, typename _Dp>
a2863bde
VV
836 typename enable_if<!__is_swappable<_Dp>::value>::type
837 swap(unique_ptr<_Tp, _Dp>&,
838 unique_ptr<_Tp, _Dp>&) = delete;
839#endif
840
7fb65a87 841 /// Equality operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
842 template<typename _Tp, typename _Dp,
843 typename _Up, typename _Ep>
2fbdcf5e
JW
844 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
845 inline bool
8fe286ea
PC
846 operator==(const unique_ptr<_Tp, _Dp>& __x,
847 const unique_ptr<_Up, _Ep>& __y)
ca0f8fd1
PC
848 { return __x.get() == __y.get(); }
849
302b6996 850 /// unique_ptr comparison with nullptr
3abeaf8f 851 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
852 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
853 inline bool
355e71b9
PC
854 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
855 { return !__x; }
3abeaf8f 856
5b074864 857#ifndef __cpp_lib_three_way_comparison
302b6996 858 /// unique_ptr comparison with nullptr
3abeaf8f 859 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
860 _GLIBCXX_NODISCARD
861 inline bool
355e71b9
PC
862 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
863 { return !__x; }
3abeaf8f 864
302b6996 865 /// Inequality operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
866 template<typename _Tp, typename _Dp,
867 typename _Up, typename _Ep>
2fbdcf5e
JW
868 _GLIBCXX_NODISCARD
869 inline bool
8fe286ea
PC
870 operator!=(const unique_ptr<_Tp, _Dp>& __x,
871 const unique_ptr<_Up, _Ep>& __y)
355e71b9 872 { return __x.get() != __y.get(); }
ca0f8fd1 873
302b6996 874 /// unique_ptr comparison with nullptr
3abeaf8f 875 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
876 _GLIBCXX_NODISCARD
877 inline bool
355e71b9
PC
878 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
879 { return (bool)__x; }
3abeaf8f 880
302b6996 881 /// unique_ptr comparison with nullptr
3abeaf8f 882 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
883 _GLIBCXX_NODISCARD
884 inline bool
355e71b9
PC
885 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
886 { return (bool)__x; }
5b074864 887#endif // three way comparison
3abeaf8f 888
302b6996 889 /// Relational operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
890 template<typename _Tp, typename _Dp,
891 typename _Up, typename _Ep>
2fbdcf5e
JW
892 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
893 inline bool
8fe286ea
PC
894 operator<(const unique_ptr<_Tp, _Dp>& __x,
895 const unique_ptr<_Up, _Ep>& __y)
355e71b9
PC
896 {
897 typedef typename
898 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
899 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
900 return std::less<_CT>()(__x.get(), __y.get());
901 }
902
302b6996 903 /// unique_ptr comparison with nullptr
355e71b9 904 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
905 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
906 inline bool
355e71b9 907 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
efa9d8ee
JW
908 {
909 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
910 nullptr);
911 }
355e71b9 912
302b6996 913 /// unique_ptr comparison with nullptr
355e71b9 914 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
915 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
916 inline bool
355e71b9 917 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
efa9d8ee
JW
918 {
919 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
920 __x.get());
921 }
ca0f8fd1 922
302b6996 923 /// Relational operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
924 template<typename _Tp, typename _Dp,
925 typename _Up, typename _Ep>
2fbdcf5e
JW
926 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
927 inline bool
8fe286ea
PC
928 operator<=(const unique_ptr<_Tp, _Dp>& __x,
929 const unique_ptr<_Up, _Ep>& __y)
355e71b9
PC
930 { return !(__y < __x); }
931
302b6996 932 /// unique_ptr comparison with nullptr
355e71b9 933 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
934 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
935 inline bool
355e71b9
PC
936 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
937 { return !(nullptr < __x); }
938
302b6996 939 /// unique_ptr comparison with nullptr
355e71b9 940 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
941 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
942 inline bool
355e71b9
PC
943 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
944 { return !(__x < nullptr); }
ca0f8fd1 945
302b6996 946 /// Relational operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
947 template<typename _Tp, typename _Dp,
948 typename _Up, typename _Ep>
2fbdcf5e
JW
949 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
950 inline bool
8fe286ea
PC
951 operator>(const unique_ptr<_Tp, _Dp>& __x,
952 const unique_ptr<_Up, _Ep>& __y)
355e71b9
PC
953 { return (__y < __x); }
954
302b6996 955 /// unique_ptr comparison with nullptr
355e71b9 956 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
957 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
958 inline bool
355e71b9 959 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
efa9d8ee
JW
960 {
961 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
962 __x.get());
963 }
355e71b9 964
302b6996 965 /// unique_ptr comparison with nullptr
355e71b9 966 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
967 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
968 inline bool
355e71b9 969 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
efa9d8ee
JW
970 {
971 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
972 nullptr);
973 }
ca0f8fd1 974
302b6996 975 /// Relational operator for unique_ptr objects, compares the owned pointers
8fe286ea
PC
976 template<typename _Tp, typename _Dp,
977 typename _Up, typename _Ep>
2fbdcf5e
JW
978 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
979 inline bool
8fe286ea
PC
980 operator>=(const unique_ptr<_Tp, _Dp>& __x,
981 const unique_ptr<_Up, _Ep>& __y)
355e71b9
PC
982 { return !(__x < __y); }
983
302b6996 984 /// unique_ptr comparison with nullptr
355e71b9 985 template<typename _Tp, typename _Dp>
2fbdcf5e
JW
986 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
987 inline bool
355e71b9
PC
988 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
989 { return !(__x < nullptr); }
990
302b6996 991 /// unique_ptr comparison with nullptr
355e71b9 992 template<typename _Tp, typename _Dp>
ec0d5371 993 _GLIBCXX_NODISCARD inline bool
355e71b9
PC
994 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
995 { return !(nullptr < __x); }
5b074864
JW
996
997#ifdef __cpp_lib_three_way_comparison
998 template<typename _Tp, typename _Dp, typename _Up, typename _Ep>
999 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
1000 typename unique_ptr<_Up, _Ep>::pointer>
2fbdcf5e 1001 _GLIBCXX23_CONSTEXPR
f5fa62ed 1002 inline
5b074864
JW
1003 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
1004 typename unique_ptr<_Up, _Ep>::pointer>
1005 operator<=>(const unique_ptr<_Tp, _Dp>& __x,
1006 const unique_ptr<_Up, _Ep>& __y)
1007 { return compare_three_way()(__x.get(), __y.get()); }
1008
1009 template<typename _Tp, typename _Dp>
1010 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
2fbdcf5e 1011 _GLIBCXX23_CONSTEXPR
f5fa62ed 1012 inline
5b074864
JW
1013 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
1014 operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
1015 {
1016 using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
f5fa62ed 1017 return compare_three_way()(__x.get(), static_cast<pointer>(nullptr));
5b074864
JW
1018 }
1019#endif
f0b88346 1020 /// @} relates unique_ptr
7fb65a87
JW
1021
1022 /// @cond undocumented
01ba02ca 1023 template<typename _Up, typename _Ptr = typename _Up::pointer>
7fb65a87 1024 struct __uniq_ptr_hash
01ba02ca 1025 : public __hash_base<size_t, _Up>
7fb65a87 1026#if ! _GLIBCXX_INLINE_VERSION
01ba02ca 1027 , private __hash_empty_base<_Ptr>
7fb65a87
JW
1028#endif
1029 {
1030 size_t
1031 operator()(const _Up& __u) const
1032 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
1033 { return hash<_Ptr>()(__u.get()); }
1034 };
1035
01ba02ca
JW
1036 template<typename _Up>
1037 using __uniq_ptr_hash_base
1038 = __conditional_t<__is_hash_enabled_for<typename _Up::pointer>,
1039 __uniq_ptr_hash<_Up>,
1040 __hash_not_enabled<typename _Up::pointer>>;
7fb65a87 1041 /// @endcond
ca0f8fd1 1042
b0e788cc 1043 /// std::hash specialization for unique_ptr.
8fe286ea
PC
1044 template<typename _Tp, typename _Dp>
1045 struct hash<unique_ptr<_Tp, _Dp>>
01ba02ca 1046 : public __uniq_ptr_hash_base<unique_ptr<_Tp, _Dp>>
7fb65a87 1047 { };
b0e788cc 1048
7ffa63df 1049#ifdef __glibcxx_make_unique // C++ >= 14 && HOSTED
efa9d8ee 1050 /// @cond undocumented
4fb471af
JW
1051namespace __detail
1052{
a9769eb0
JW
1053 template<typename _Tp>
1054 struct _MakeUniq
1055 { typedef unique_ptr<_Tp> __single_object; };
1056
1057 template<typename _Tp>
1058 struct _MakeUniq<_Tp[]>
1059 { typedef unique_ptr<_Tp[]> __array; };
1060
1061 template<typename _Tp, size_t _Bound>
1062 struct _MakeUniq<_Tp[_Bound]>
1063 { struct __invalid_type { }; };
1064
4fb471af
JW
1065 template<typename _Tp>
1066 using __unique_ptr_t = typename _MakeUniq<_Tp>::__single_object;
1067 template<typename _Tp>
1068 using __unique_ptr_array_t = typename _MakeUniq<_Tp>::__array;
1069 template<typename _Tp>
1070 using __invalid_make_unique_t = typename _MakeUniq<_Tp>::__invalid_type;
1071}
efa9d8ee
JW
1072 /// @endcond
1073
4fb471af
JW
1074 /** Create an object owned by a `unique_ptr`.
1075 * @tparam _Tp A non-array object type.
1076 * @param __args Constructor arguments for the new object.
1077 * @returns A `unique_ptr<_Tp>` that owns the new object.
1078 * @since C++14
1079 * @relates unique_ptr
1080 */
a9769eb0 1081 template<typename _Tp, typename... _Args>
2fbdcf5e 1082 _GLIBCXX23_CONSTEXPR
4fb471af 1083 inline __detail::__unique_ptr_t<_Tp>
a9769eb0
JW
1084 make_unique(_Args&&... __args)
1085 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
1086
4fb471af
JW
1087 /** Create an array owned by a `unique_ptr`.
1088 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1089 * @param __num The number of elements of type `U` in the new array.
1090 * @returns A `unique_ptr<U[]>` that owns the new array.
1091 * @since C++14
1092 * @relates unique_ptr
1093 *
1094 * The array elements are value-initialized.
1095 */
a9769eb0 1096 template<typename _Tp>
2fbdcf5e 1097 _GLIBCXX23_CONSTEXPR
4fb471af 1098 inline __detail::__unique_ptr_array_t<_Tp>
a9769eb0 1099 make_unique(size_t __num)
8a57bed1 1100 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
a9769eb0 1101
4fb471af
JW
1102 /** Disable std::make_unique for arrays of known bound.
1103 * @tparam _Tp An array type of known bound, such as `U[N]`.
1104 * @since C++14
1105 * @relates unique_ptr
1106 */
a9769eb0 1107 template<typename _Tp, typename... _Args>
4fb471af 1108 __detail::__invalid_make_unique_t<_Tp>
a9769eb0 1109 make_unique(_Args&&...) = delete;
e7a0af84
JW
1110
1111#if __cplusplus > 201703L
4fb471af
JW
1112 /** Create a default-initialied object owned by a `unique_ptr`.
1113 * @tparam _Tp A non-array object type.
1114 * @returns A `unique_ptr<_Tp>` that owns the new object.
1115 * @since C++20
1116 * @relates unique_ptr
1117 */
e7a0af84 1118 template<typename _Tp>
2fbdcf5e 1119 _GLIBCXX23_CONSTEXPR
4fb471af 1120 inline __detail::__unique_ptr_t<_Tp>
e7a0af84
JW
1121 make_unique_for_overwrite()
1122 { return unique_ptr<_Tp>(new _Tp); }
1123
4fb471af
JW
1124 /** Create a default-initialized array owned by a `unique_ptr`.
1125 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1126 * @param __num The number of elements of type `U` in the new array.
1127 * @returns A `unique_ptr<U[]>` that owns the new array.
1128 * @since C++20
1129 * @relates unique_ptr
1130 */
e7a0af84 1131 template<typename _Tp>
2fbdcf5e 1132 _GLIBCXX23_CONSTEXPR
4fb471af 1133 inline __detail::__unique_ptr_array_t<_Tp>
3a32a8ad
JW
1134 make_unique_for_overwrite(size_t __num)
1135 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]); }
e7a0af84 1136
4fb471af
JW
1137 /** Disable std::make_unique_for_overwrite for arrays of known bound.
1138 * @tparam _Tp An array type of known bound, such as `U[N]`.
1139 * @since C++20
1140 * @relates unique_ptr
1141 */
e7a0af84 1142 template<typename _Tp, typename... _Args>
4fb471af 1143 __detail::__invalid_make_unique_t<_Tp>
e7a0af84
JW
1144 make_unique_for_overwrite(_Args&&...) = delete;
1145#endif // C++20
1146
cf0fded5 1147#endif // C++14 && HOSTED
187da2ce 1148
cf0fded5 1149#if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
187da2ce
JW
1150 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1151 // 2948. unique_ptr does not define operator<< for stream output
1152 /// Stream output operator for unique_ptr
4fb471af
JW
1153 /// @relates unique_ptr
1154 /// @since C++20
187da2ce
JW
1155 template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
1156 inline basic_ostream<_CharT, _Traits>&
1157 operator<<(basic_ostream<_CharT, _Traits>& __os,
1158 const unique_ptr<_Tp, _Dp>& __p)
1159 requires requires { __os << __p.get(); }
1160 {
1161 __os << __p.get();
1162 return __os;
1163 }
cf0fded5 1164#endif // C++20 && HOSTED
a9769eb0 1165
c7f6537d
JW
1166#if __cpp_variable_templates
1167 template<typename _Tp>
6a4d1c37 1168 constexpr bool __is_unique_ptr = false;
c7f6537d 1169 template<typename _Tp, typename _Del>
6a4d1c37 1170 constexpr bool __is_unique_ptr<unique_ptr<_Tp, _Del>> = true;
c7f6537d
JW
1171#endif
1172
f0b88346 1173 /// @} group pointer_abstractions
5b9daa7e 1174
10f26de9
JW
1175#if __cplusplus >= 201703L
1176 namespace __detail::__variant
1177 {
1178 template<typename> struct _Never_valueless_alt; // see <variant>
1179
1180 // Provide the strong exception-safety guarantee when emplacing a
1181 // unique_ptr into a variant.
1182 template<typename _Tp, typename _Del>
1183 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
1184 : std::true_type
1185 { };
1186 } // namespace __detail::__variant
1187#endif // C++17
1188
12ffa228
BK
1189_GLIBCXX_END_NAMESPACE_VERSION
1190} // namespace
ca0f8fd1
PC
1191
1192#endif /* _UNIQUE_PTR_H */