1 // unique_ptr implementation -*- C++ -*-
3 // Copyright (C) 2008-2023 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
31 #define _UNIQUE_PTR_H 1
33 #include <bits/c++config.h>
34 #include <debug/assertions.h>
35 #include <type_traits>
37 #include <bits/stl_function.h>
38 #include <bits/functional_hash.h>
39 #if __cplusplus >= 202002L
46 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
47 # if __cpp_lib_constexpr_memory < 202202L
48 // Defined with older value in bits/ptr_traits.h for C++20
49 # undef __cpp_lib_constexpr_memory
50 # define __cpp_lib_constexpr_memory 202202L
54 namespace std
_GLIBCXX_VISIBILITY(default)
56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 * @addtogroup pointer_abstractions
63 #if _GLIBCXX_USE_DEPRECATED
64 #pragma GCC diagnostic push
65 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
66 template<typename
> class auto_ptr
;
67 #pragma GCC diagnostic pop
70 /** Primary template of default_delete, used by unique_ptr for single objects
75 template<typename _Tp
>
78 /// Default constructor
79 constexpr default_delete() noexcept
= default;
81 /** @brief Converting constructor.
83 * Allows conversion from a deleter for objects of another type, `_Up`,
84 * only if `_Up*` is convertible to `_Tp*`.
86 template<typename _Up
,
87 typename
= _Require
<is_convertible
<_Up
*, _Tp
*>>>
89 default_delete(const default_delete
<_Up
>&) noexcept
{ }
91 /// Calls `delete __ptr`
94 operator()(_Tp
* __ptr
) const
96 static_assert(!is_void
<_Tp
>::value
,
97 "can't delete pointer to incomplete type");
98 static_assert(sizeof(_Tp
)>0,
99 "can't delete pointer to incomplete type");
104 // _GLIBCXX_RESOLVE_LIB_DEFECTS
105 // DR 740 - omit specialization for array objects with a compile time length
107 /** Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
112 template<typename _Tp
>
113 struct default_delete
<_Tp
[]>
116 /// Default constructor
117 constexpr default_delete() noexcept
= default;
119 /** @brief Converting constructor.
121 * Allows conversion from a deleter for arrays of another type, such as
122 * a const-qualified version of `_Tp`.
124 * Conversions from types derived from `_Tp` are not allowed because
125 * it is undefined to `delete[]` an array of derived types through a
126 * pointer to the base type.
128 template<typename _Up
,
129 typename
= _Require
<is_convertible
<_Up(*)[], _Tp(*)[]>>>
131 default_delete(const default_delete
<_Up
[]>&) noexcept
{ }
133 /// Calls `delete[] __ptr`
134 template<typename _Up
>
136 typename enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
>::type
137 operator()(_Up
* __ptr
) const
139 static_assert(sizeof(_Tp
)>0,
140 "can't delete pointer to incomplete type");
145 /// @cond undocumented
147 // Manages the pointer and deleter of a unique_ptr
148 template <typename _Tp
, typename _Dp
>
149 class __uniq_ptr_impl
151 template <typename _Up
, typename _Ep
, typename
= void>
157 template <typename _Up
, typename _Ep
>
159 _Ptr
<_Up
, _Ep
, __void_t
<typename remove_reference
<_Ep
>::type::pointer
>>
161 using type
= typename remove_reference
<_Ep
>::type::pointer
;
165 using _DeleterConstraint
= enable_if
<
166 __and_
<__not_
<is_pointer
<_Dp
>>,
167 is_default_constructible
<_Dp
>>::value
>;
169 using pointer
= typename _Ptr
<_Tp
, _Dp
>::type
;
171 static_assert( !is_rvalue_reference
<_Dp
>::value
,
172 "unique_ptr's deleter type must be a function object type"
173 " or an lvalue reference type" );
175 __uniq_ptr_impl() = default;
177 __uniq_ptr_impl(pointer __p
) : _M_t() { _M_ptr() = __p
; }
179 template<typename _Del
>
181 __uniq_ptr_impl(pointer __p
, _Del
&& __d
)
182 : _M_t(__p
, std::forward
<_Del
>(__d
)) { }
185 __uniq_ptr_impl(__uniq_ptr_impl
&& __u
) noexcept
186 : _M_t(std::move(__u
._M_t
))
187 { __u
._M_ptr() = nullptr; }
190 __uniq_ptr_impl
& operator=(__uniq_ptr_impl
&& __u
) noexcept
192 reset(__u
.release());
193 _M_deleter() = std::forward
<_Dp
>(__u
._M_deleter());
198 pointer
& _M_ptr() noexcept
{ return std::get
<0>(_M_t
); }
200 pointer
_M_ptr() const noexcept
{ return std::get
<0>(_M_t
); }
202 _Dp
& _M_deleter() noexcept
{ return std::get
<1>(_M_t
); }
204 const _Dp
& _M_deleter() const noexcept
{ return std::get
<1>(_M_t
); }
207 void reset(pointer __p
) noexcept
209 const pointer __old_p
= _M_ptr();
212 _M_deleter()(__old_p
);
216 pointer
release() noexcept
218 pointer __p
= _M_ptr();
225 swap(__uniq_ptr_impl
& __rhs
) noexcept
228 swap(this->_M_ptr(), __rhs
._M_ptr());
229 swap(this->_M_deleter(), __rhs
._M_deleter());
233 tuple
<pointer
, _Dp
> _M_t
;
236 // Defines move construction + assignment as either defaulted or deleted.
237 template <typename _Tp
, typename _Dp
,
238 bool = is_move_constructible
<_Dp
>::value
,
239 bool = is_move_assignable
<_Dp
>::value
>
240 struct __uniq_ptr_data
: __uniq_ptr_impl
<_Tp
, _Dp
>
242 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
243 __uniq_ptr_data(__uniq_ptr_data
&&) = default;
244 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = default;
247 template <typename _Tp
, typename _Dp
>
248 struct __uniq_ptr_data
<_Tp
, _Dp
, true, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
250 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
251 __uniq_ptr_data(__uniq_ptr_data
&&) = default;
252 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = delete;
255 template <typename _Tp
, typename _Dp
>
256 struct __uniq_ptr_data
<_Tp
, _Dp
, false, true> : __uniq_ptr_impl
<_Tp
, _Dp
>
258 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
259 __uniq_ptr_data(__uniq_ptr_data
&&) = delete;
260 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = default;
263 template <typename _Tp
, typename _Dp
>
264 struct __uniq_ptr_data
<_Tp
, _Dp
, false, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
266 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
267 __uniq_ptr_data(__uniq_ptr_data
&&) = delete;
268 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = delete;
272 // 20.7.1.2 unique_ptr for single objects.
274 /// A move-only smart pointer that manages unique ownership of a resource.
275 /// @headerfile memory
277 template <typename _Tp
, typename _Dp
= default_delete
<_Tp
>>
280 template <typename _Up
>
281 using _DeleterConstraint
=
282 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
284 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
287 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
288 using element_type
= _Tp
;
289 using deleter_type
= _Dp
;
292 // helper template for detecting a safe conversion from another
294 template<typename _Up
, typename _Ep
>
295 using __safe_conversion_up
= __and_
<
296 is_convertible
<typename unique_ptr
<_Up
, _Ep
>::pointer
, pointer
>,
297 __not_
<is_array
<_Up
>>
303 /// Default constructor, creates a unique_ptr that owns nothing.
304 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
305 constexpr unique_ptr() noexcept
309 /** Takes ownership of a pointer.
311 * @param __p A pointer to an object of @c element_type
313 * The deleter will be value-initialized.
315 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
318 unique_ptr(pointer __p
) noexcept
322 /** Takes ownership of a pointer.
324 * @param __p A pointer to an object of @c element_type
325 * @param __d A reference to a deleter.
327 * The deleter will be initialized with @p __d
329 template<typename _Del
= deleter_type
,
330 typename
= _Require
<is_copy_constructible
<_Del
>>>
332 unique_ptr(pointer __p
, const deleter_type
& __d
) noexcept
335 /** Takes ownership of a pointer.
337 * @param __p A pointer to an object of @c element_type
338 * @param __d An rvalue reference to a (non-reference) deleter.
340 * The deleter will be initialized with @p std::move(__d)
342 template<typename _Del
= deleter_type
,
343 typename
= _Require
<is_move_constructible
<_Del
>>>
345 unique_ptr(pointer __p
,
346 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
347 _Del
&&> __d
) noexcept
348 : _M_t(__p
, std::move(__d
))
351 template<typename _Del
= deleter_type
,
352 typename _DelUnref
= typename remove_reference
<_Del
>::type
>
355 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
356 _DelUnref
&&>) = delete;
358 /// Creates a unique_ptr that owns nothing.
359 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
360 constexpr unique_ptr(nullptr_t
) noexcept
364 // Move constructors.
366 /// Move constructor.
367 unique_ptr(unique_ptr
&&) = default;
369 /** @brief Converting constructor from another type
371 * Requires that the pointer owned by @p __u is convertible to the
372 * type of pointer owned by this object, @p __u does not own an array,
373 * and @p __u has a compatible deleter type.
375 template<typename _Up
, typename _Ep
, typename
= _Require
<
376 __safe_conversion_up
<_Up
, _Ep
>,
377 __conditional_t
<is_reference
<_Dp
>::value
,
379 is_convertible
<_Ep
, _Dp
>>>>
381 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
382 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
385 #if _GLIBCXX_USE_DEPRECATED
386 #pragma GCC diagnostic push
387 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
388 /// Converting constructor from @c auto_ptr
389 template<typename _Up
, typename
= _Require
<
390 is_convertible
<_Up
*, _Tp
*>, is_same
<_Dp
, default_delete
<_Tp
>>>>
391 unique_ptr(auto_ptr
<_Up
>&& __u
) noexcept
;
392 #pragma GCC diagnostic pop
395 /// Destructor, invokes the deleter if the stored pointer is not null.
396 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
399 ~unique_ptr() noexcept
401 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
402 "unique_ptr's deleter must be invocable with a pointer");
403 auto& __ptr
= _M_t
._M_ptr();
404 if (__ptr
!= nullptr)
405 get_deleter()(std::move(__ptr
));
411 /** @brief Move assignment operator.
413 * Invokes the deleter if this object owns a pointer.
415 unique_ptr
& operator=(unique_ptr
&&) = default;
417 /** @brief Assignment from another type.
419 * @param __u The object to transfer ownership from, which owns a
420 * convertible pointer to a non-array object.
422 * Invokes the deleter if this object owns a pointer.
424 template<typename _Up
, typename _Ep
>
426 typename enable_if
< __and_
<
427 __safe_conversion_up
<_Up
, _Ep
>,
428 is_assignable
<deleter_type
&, _Ep
&&>
431 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
433 reset(__u
.release());
434 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
438 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
441 operator=(nullptr_t
) noexcept
449 /// Dereference the stored pointer.
451 typename add_lvalue_reference
<element_type
>::type
452 operator*() const noexcept(noexcept(*std::declval
<pointer
>()))
454 __glibcxx_assert(get() != pointer());
458 /// Return the stored pointer.
461 operator->() const noexcept
463 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
467 /// Return the stored pointer.
471 { return _M_t
._M_ptr(); }
473 /// Return a reference to the stored deleter.
476 get_deleter() noexcept
477 { return _M_t
._M_deleter(); }
479 /// Return a reference to the stored deleter.
482 get_deleter() const noexcept
483 { return _M_t
._M_deleter(); }
485 /// Return @c true if the stored pointer is not null.
487 explicit operator bool() const noexcept
488 { return get() == pointer() ? false : true; }
492 /// Release ownership of any stored pointer.
496 { return _M_t
.release(); }
498 /** @brief Replace the stored pointer.
500 * @param __p The new pointer to store.
502 * The deleter will be invoked if a pointer is already owned.
506 reset(pointer __p
= pointer()) noexcept
508 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
509 "unique_ptr's deleter must be invocable with a pointer");
510 _M_t
.reset(std::move(__p
));
513 /// Exchange the pointer and deleter with another object.
516 swap(unique_ptr
& __u
) noexcept
518 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
522 // Disable copy from lvalue.
523 unique_ptr(const unique_ptr
&) = delete;
524 unique_ptr
& operator=(const unique_ptr
&) = delete;
527 // 20.7.1.3 unique_ptr for array objects with a runtime length
528 // [unique.ptr.runtime]
529 // _GLIBCXX_RESOLVE_LIB_DEFECTS
530 // DR 740 - omit specialization for array objects with a compile time length
532 /// A move-only smart pointer that manages unique ownership of an array.
533 /// @headerfile memory
535 template<typename _Tp
, typename _Dp
>
536 class unique_ptr
<_Tp
[], _Dp
>
538 template <typename _Up
>
539 using _DeleterConstraint
=
540 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
542 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
544 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
545 template<typename _Up
>
546 using __is_derived_Tp
547 = __and_
< is_base_of
<_Tp
, _Up
>,
548 __not_
<is_same
<__remove_cv_t
<_Tp
>, __remove_cv_t
<_Up
>>> >;
551 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
552 using element_type
= _Tp
;
553 using deleter_type
= _Dp
;
555 // helper template for detecting a safe conversion from another
557 template<typename _Up
, typename _Ep
,
558 typename _UPtr
= unique_ptr
<_Up
, _Ep
>,
559 typename _UP_pointer
= typename
_UPtr::pointer
,
560 typename _UP_element_type
= typename
_UPtr::element_type
>
561 using __safe_conversion_up
= __and_
<
563 is_same
<pointer
, element_type
*>,
564 is_same
<_UP_pointer
, _UP_element_type
*>,
565 is_convertible
<_UP_element_type(*)[], element_type(*)[]>
568 // helper template for detecting a safe conversion from a raw pointer
569 template<typename _Up
>
570 using __safe_conversion_raw
= __and_
<
571 __or_
<__or_
<is_same
<_Up
, pointer
>,
572 is_same
<_Up
, nullptr_t
>>,
573 __and_
<is_pointer
<_Up
>,
574 is_same
<pointer
, element_type
*>,
576 typename remove_pointer
<_Up
>::type(*)[],
584 /// Default constructor, creates a unique_ptr that owns nothing.
585 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
586 constexpr unique_ptr() noexcept
590 /** Takes ownership of a pointer.
592 * @param __p A pointer to an array of a type safely convertible
593 * to an array of @c element_type
595 * The deleter will be value-initialized.
597 template<typename _Up
,
599 typename
= _DeleterConstraint
<_Vp
>,
600 typename
= typename enable_if
<
601 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
604 unique_ptr(_Up __p
) noexcept
608 /** Takes ownership of a pointer.
610 * @param __p A pointer to an array of a type safely convertible
611 * to an array of @c element_type
612 * @param __d A reference to a deleter.
614 * The deleter will be initialized with @p __d
616 template<typename _Up
, typename _Del
= deleter_type
,
617 typename
= _Require
<__safe_conversion_raw
<_Up
>,
618 is_copy_constructible
<_Del
>>>
620 unique_ptr(_Up __p
, const deleter_type
& __d
) noexcept
623 /** Takes ownership of a pointer.
625 * @param __p A pointer to an array of a type safely convertible
626 * to an array of @c element_type
627 * @param __d A reference to a deleter.
629 * The deleter will be initialized with @p std::move(__d)
631 template<typename _Up
, typename _Del
= deleter_type
,
632 typename
= _Require
<__safe_conversion_raw
<_Up
>,
633 is_move_constructible
<_Del
>>>
636 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
637 _Del
&&> __d
) noexcept
638 : _M_t(std::move(__p
), std::move(__d
))
641 template<typename _Up
, typename _Del
= deleter_type
,
642 typename _DelUnref
= typename remove_reference
<_Del
>::type
,
643 typename
= _Require
<__safe_conversion_raw
<_Up
>>>
645 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
646 _DelUnref
&&>) = delete;
648 /// Move constructor.
649 unique_ptr(unique_ptr
&&) = default;
651 /// Creates a unique_ptr that owns nothing.
652 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
653 constexpr unique_ptr(nullptr_t
) noexcept
657 template<typename _Up
, typename _Ep
, typename
= _Require
<
658 __safe_conversion_up
<_Up
, _Ep
>,
659 __conditional_t
<is_reference
<_Dp
>::value
,
661 is_convertible
<_Ep
, _Dp
>>>>
663 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
664 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
667 /// Destructor, invokes the deleter if the stored pointer is not null.
668 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
673 auto& __ptr
= _M_t
._M_ptr();
674 if (__ptr
!= nullptr)
675 get_deleter()(__ptr
);
681 /** @brief Move assignment operator.
683 * Invokes the deleter if this object owns a pointer.
686 operator=(unique_ptr
&&) = default;
688 /** @brief Assignment from another type.
690 * @param __u The object to transfer ownership from, which owns a
691 * convertible pointer to an array object.
693 * Invokes the deleter if this object owns a pointer.
695 template<typename _Up
, typename _Ep
>
698 enable_if
<__and_
<__safe_conversion_up
<_Up
, _Ep
>,
699 is_assignable
<deleter_type
&, _Ep
&&>
702 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
704 reset(__u
.release());
705 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
709 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
712 operator=(nullptr_t
) noexcept
720 /// Access an element of owned array.
722 typename
std::add_lvalue_reference
<element_type
>::type
723 operator[](size_t __i
) const
725 __glibcxx_assert(get() != pointer());
729 /// Return the stored pointer.
733 { return _M_t
._M_ptr(); }
735 /// Return a reference to the stored deleter.
738 get_deleter() noexcept
739 { return _M_t
._M_deleter(); }
741 /// Return a reference to the stored deleter.
744 get_deleter() const noexcept
745 { return _M_t
._M_deleter(); }
747 /// Return @c true if the stored pointer is not null.
749 explicit operator bool() const noexcept
750 { return get() == pointer() ? false : true; }
754 /// Release ownership of any stored pointer.
758 { return _M_t
.release(); }
760 /** @brief Replace the stored pointer.
762 * @param __p The new pointer to store.
764 * The deleter will be invoked if a pointer is already owned.
766 template <typename _Up
,
768 __or_
<is_same
<_Up
, pointer
>,
769 __and_
<is_same
<pointer
, element_type
*>,
772 typename remove_pointer
<_Up
>::type(*)[],
780 reset(_Up __p
) noexcept
781 { _M_t
.reset(std::move(__p
)); }
784 void reset(nullptr_t
= nullptr) noexcept
785 { reset(pointer()); }
787 /// Exchange the pointer and deleter with another object.
790 swap(unique_ptr
& __u
) noexcept
792 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
796 // Disable copy from lvalue.
797 unique_ptr(const unique_ptr
&) = delete;
798 unique_ptr
& operator=(const unique_ptr
&) = delete;
802 /// @relates unique_ptr
804 /// Swap overload for unique_ptr
805 template<typename _Tp
, typename _Dp
>
807 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
808 // Constrained free swap overload, see p0185r1
810 typename enable_if
<__is_swappable
<_Dp
>::value
>::type
814 swap(unique_ptr
<_Tp
, _Dp
>& __x
,
815 unique_ptr
<_Tp
, _Dp
>& __y
) noexcept
818 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
819 template<typename _Tp
, typename _Dp
>
820 typename enable_if
<!__is_swappable
<_Dp
>::value
>::type
821 swap(unique_ptr
<_Tp
, _Dp
>&,
822 unique_ptr
<_Tp
, _Dp
>&) = delete;
825 /// Equality operator for unique_ptr objects, compares the owned pointers
826 template<typename _Tp
, typename _Dp
,
827 typename _Up
, typename _Ep
>
828 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
830 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
,
831 const unique_ptr
<_Up
, _Ep
>& __y
)
832 { return __x
.get() == __y
.get(); }
834 /// unique_ptr comparison with nullptr
835 template<typename _Tp
, typename _Dp
>
836 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
838 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
841 #ifndef __cpp_lib_three_way_comparison
842 /// unique_ptr comparison with nullptr
843 template<typename _Tp
, typename _Dp
>
846 operator==(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
849 /// Inequality operator for unique_ptr objects, compares the owned pointers
850 template<typename _Tp
, typename _Dp
,
851 typename _Up
, typename _Ep
>
854 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
,
855 const unique_ptr
<_Up
, _Ep
>& __y
)
856 { return __x
.get() != __y
.get(); }
858 /// unique_ptr comparison with nullptr
859 template<typename _Tp
, typename _Dp
>
862 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
863 { return (bool)__x
; }
865 /// unique_ptr comparison with nullptr
866 template<typename _Tp
, typename _Dp
>
869 operator!=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
870 { return (bool)__x
; }
871 #endif // three way comparison
873 /// Relational operator for unique_ptr objects, compares the owned pointers
874 template<typename _Tp
, typename _Dp
,
875 typename _Up
, typename _Ep
>
876 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
878 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
,
879 const unique_ptr
<_Up
, _Ep
>& __y
)
882 std::common_type
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
883 typename unique_ptr
<_Up
, _Ep
>::pointer
>::type _CT
;
884 return std::less
<_CT
>()(__x
.get(), __y
.get());
887 /// unique_ptr comparison with nullptr
888 template<typename _Tp
, typename _Dp
>
889 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
891 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
893 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
897 /// unique_ptr comparison with nullptr
898 template<typename _Tp
, typename _Dp
>
899 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
901 operator<(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
903 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
907 /// Relational operator for unique_ptr objects, compares the owned pointers
908 template<typename _Tp
, typename _Dp
,
909 typename _Up
, typename _Ep
>
910 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
912 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
,
913 const unique_ptr
<_Up
, _Ep
>& __y
)
914 { return !(__y
< __x
); }
916 /// unique_ptr comparison with nullptr
917 template<typename _Tp
, typename _Dp
>
918 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
920 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
921 { return !(nullptr < __x
); }
923 /// unique_ptr comparison with nullptr
924 template<typename _Tp
, typename _Dp
>
925 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
927 operator<=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
928 { return !(__x
< nullptr); }
930 /// Relational operator for unique_ptr objects, compares the owned pointers
931 template<typename _Tp
, typename _Dp
,
932 typename _Up
, typename _Ep
>
933 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
935 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
,
936 const unique_ptr
<_Up
, _Ep
>& __y
)
937 { return (__y
< __x
); }
939 /// unique_ptr comparison with nullptr
940 template<typename _Tp
, typename _Dp
>
941 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
943 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
945 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
949 /// unique_ptr comparison with nullptr
950 template<typename _Tp
, typename _Dp
>
951 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
953 operator>(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
955 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
959 /// Relational operator for unique_ptr objects, compares the owned pointers
960 template<typename _Tp
, typename _Dp
,
961 typename _Up
, typename _Ep
>
962 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
964 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
,
965 const unique_ptr
<_Up
, _Ep
>& __y
)
966 { return !(__x
< __y
); }
968 /// unique_ptr comparison with nullptr
969 template<typename _Tp
, typename _Dp
>
970 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
972 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
973 { return !(__x
< nullptr); }
975 /// unique_ptr comparison with nullptr
976 template<typename _Tp
, typename _Dp
>
977 _GLIBCXX_NODISCARD
inline bool
978 operator>=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
979 { return !(nullptr < __x
); }
981 #ifdef __cpp_lib_three_way_comparison
982 template<typename _Tp
, typename _Dp
, typename _Up
, typename _Ep
>
983 requires three_way_comparable_with
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
984 typename unique_ptr
<_Up
, _Ep
>::pointer
>
987 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
988 typename unique_ptr
<_Up
, _Ep
>::pointer
>
989 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
,
990 const unique_ptr
<_Up
, _Ep
>& __y
)
991 { return compare_three_way()(__x
.get(), __y
.get()); }
993 template<typename _Tp
, typename _Dp
>
994 requires three_way_comparable
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
997 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
998 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
1000 using pointer
= typename unique_ptr
<_Tp
, _Dp
>::pointer
;
1001 return compare_three_way()(__x
.get(), static_cast<pointer
>(nullptr));
1004 /// @} relates unique_ptr
1006 /// @cond undocumented
1007 template<typename _Up
, typename _Ptr
= typename
_Up::pointer
,
1008 bool = __poison_hash
<_Ptr
>::__enable_hash_call
>
1009 struct __uniq_ptr_hash
1010 #if ! _GLIBCXX_INLINE_VERSION
1011 : private __poison_hash
<_Ptr
>
1015 operator()(const _Up
& __u
) const
1016 noexcept(noexcept(std::declval
<hash
<_Ptr
>>()(std::declval
<_Ptr
>())))
1017 { return hash
<_Ptr
>()(__u
.get()); }
1020 template<typename _Up
, typename _Ptr
>
1021 struct __uniq_ptr_hash
<_Up
, _Ptr
, false>
1022 : private __poison_hash
<_Ptr
>
1026 /// std::hash specialization for unique_ptr.
1027 template<typename _Tp
, typename _Dp
>
1028 struct hash
<unique_ptr
<_Tp
, _Dp
>>
1029 : public __hash_base
<size_t, unique_ptr
<_Tp
, _Dp
>>,
1030 public __uniq_ptr_hash
<unique_ptr
<_Tp
, _Dp
>>
1033 #if __cplusplus >= 201402L && _GLIBCXX_HOSTED
1034 #define __cpp_lib_make_unique 201304L
1036 /// @cond undocumented
1039 template<typename _Tp
>
1041 { typedef unique_ptr
<_Tp
> __single_object
; };
1043 template<typename _Tp
>
1044 struct _MakeUniq
<_Tp
[]>
1045 { typedef unique_ptr
<_Tp
[]> __array
; };
1047 template<typename _Tp
, size_t _Bound
>
1048 struct _MakeUniq
<_Tp
[_Bound
]>
1049 { struct __invalid_type
{ }; };
1051 template<typename _Tp
>
1052 using __unique_ptr_t
= typename _MakeUniq
<_Tp
>::__single_object
;
1053 template<typename _Tp
>
1054 using __unique_ptr_array_t
= typename _MakeUniq
<_Tp
>::__array
;
1055 template<typename _Tp
>
1056 using __invalid_make_unique_t
= typename _MakeUniq
<_Tp
>::__invalid_type
;
1060 /** Create an object owned by a `unique_ptr`.
1061 * @tparam _Tp A non-array object type.
1062 * @param __args Constructor arguments for the new object.
1063 * @returns A `unique_ptr<_Tp>` that owns the new object.
1065 * @relates unique_ptr
1067 template<typename _Tp
, typename
... _Args
>
1068 _GLIBCXX23_CONSTEXPR
1069 inline __detail::__unique_ptr_t
<_Tp
>
1070 make_unique(_Args
&&... __args
)
1071 { return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...)); }
1073 /** Create an array owned by a `unique_ptr`.
1074 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1075 * @param __num The number of elements of type `U` in the new array.
1076 * @returns A `unique_ptr<U[]>` that owns the new array.
1078 * @relates unique_ptr
1080 * The array elements are value-initialized.
1082 template<typename _Tp
>
1083 _GLIBCXX23_CONSTEXPR
1084 inline __detail::__unique_ptr_array_t
<_Tp
>
1085 make_unique(size_t __num
)
1086 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]()); }
1088 /** Disable std::make_unique for arrays of known bound.
1089 * @tparam _Tp An array type of known bound, such as `U[N]`.
1091 * @relates unique_ptr
1093 template<typename _Tp
, typename
... _Args
>
1094 __detail::__invalid_make_unique_t
<_Tp
>
1095 make_unique(_Args
&&...) = delete;
1097 #if __cplusplus > 201703L
1098 /** Create a default-initialied object owned by a `unique_ptr`.
1099 * @tparam _Tp A non-array object type.
1100 * @returns A `unique_ptr<_Tp>` that owns the new object.
1102 * @relates unique_ptr
1104 template<typename _Tp
>
1105 _GLIBCXX23_CONSTEXPR
1106 inline __detail::__unique_ptr_t
<_Tp
>
1107 make_unique_for_overwrite()
1108 { return unique_ptr
<_Tp
>(new _Tp
); }
1110 /** Create a default-initialized array owned by a `unique_ptr`.
1111 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1112 * @param __num The number of elements of type `U` in the new array.
1113 * @returns A `unique_ptr<U[]>` that owns the new array.
1115 * @relates unique_ptr
1117 template<typename _Tp
>
1118 _GLIBCXX23_CONSTEXPR
1119 inline __detail::__unique_ptr_array_t
<_Tp
>
1120 make_unique_for_overwrite(size_t __num
)
1121 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]); }
1123 /** Disable std::make_unique_for_overwrite for arrays of known bound.
1124 * @tparam _Tp An array type of known bound, such as `U[N]`.
1126 * @relates unique_ptr
1128 template<typename _Tp
, typename
... _Args
>
1129 __detail::__invalid_make_unique_t
<_Tp
>
1130 make_unique_for_overwrite(_Args
&&...) = delete;
1133 #endif // C++14 && HOSTED
1135 #if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
1136 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1137 // 2948. unique_ptr does not define operator<< for stream output
1138 /// Stream output operator for unique_ptr
1139 /// @relates unique_ptr
1141 template<typename _CharT
, typename _Traits
, typename _Tp
, typename _Dp
>
1142 inline basic_ostream
<_CharT
, _Traits
>&
1143 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
1144 const unique_ptr
<_Tp
, _Dp
>& __p
)
1145 requires requires
{ __os
<< __p
.get(); }
1150 #endif // C++20 && HOSTED
1152 /// @} group pointer_abstractions
1154 #if __cplusplus >= 201703L
1155 namespace __detail::__variant
1157 template<typename
> struct _Never_valueless_alt
; // see <variant>
1159 // Provide the strong exception-safety guarantee when emplacing a
1160 // unique_ptr into a variant.
1161 template<typename _Tp
, typename _Del
>
1162 struct _Never_valueless_alt
<std::unique_ptr
<_Tp
, _Del
>>
1165 } // namespace __detail::__variant
1168 _GLIBCXX_END_NAMESPACE_VERSION
1171 #endif /* _UNIQUE_PTR_H */