2 // unique_ptr implementation -*- C++ -*-
4 // Copyright (C) 2008-2025 Free Software Foundation, Inc.
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
9 // Free Software Foundation; either version 3, or (at your option)
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.
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.
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/>.
26 /** @file bits/unique_ptr.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{memory}
32 #define _UNIQUE_PTR_H 1
34 #include <bits/c++config.h>
35 #include <debug/assertions.h>
36 #include <type_traits>
38 #include <bits/stl_function.h>
39 #include <bits/functional_hash.h>
40 #if __cplusplus >= 202002L
43 # include <bits/ostream.h>
47 namespace std
_GLIBCXX_VISIBILITY(default)
49 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52 * @addtogroup pointer_abstractions
56 #if _GLIBCXX_USE_DEPRECATED
57 #pragma GCC diagnostic push
58 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
59 template<typename
> class auto_ptr
;
60 #pragma GCC diagnostic pop
63 /** Primary template of default_delete, used by unique_ptr for single objects
68 template<typename _Tp
>
71 /// Default constructor
72 constexpr default_delete() noexcept
= default;
74 /** @brief Converting constructor.
76 * Allows conversion from a deleter for objects of another type, `_Up`,
77 * only if `_Up*` is convertible to `_Tp*`.
79 template<typename _Up
,
80 typename
= _Require
<is_convertible
<_Up
*, _Tp
*>>>
82 default_delete(const default_delete
<_Up
>&) noexcept
{ }
84 /// Calls `delete __ptr`
87 operator()(_Tp
* __ptr
) const
89 static_assert(!is_void
<_Tp
>::value
,
90 "can't delete pointer to incomplete type");
91 static_assert(sizeof(_Tp
)>0,
92 "can't delete pointer to incomplete type");
97 // _GLIBCXX_RESOLVE_LIB_DEFECTS
98 // DR 740 - omit specialization for array objects with a compile time length
100 /** Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
105 template<typename _Tp
>
106 struct default_delete
<_Tp
[]>
109 /// Default constructor
110 constexpr default_delete() noexcept
= default;
112 /** @brief Converting constructor.
114 * Allows conversion from a deleter for arrays of another type, such as
115 * a const-qualified version of `_Tp`.
117 * Conversions from types derived from `_Tp` are not allowed because
118 * it is undefined to `delete[]` an array of derived types through a
119 * pointer to the base type.
121 template<typename _Up
,
122 typename
= _Require
<is_convertible
<_Up(*)[], _Tp(*)[]>>>
124 default_delete(const default_delete
<_Up
[]>&) noexcept
{ }
126 /// Calls `delete[] __ptr`
127 template<typename _Up
>
129 typename enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
>::type
130 operator()(_Up
* __ptr
) const
132 static_assert(sizeof(_Tp
)>0,
133 "can't delete pointer to incomplete type");
138 /// @cond undocumented
140 // Manages the pointer and deleter of a unique_ptr
141 template <typename _Tp
, typename _Dp
>
142 class __uniq_ptr_impl
144 template <typename _Up
, typename _Ep
, typename
= void>
150 template <typename _Up
, typename _Ep
>
152 _Ptr
<_Up
, _Ep
, __void_t
<typename remove_reference
<_Ep
>::type::pointer
>>
154 using type
= typename remove_reference
<_Ep
>::type::pointer
;
158 using _DeleterConstraint
= enable_if
<
159 __and_
<__not_
<is_pointer
<_Dp
>>,
160 is_default_constructible
<_Dp
>>::value
>;
162 using pointer
= typename _Ptr
<_Tp
, _Dp
>::type
;
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" );
168 __uniq_ptr_impl() = default;
170 __uniq_ptr_impl(pointer __p
) : _M_t() { _M_ptr() = __p
; }
172 template<typename _Del
>
174 __uniq_ptr_impl(pointer __p
, _Del
&& __d
)
175 : _M_t(__p
, std::forward
<_Del
>(__d
)) { }
178 __uniq_ptr_impl(__uniq_ptr_impl
&& __u
) noexcept
179 : _M_t(std::move(__u
._M_t
))
180 { __u
._M_ptr() = nullptr; }
183 __uniq_ptr_impl
& operator=(__uniq_ptr_impl
&& __u
) noexcept
185 reset(__u
.release());
186 _M_deleter() = std::forward
<_Dp
>(__u
._M_deleter());
191 pointer
& _M_ptr() noexcept
{ return std::get
<0>(_M_t
); }
193 pointer
_M_ptr() const noexcept
{ return std::get
<0>(_M_t
); }
195 _Dp
& _M_deleter() noexcept
{ return std::get
<1>(_M_t
); }
197 const _Dp
& _M_deleter() const noexcept
{ return std::get
<1>(_M_t
); }
200 void reset(pointer __p
) noexcept
202 const pointer __old_p
= _M_ptr();
205 _M_deleter()(__old_p
);
209 pointer
release() noexcept
211 pointer __p
= _M_ptr();
218 swap(__uniq_ptr_impl
& __rhs
) noexcept
221 swap(this->_M_ptr(), __rhs
._M_ptr());
222 swap(this->_M_deleter(), __rhs
._M_deleter());
226 tuple
<pointer
, _Dp
> _M_t
;
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
>
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;
240 template <typename _Tp
, typename _Dp
>
241 struct __uniq_ptr_data
<_Tp
, _Dp
, true, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
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;
248 template <typename _Tp
, typename _Dp
>
249 struct __uniq_ptr_data
<_Tp
, _Dp
, false, true> : __uniq_ptr_impl
<_Tp
, _Dp
>
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;
256 template <typename _Tp
, typename _Dp
>
257 struct __uniq_ptr_data
<_Tp
, _Dp
, false, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
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;
265 // 20.7.1.2 unique_ptr for single objects.
267 /// A move-only smart pointer that manages unique ownership of a resource.
268 /// @headerfile memory
270 template <typename _Tp
, typename _Dp
= default_delete
<_Tp
>>
273 template <typename _Up
>
274 using _DeleterConstraint
=
275 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
277 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
280 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
281 using element_type
= _Tp
;
282 using deleter_type
= _Dp
;
285 // helper template for detecting a safe conversion from another
287 template<typename _Up
, typename _Ep
>
288 using __safe_conversion_up
= __and_
<
289 is_convertible
<typename unique_ptr
<_Up
, _Ep
>::pointer
, pointer
>,
290 __not_
<is_array
<_Up
>>
296 /// Default constructor, creates a unique_ptr that owns nothing.
297 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
298 constexpr unique_ptr() noexcept
302 /** Takes ownership of a pointer.
304 * @param __p A pointer to an object of @c element_type
306 * The deleter will be value-initialized.
308 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
311 unique_ptr(pointer __p
) noexcept
315 /** Takes ownership of a pointer.
317 * @param __p A pointer to an object of @c element_type
318 * @param __d A reference to a deleter.
320 * The deleter will be initialized with @p __d
322 template<typename _Del
= deleter_type
,
323 typename
= _Require
<is_copy_constructible
<_Del
>>>
325 unique_ptr(pointer __p
, const deleter_type
& __d
) noexcept
328 /** Takes ownership of a pointer.
330 * @param __p A pointer to an object of @c element_type
331 * @param __d An rvalue reference to a (non-reference) deleter.
333 * The deleter will be initialized with @p std::move(__d)
335 template<typename _Del
= deleter_type
,
336 typename
= _Require
<is_move_constructible
<_Del
>>>
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
))
344 template<typename _Del
= deleter_type
,
345 typename _DelUnref
= typename remove_reference
<_Del
>::type
>
348 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
349 _DelUnref
&&>) = delete;
351 /// Creates a unique_ptr that owns nothing.
352 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
353 constexpr unique_ptr(nullptr_t
) noexcept
357 // Move constructors.
359 /// Move constructor.
360 unique_ptr(unique_ptr
&&) = default;
362 /** @brief Converting constructor from another type
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.
368 template<typename _Up
, typename _Ep
, typename
= _Require
<
369 __safe_conversion_up
<_Up
, _Ep
>,
370 __conditional_t
<is_reference
<_Dp
>::value
,
372 is_convertible
<_Ep
, _Dp
>>>>
374 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
375 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
378 #if _GLIBCXX_USE_DEPRECATED
379 #pragma GCC diagnostic push
380 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
381 /// Converting constructor from @c auto_ptr
382 template<typename _Up
,
383 typename
= _Require
<is_convertible
<_Up
*, pointer
>,
384 is_same
<_Dp
, default_delete
<_Tp
>>>>
385 unique_ptr(auto_ptr
<_Up
>&& __u
) noexcept
;
386 #pragma GCC diagnostic pop
389 /// Destructor, invokes the deleter if the stored pointer is not null.
390 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
393 ~unique_ptr() noexcept
395 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
396 "unique_ptr's deleter must be invocable with a pointer");
397 auto& __ptr
= _M_t
._M_ptr();
398 if (__ptr
!= nullptr)
399 get_deleter()(std::move(__ptr
));
405 /** @brief Move assignment operator.
407 * Invokes the deleter if this object owns a pointer.
409 unique_ptr
& operator=(unique_ptr
&&) = default;
411 /** @brief Assignment from another type.
413 * @param __u The object to transfer ownership from, which owns a
414 * convertible pointer to a non-array object.
416 * Invokes the deleter if this object owns a pointer.
418 template<typename _Up
, typename _Ep
>
420 typename enable_if
< __and_
<
421 __safe_conversion_up
<_Up
, _Ep
>,
422 is_assignable
<deleter_type
&, _Ep
&&>
425 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
427 reset(__u
.release());
428 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
432 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
435 operator=(nullptr_t
) noexcept
443 /// Dereference the stored pointer.
445 typename add_lvalue_reference
<element_type
>::type
446 operator*() const noexcept(noexcept(*std::declval
<pointer
>()))
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");
456 __glibcxx_assert(get() != pointer());
460 /// Return the stored pointer.
463 operator->() const noexcept
465 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
469 /// Return the stored pointer.
473 { return _M_t
._M_ptr(); }
475 /// Return a reference to the stored deleter.
478 get_deleter() noexcept
479 { return _M_t
._M_deleter(); }
481 /// Return a reference to the stored deleter.
484 get_deleter() const noexcept
485 { return _M_t
._M_deleter(); }
487 /// Return @c true if the stored pointer is not null.
489 explicit operator bool() const noexcept
490 { return get() == pointer() ? false : true; }
494 /// Release ownership of any stored pointer.
498 { return _M_t
.release(); }
500 /** @brief Replace the stored pointer.
502 * @param __p The new pointer to store.
504 * The deleter will be invoked if a pointer is already owned.
508 reset(pointer __p
= pointer()) noexcept
510 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
511 "unique_ptr's deleter must be invocable with a pointer");
512 _M_t
.reset(std::move(__p
));
515 /// Exchange the pointer and deleter with another object.
518 swap(unique_ptr
& __u
) noexcept
520 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
524 // Disable copy from lvalue.
525 unique_ptr(const unique_ptr
&) = delete;
526 unique_ptr
& operator=(const unique_ptr
&) = delete;
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
;
537 // 20.7.1.3 unique_ptr for array objects with a runtime length
538 // [unique.ptr.runtime]
539 // _GLIBCXX_RESOLVE_LIB_DEFECTS
540 // DR 740 - omit specialization for array objects with a compile time length
542 /// A move-only smart pointer that manages unique ownership of an array.
543 /// @headerfile memory
545 template<typename _Tp
, typename _Dp
>
546 class unique_ptr
<_Tp
[], _Dp
>
548 template <typename _Up
>
549 using _DeleterConstraint
=
550 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
552 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
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
>,
558 __not_
<is_same
<__remove_cv_t
<_Tp
>, __remove_cv_t
<_Up
>>> >;
561 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
562 using element_type
= _Tp
;
563 using deleter_type
= _Dp
;
565 // helper template for detecting a safe conversion from another
567 template<typename _Up
, typename _Ep
,
568 typename _UPtr
= unique_ptr
<_Up
, _Ep
>,
569 typename _UP_pointer
= typename
_UPtr::pointer
,
570 typename _UP_element_type
= typename
_UPtr::element_type
>
571 using __safe_conversion_up
= __and_
<
573 is_same
<pointer
, element_type
*>,
574 is_same
<_UP_pointer
, _UP_element_type
*>,
575 is_convertible
<_UP_element_type(*)[], element_type(*)[]>
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
*>,
586 typename remove_pointer
<_Up
>::type(*)[],
594 /// Default constructor, creates a unique_ptr that owns nothing.
595 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
596 constexpr unique_ptr() noexcept
600 /** Takes ownership of a pointer.
602 * @param __p A pointer to an array of a type safely convertible
603 * to an array of @c element_type
605 * The deleter will be value-initialized.
607 template<typename _Up
,
609 typename
= _DeleterConstraint
<_Vp
>,
610 typename
= typename enable_if
<
611 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
614 unique_ptr(_Up __p
) noexcept
618 /** Takes ownership of a pointer.
620 * @param __p A pointer to an array of a type safely convertible
621 * to an array of @c element_type
622 * @param __d A reference to a deleter.
624 * The deleter will be initialized with @p __d
626 template<typename _Up
, typename _Del
= deleter_type
,
627 typename
= _Require
<__safe_conversion_raw
<_Up
>,
628 is_copy_constructible
<_Del
>>>
630 unique_ptr(_Up __p
, const deleter_type
& __d
) noexcept
633 /** Takes ownership of a pointer.
635 * @param __p A pointer to an array of a type safely convertible
636 * to an array of @c element_type
637 * @param __d A reference to a deleter.
639 * The deleter will be initialized with @p std::move(__d)
641 template<typename _Up
, typename _Del
= deleter_type
,
642 typename
= _Require
<__safe_conversion_raw
<_Up
>,
643 is_move_constructible
<_Del
>>>
646 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
647 _Del
&&> __d
) noexcept
648 : _M_t(std::move(__p
), std::move(__d
))
651 template<typename _Up
, typename _Del
= deleter_type
,
652 typename _DelUnref
= typename remove_reference
<_Del
>::type
,
653 typename
= _Require
<__safe_conversion_raw
<_Up
>>>
655 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
656 _DelUnref
&&>) = delete;
658 /// Move constructor.
659 unique_ptr(unique_ptr
&&) = default;
661 /// Creates a unique_ptr that owns nothing.
662 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
663 constexpr unique_ptr(nullptr_t
) noexcept
667 template<typename _Up
, typename _Ep
, typename
= _Require
<
668 __safe_conversion_up
<_Up
, _Ep
>,
669 __conditional_t
<is_reference
<_Dp
>::value
,
671 is_convertible
<_Ep
, _Dp
>>>>
673 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
674 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
677 /// Destructor, invokes the deleter if the stored pointer is not null.
678 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
683 auto& __ptr
= _M_t
._M_ptr();
684 if (__ptr
!= nullptr)
685 get_deleter()(__ptr
);
691 /** @brief Move assignment operator.
693 * Invokes the deleter if this object owns a pointer.
696 operator=(unique_ptr
&&) = default;
698 /** @brief Assignment from another type.
700 * @param __u The object to transfer ownership from, which owns a
701 * convertible pointer to an array object.
703 * Invokes the deleter if this object owns a pointer.
705 template<typename _Up
, typename _Ep
>
708 enable_if
<__and_
<__safe_conversion_up
<_Up
, _Ep
>,
709 is_assignable
<deleter_type
&, _Ep
&&>
712 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
714 reset(__u
.release());
715 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
719 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
722 operator=(nullptr_t
) noexcept
730 /// Access an element of owned array.
732 typename
std::add_lvalue_reference
<element_type
>::type
733 operator[](size_t __i
) const
735 __glibcxx_assert(get() != pointer());
739 /// Return the stored pointer.
743 { return _M_t
._M_ptr(); }
745 /// Return a reference to the stored deleter.
748 get_deleter() noexcept
749 { return _M_t
._M_deleter(); }
751 /// Return a reference to the stored deleter.
754 get_deleter() const noexcept
755 { return _M_t
._M_deleter(); }
757 /// Return @c true if the stored pointer is not null.
759 explicit operator bool() const noexcept
760 { return get() == pointer() ? false : true; }
764 /// Release ownership of any stored pointer.
768 { return _M_t
.release(); }
770 /** @brief Replace the stored pointer.
772 * @param __p The new pointer to store.
774 * The deleter will be invoked if a pointer is already owned.
776 template <typename _Up
,
778 __or_
<is_same
<_Up
, pointer
>,
779 __and_
<is_same
<pointer
, element_type
*>,
782 typename remove_pointer
<_Up
>::type(*)[],
790 reset(_Up __p
) noexcept
791 { _M_t
.reset(std::move(__p
)); }
794 void reset(nullptr_t
= nullptr) noexcept
795 { reset(pointer()); }
797 /// Exchange the pointer and deleter with another object.
800 swap(unique_ptr
& __u
) noexcept
802 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
806 // Disable copy from lvalue.
807 unique_ptr(const unique_ptr
&) = delete;
808 unique_ptr
& operator=(const unique_ptr
&) = delete;
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
;
818 /// @relates unique_ptr
820 /// Swap overload for unique_ptr
821 template<typename _Tp
, typename _Dp
>
823 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
824 // Constrained free swap overload, see p0185r1
826 typename enable_if
<__is_swappable
<_Dp
>::value
>::type
830 swap(unique_ptr
<_Tp
, _Dp
>& __x
,
831 unique_ptr
<_Tp
, _Dp
>& __y
) noexcept
834 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
835 template<typename _Tp
, typename _Dp
>
836 typename enable_if
<!__is_swappable
<_Dp
>::value
>::type
837 swap(unique_ptr
<_Tp
, _Dp
>&,
838 unique_ptr
<_Tp
, _Dp
>&) = delete;
841 /// Equality operator for unique_ptr objects, compares the owned pointers
842 template<typename _Tp
, typename _Dp
,
843 typename _Up
, typename _Ep
>
844 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
846 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
,
847 const unique_ptr
<_Up
, _Ep
>& __y
)
848 { return __x
.get() == __y
.get(); }
850 /// unique_ptr comparison with nullptr
851 template<typename _Tp
, typename _Dp
>
852 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
854 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
857 #ifndef __cpp_lib_three_way_comparison
858 /// unique_ptr comparison with nullptr
859 template<typename _Tp
, typename _Dp
>
862 operator==(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
865 /// Inequality operator for unique_ptr objects, compares the owned pointers
866 template<typename _Tp
, typename _Dp
,
867 typename _Up
, typename _Ep
>
870 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
,
871 const unique_ptr
<_Up
, _Ep
>& __y
)
872 { return __x
.get() != __y
.get(); }
874 /// unique_ptr comparison with nullptr
875 template<typename _Tp
, typename _Dp
>
878 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
879 { return (bool)__x
; }
881 /// unique_ptr comparison with nullptr
882 template<typename _Tp
, typename _Dp
>
885 operator!=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
886 { return (bool)__x
; }
887 #endif // three way comparison
889 /// Relational operator for unique_ptr objects, compares the owned pointers
890 template<typename _Tp
, typename _Dp
,
891 typename _Up
, typename _Ep
>
892 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
894 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
,
895 const unique_ptr
<_Up
, _Ep
>& __y
)
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());
903 /// unique_ptr comparison with nullptr
904 template<typename _Tp
, typename _Dp
>
905 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
907 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
909 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
913 /// unique_ptr comparison with nullptr
914 template<typename _Tp
, typename _Dp
>
915 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
917 operator<(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
919 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
923 /// Relational operator for unique_ptr objects, compares the owned pointers
924 template<typename _Tp
, typename _Dp
,
925 typename _Up
, typename _Ep
>
926 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
928 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
,
929 const unique_ptr
<_Up
, _Ep
>& __y
)
930 { return !(__y
< __x
); }
932 /// unique_ptr comparison with nullptr
933 template<typename _Tp
, typename _Dp
>
934 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
936 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
937 { return !(nullptr < __x
); }
939 /// unique_ptr comparison with nullptr
940 template<typename _Tp
, typename _Dp
>
941 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
943 operator<=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
944 { return !(__x
< nullptr); }
946 /// Relational operator for unique_ptr objects, compares the owned pointers
947 template<typename _Tp
, typename _Dp
,
948 typename _Up
, typename _Ep
>
949 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
951 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
,
952 const unique_ptr
<_Up
, _Ep
>& __y
)
953 { return (__y
< __x
); }
955 /// unique_ptr comparison with nullptr
956 template<typename _Tp
, typename _Dp
>
957 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
959 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
961 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
965 /// unique_ptr comparison with nullptr
966 template<typename _Tp
, typename _Dp
>
967 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
969 operator>(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
971 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
975 /// Relational operator for unique_ptr objects, compares the owned pointers
976 template<typename _Tp
, typename _Dp
,
977 typename _Up
, typename _Ep
>
978 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
980 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
,
981 const unique_ptr
<_Up
, _Ep
>& __y
)
982 { return !(__x
< __y
); }
984 /// unique_ptr comparison with nullptr
985 template<typename _Tp
, typename _Dp
>
986 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
988 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
989 { return !(__x
< nullptr); }
991 /// unique_ptr comparison with nullptr
992 template<typename _Tp
, typename _Dp
>
993 _GLIBCXX_NODISCARD
inline bool
994 operator>=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
995 { return !(nullptr < __x
); }
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
>
1001 _GLIBCXX23_CONSTEXPR
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()); }
1009 template<typename _Tp
, typename _Dp
>
1010 requires three_way_comparable
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
1011 _GLIBCXX23_CONSTEXPR
1013 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
1014 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
1016 using pointer
= typename unique_ptr
<_Tp
, _Dp
>::pointer
;
1017 return compare_three_way()(__x
.get(), static_cast<pointer
>(nullptr));
1020 /// @} relates unique_ptr
1022 /// @cond undocumented
1023 template<typename _Up
, typename _Ptr
= typename
_Up::pointer
>
1024 struct __uniq_ptr_hash
1025 : public __hash_base
<size_t, _Up
>
1026 #if ! _GLIBCXX_INLINE_VERSION
1027 , private __hash_empty_base
<_Ptr
>
1031 operator()(const _Up
& __u
) const
1032 noexcept(noexcept(std::declval
<hash
<_Ptr
>>()(std::declval
<_Ptr
>())))
1033 { return hash
<_Ptr
>()(__u
.get()); }
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
>>;
1043 /// std::hash specialization for unique_ptr.
1044 template<typename _Tp
, typename _Dp
>
1045 struct hash
<unique_ptr
<_Tp
, _Dp
>>
1046 : public __uniq_ptr_hash_base
<unique_ptr
<_Tp
, _Dp
>>
1049 #ifdef __glibcxx_make_unique // C++ >= 14 && HOSTED
1050 /// @cond undocumented
1053 template<typename _Tp
>
1055 { typedef unique_ptr
<_Tp
> __single_object
; };
1057 template<typename _Tp
>
1058 struct _MakeUniq
<_Tp
[]>
1059 { typedef unique_ptr
<_Tp
[]> __array
; };
1061 template<typename _Tp
, size_t _Bound
>
1062 struct _MakeUniq
<_Tp
[_Bound
]>
1063 { struct __invalid_type
{ }; };
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
;
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.
1079 * @relates unique_ptr
1081 template<typename _Tp
, typename
... _Args
>
1082 _GLIBCXX23_CONSTEXPR
1083 inline __detail::__unique_ptr_t
<_Tp
>
1084 make_unique(_Args
&&... __args
)
1085 { return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...)); }
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.
1092 * @relates unique_ptr
1094 * The array elements are value-initialized.
1096 template<typename _Tp
>
1097 _GLIBCXX23_CONSTEXPR
1098 inline __detail::__unique_ptr_array_t
<_Tp
>
1099 make_unique(size_t __num
)
1100 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]()); }
1102 /** Disable std::make_unique for arrays of known bound.
1103 * @tparam _Tp An array type of known bound, such as `U[N]`.
1105 * @relates unique_ptr
1107 template<typename _Tp
, typename
... _Args
>
1108 __detail::__invalid_make_unique_t
<_Tp
>
1109 make_unique(_Args
&&...) = delete;
1111 #if __cplusplus > 201703L
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.
1116 * @relates unique_ptr
1118 template<typename _Tp
>
1119 _GLIBCXX23_CONSTEXPR
1120 inline __detail::__unique_ptr_t
<_Tp
>
1121 make_unique_for_overwrite()
1122 { return unique_ptr
<_Tp
>(new _Tp
); }
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.
1129 * @relates unique_ptr
1131 template<typename _Tp
>
1132 _GLIBCXX23_CONSTEXPR
1133 inline __detail::__unique_ptr_array_t
<_Tp
>
1134 make_unique_for_overwrite(size_t __num
)
1135 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]); }
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]`.
1140 * @relates unique_ptr
1142 template<typename _Tp
, typename
... _Args
>
1143 __detail::__invalid_make_unique_t
<_Tp
>
1144 make_unique_for_overwrite(_Args
&&...) = delete;
1147 #endif // C++14 && HOSTED
1149 #if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
1150 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1151 // 2948. unique_ptr does not define operator<< for stream output
1152 /// Stream output operator for unique_ptr
1153 /// @relates unique_ptr
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(); }
1164 #endif // C++20 && HOSTED
1166 #if __cpp_variable_templates
1167 template<typename _Tp
>
1168 constexpr bool __is_unique_ptr
= false;
1169 template<typename _Tp
, typename _Del
>
1170 constexpr bool __is_unique_ptr
<unique_ptr
<_Tp
, _Del
>> = true;
1173 /// @} group pointer_abstractions
1175 #if __cplusplus >= 201703L
1176 namespace __detail::__variant
1178 template<typename
> struct _Never_valueless_alt
; // see <variant>
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
>>
1186 } // namespace __detail::__variant
1189 _GLIBCXX_END_NAMESPACE_VERSION
1192 #endif /* _UNIQUE_PTR_H */