1 // unique_ptr implementation -*- C++ -*-
3 // Copyright (C) 2008-2021 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>
38 #include <bits/stl_function.h>
39 #include <bits/functional_hash.h>
40 #if __cplusplus > 201703L
45 namespace std
_GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 * @addtogroup pointer_abstractions
54 #if _GLIBCXX_USE_DEPRECATED
55 #pragma GCC diagnostic push
56 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
57 template<typename
> class auto_ptr
;
58 #pragma GCC diagnostic pop
61 /// Primary template of default_delete, used by unique_ptr for single objects
62 template<typename _Tp
>
65 /// Default constructor
66 constexpr default_delete() noexcept
= default;
68 /** @brief Converting constructor.
70 * Allows conversion from a deleter for objects of another type, `_Up`,
71 * only if `_Up*` is convertible to `_Tp*`.
73 template<typename _Up
,
74 typename
= _Require
<is_convertible
<_Up
*, _Tp
*>>>
75 default_delete(const default_delete
<_Up
>&) noexcept
{ }
77 /// Calls `delete __ptr`
79 operator()(_Tp
* __ptr
) const
81 static_assert(!is_void
<_Tp
>::value
,
82 "can't delete pointer to incomplete type");
83 static_assert(sizeof(_Tp
)>0,
84 "can't delete pointer to incomplete type");
89 // _GLIBCXX_RESOLVE_LIB_DEFECTS
90 // DR 740 - omit specialization for array objects with a compile time length
92 /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
93 template<typename _Tp
>
94 struct default_delete
<_Tp
[]>
97 /// Default constructor
98 constexpr default_delete() noexcept
= default;
100 /** @brief Converting constructor.
102 * Allows conversion from a deleter for arrays of another type, such as
103 * a const-qualified version of `_Tp`.
105 * Conversions from types derived from `_Tp` are not allowed because
106 * it is undefined to `delete[]` an array of derived types through a
107 * pointer to the base type.
109 template<typename _Up
,
110 typename
= _Require
<is_convertible
<_Up(*)[], _Tp(*)[]>>>
111 default_delete(const default_delete
<_Up
[]>&) noexcept
{ }
113 /// Calls `delete[] __ptr`
114 template<typename _Up
>
115 typename enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
>::type
116 operator()(_Up
* __ptr
) const
118 static_assert(sizeof(_Tp
)>0,
119 "can't delete pointer to incomplete type");
124 /// @cond undocumented
126 // Manages the pointer and deleter of a unique_ptr
127 template <typename _Tp
, typename _Dp
>
128 class __uniq_ptr_impl
130 template <typename _Up
, typename _Ep
, typename
= void>
136 template <typename _Up
, typename _Ep
>
138 _Ptr
<_Up
, _Ep
, __void_t
<typename remove_reference
<_Ep
>::type::pointer
>>
140 using type
= typename remove_reference
<_Ep
>::type::pointer
;
144 using _DeleterConstraint
= enable_if
<
145 __and_
<__not_
<is_pointer
<_Dp
>>,
146 is_default_constructible
<_Dp
>>::value
>;
148 using pointer
= typename _Ptr
<_Tp
, _Dp
>::type
;
150 static_assert( !is_rvalue_reference
<_Dp
>::value
,
151 "unique_ptr's deleter type must be a function object type"
152 " or an lvalue reference type" );
154 __uniq_ptr_impl() = default;
155 __uniq_ptr_impl(pointer __p
) : _M_t() { _M_ptr() = __p
; }
157 template<typename _Del
>
158 __uniq_ptr_impl(pointer __p
, _Del
&& __d
)
159 : _M_t(__p
, std::forward
<_Del
>(__d
)) { }
161 __uniq_ptr_impl(__uniq_ptr_impl
&& __u
) noexcept
162 : _M_t(std::move(__u
._M_t
))
163 { __u
._M_ptr() = nullptr; }
165 __uniq_ptr_impl
& operator=(__uniq_ptr_impl
&& __u
) noexcept
167 reset(__u
.release());
168 _M_deleter() = std::forward
<_Dp
>(__u
._M_deleter());
172 pointer
& _M_ptr() { return std::get
<0>(_M_t
); }
173 pointer
_M_ptr() const { return std::get
<0>(_M_t
); }
174 _Dp
& _M_deleter() { return std::get
<1>(_M_t
); }
175 const _Dp
& _M_deleter() const { return std::get
<1>(_M_t
); }
177 void reset(pointer __p
) noexcept
179 const pointer __old_p
= _M_ptr();
182 _M_deleter()(__old_p
);
185 pointer
release() noexcept
187 pointer __p
= _M_ptr();
193 swap(__uniq_ptr_impl
& __rhs
) noexcept
196 swap(this->_M_ptr(), __rhs
._M_ptr());
197 swap(this->_M_deleter(), __rhs
._M_deleter());
201 tuple
<pointer
, _Dp
> _M_t
;
204 // Defines move construction + assignment as either defaulted or deleted.
205 template <typename _Tp
, typename _Dp
,
206 bool = is_move_constructible
<_Dp
>::value
,
207 bool = is_move_assignable
<_Dp
>::value
>
208 struct __uniq_ptr_data
: __uniq_ptr_impl
<_Tp
, _Dp
>
210 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
211 __uniq_ptr_data(__uniq_ptr_data
&&) = default;
212 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = default;
215 template <typename _Tp
, typename _Dp
>
216 struct __uniq_ptr_data
<_Tp
, _Dp
, true, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
218 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
219 __uniq_ptr_data(__uniq_ptr_data
&&) = default;
220 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = delete;
223 template <typename _Tp
, typename _Dp
>
224 struct __uniq_ptr_data
<_Tp
, _Dp
, false, true> : __uniq_ptr_impl
<_Tp
, _Dp
>
226 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
227 __uniq_ptr_data(__uniq_ptr_data
&&) = delete;
228 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = default;
231 template <typename _Tp
, typename _Dp
>
232 struct __uniq_ptr_data
<_Tp
, _Dp
, false, false> : __uniq_ptr_impl
<_Tp
, _Dp
>
234 using __uniq_ptr_impl
<_Tp
, _Dp
>::__uniq_ptr_impl
;
235 __uniq_ptr_data(__uniq_ptr_data
&&) = delete;
236 __uniq_ptr_data
& operator=(__uniq_ptr_data
&&) = delete;
240 /// 20.7.1.2 unique_ptr for single objects.
241 template <typename _Tp
, typename _Dp
= default_delete
<_Tp
>>
244 template <typename _Up
>
245 using _DeleterConstraint
=
246 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
248 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
251 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
252 using element_type
= _Tp
;
253 using deleter_type
= _Dp
;
256 // helper template for detecting a safe conversion from another
258 template<typename _Up
, typename _Ep
>
259 using __safe_conversion_up
= __and_
<
260 is_convertible
<typename unique_ptr
<_Up
, _Ep
>::pointer
, pointer
>,
261 __not_
<is_array
<_Up
>>
267 /// Default constructor, creates a unique_ptr that owns nothing.
268 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
269 constexpr unique_ptr() noexcept
273 /** Takes ownership of a pointer.
275 * @param __p A pointer to an object of @c element_type
277 * The deleter will be value-initialized.
279 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
281 unique_ptr(pointer __p
) noexcept
285 /** Takes ownership of a pointer.
287 * @param __p A pointer to an object of @c element_type
288 * @param __d A reference to a deleter.
290 * The deleter will be initialized with @p __d
292 template<typename _Del
= deleter_type
,
293 typename
= _Require
<is_copy_constructible
<_Del
>>>
294 unique_ptr(pointer __p
, const deleter_type
& __d
) noexcept
297 /** Takes ownership of a pointer.
299 * @param __p A pointer to an object of @c element_type
300 * @param __d An rvalue reference to a (non-reference) deleter.
302 * The deleter will be initialized with @p std::move(__d)
304 template<typename _Del
= deleter_type
,
305 typename
= _Require
<is_move_constructible
<_Del
>>>
306 unique_ptr(pointer __p
,
307 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
308 _Del
&&> __d
) noexcept
309 : _M_t(__p
, std::move(__d
))
312 template<typename _Del
= deleter_type
,
313 typename _DelUnref
= typename remove_reference
<_Del
>::type
>
315 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
316 _DelUnref
&&>) = delete;
318 /// Creates a unique_ptr that owns nothing.
319 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
320 constexpr unique_ptr(nullptr_t
) noexcept
324 // Move constructors.
326 /// Move constructor.
327 unique_ptr(unique_ptr
&&) = default;
329 /** @brief Converting constructor from another type
331 * Requires that the pointer owned by @p __u is convertible to the
332 * type of pointer owned by this object, @p __u does not own an array,
333 * and @p __u has a compatible deleter type.
335 template<typename _Up
, typename _Ep
, typename
= _Require
<
336 __safe_conversion_up
<_Up
, _Ep
>,
337 typename conditional
<is_reference
<_Dp
>::value
,
339 is_convertible
<_Ep
, _Dp
>>::type
>>
340 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
341 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
344 #if _GLIBCXX_USE_DEPRECATED
345 #pragma GCC diagnostic push
346 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
347 /// Converting constructor from @c auto_ptr
348 template<typename _Up
, typename
= _Require
<
349 is_convertible
<_Up
*, _Tp
*>, is_same
<_Dp
, default_delete
<_Tp
>>>>
350 unique_ptr(auto_ptr
<_Up
>&& __u
) noexcept
;
351 #pragma GCC diagnostic pop
354 /// Destructor, invokes the deleter if the stored pointer is not null.
355 ~unique_ptr() noexcept
357 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
358 "unique_ptr's deleter must be invocable with a pointer");
359 auto& __ptr
= _M_t
._M_ptr();
360 if (__ptr
!= nullptr)
361 get_deleter()(std::move(__ptr
));
367 /** @brief Move assignment operator.
369 * Invokes the deleter if this object owns a pointer.
371 unique_ptr
& operator=(unique_ptr
&&) = default;
373 /** @brief Assignment from another type.
375 * @param __u The object to transfer ownership from, which owns a
376 * convertible pointer to a non-array object.
378 * Invokes the deleter if this object owns a pointer.
380 template<typename _Up
, typename _Ep
>
381 typename enable_if
< __and_
<
382 __safe_conversion_up
<_Up
, _Ep
>,
383 is_assignable
<deleter_type
&, _Ep
&&>
386 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
388 reset(__u
.release());
389 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
393 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
395 operator=(nullptr_t
) noexcept
403 /// Dereference the stored pointer.
404 typename add_lvalue_reference
<element_type
>::type
407 __glibcxx_assert(get() != pointer());
411 /// Return the stored pointer.
413 operator->() const noexcept
415 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
419 /// Return the stored pointer.
422 { return _M_t
._M_ptr(); }
424 /// Return a reference to the stored deleter.
426 get_deleter() noexcept
427 { return _M_t
._M_deleter(); }
429 /// Return a reference to the stored deleter.
431 get_deleter() const noexcept
432 { return _M_t
._M_deleter(); }
434 /// Return @c true if the stored pointer is not null.
435 explicit operator bool() const noexcept
436 { return get() == pointer() ? false : true; }
440 /// Release ownership of any stored pointer.
443 { return _M_t
.release(); }
445 /** @brief Replace the stored pointer.
447 * @param __p The new pointer to store.
449 * The deleter will be invoked if a pointer is already owned.
452 reset(pointer __p
= pointer()) noexcept
454 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
455 "unique_ptr's deleter must be invocable with a pointer");
456 _M_t
.reset(std::move(__p
));
459 /// Exchange the pointer and deleter with another object.
461 swap(unique_ptr
& __u
) noexcept
463 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
467 // Disable copy from lvalue.
468 unique_ptr(const unique_ptr
&) = delete;
469 unique_ptr
& operator=(const unique_ptr
&) = delete;
472 /// 20.7.1.3 unique_ptr for array objects with a runtime length
473 // [unique.ptr.runtime]
474 // _GLIBCXX_RESOLVE_LIB_DEFECTS
475 // DR 740 - omit specialization for array objects with a compile time length
476 template<typename _Tp
, typename _Dp
>
477 class unique_ptr
<_Tp
[], _Dp
>
479 template <typename _Up
>
480 using _DeleterConstraint
=
481 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
483 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
485 template<typename _Up
>
486 using __remove_cv
= typename remove_cv
<_Up
>::type
;
488 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
489 template<typename _Up
>
490 using __is_derived_Tp
491 = __and_
< is_base_of
<_Tp
, _Up
>,
492 __not_
<is_same
<__remove_cv
<_Tp
>, __remove_cv
<_Up
>>> >;
495 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
496 using element_type
= _Tp
;
497 using deleter_type
= _Dp
;
499 // helper template for detecting a safe conversion from another
501 template<typename _Up
, typename _Ep
,
502 typename _UPtr
= unique_ptr
<_Up
, _Ep
>,
503 typename _UP_pointer
= typename
_UPtr::pointer
,
504 typename _UP_element_type
= typename
_UPtr::element_type
>
505 using __safe_conversion_up
= __and_
<
507 is_same
<pointer
, element_type
*>,
508 is_same
<_UP_pointer
, _UP_element_type
*>,
509 is_convertible
<_UP_element_type(*)[], element_type(*)[]>
512 // helper template for detecting a safe conversion from a raw pointer
513 template<typename _Up
>
514 using __safe_conversion_raw
= __and_
<
515 __or_
<__or_
<is_same
<_Up
, pointer
>,
516 is_same
<_Up
, nullptr_t
>>,
517 __and_
<is_pointer
<_Up
>,
518 is_same
<pointer
, element_type
*>,
520 typename remove_pointer
<_Up
>::type(*)[],
528 /// Default constructor, creates a unique_ptr that owns nothing.
529 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
530 constexpr unique_ptr() noexcept
534 /** Takes ownership of a pointer.
536 * @param __p A pointer to an array of a type safely convertible
537 * to an array of @c element_type
539 * The deleter will be value-initialized.
541 template<typename _Up
,
543 typename
= _DeleterConstraint
<_Vp
>,
544 typename
= typename enable_if
<
545 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
547 unique_ptr(_Up __p
) noexcept
551 /** Takes ownership of a pointer.
553 * @param __p A pointer to an array of a type safely convertible
554 * to an array of @c element_type
555 * @param __d A reference to a deleter.
557 * The deleter will be initialized with @p __d
559 template<typename _Up
, typename _Del
= deleter_type
,
560 typename
= _Require
<__safe_conversion_raw
<_Up
>,
561 is_copy_constructible
<_Del
>>>
562 unique_ptr(_Up __p
, const deleter_type
& __d
) noexcept
565 /** Takes ownership of a pointer.
567 * @param __p A pointer to an array of a type safely convertible
568 * to an array of @c element_type
569 * @param __d A reference to a deleter.
571 * The deleter will be initialized with @p std::move(__d)
573 template<typename _Up
, typename _Del
= deleter_type
,
574 typename
= _Require
<__safe_conversion_raw
<_Up
>,
575 is_move_constructible
<_Del
>>>
577 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
578 _Del
&&> __d
) noexcept
579 : _M_t(std::move(__p
), std::move(__d
))
582 template<typename _Up
, typename _Del
= deleter_type
,
583 typename _DelUnref
= typename remove_reference
<_Del
>::type
,
584 typename
= _Require
<__safe_conversion_raw
<_Up
>>>
586 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
587 _DelUnref
&&>) = delete;
589 /// Move constructor.
590 unique_ptr(unique_ptr
&&) = default;
592 /// Creates a unique_ptr that owns nothing.
593 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
594 constexpr unique_ptr(nullptr_t
) noexcept
598 template<typename _Up
, typename _Ep
, typename
= _Require
<
599 __safe_conversion_up
<_Up
, _Ep
>,
600 typename conditional
<is_reference
<_Dp
>::value
,
602 is_convertible
<_Ep
, _Dp
>>::type
>>
603 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
604 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
607 /// Destructor, invokes the deleter if the stored pointer is not null.
610 auto& __ptr
= _M_t
._M_ptr();
611 if (__ptr
!= nullptr)
612 get_deleter()(__ptr
);
618 /** @brief Move assignment operator.
620 * Invokes the deleter if this object owns a pointer.
623 operator=(unique_ptr
&&) = default;
625 /** @brief Assignment from another type.
627 * @param __u The object to transfer ownership from, which owns a
628 * convertible pointer to an array object.
630 * Invokes the deleter if this object owns a pointer.
632 template<typename _Up
, typename _Ep
>
634 enable_if
<__and_
<__safe_conversion_up
<_Up
, _Ep
>,
635 is_assignable
<deleter_type
&, _Ep
&&>
638 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
640 reset(__u
.release());
641 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
645 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
647 operator=(nullptr_t
) noexcept
655 /// Access an element of owned array.
656 typename
std::add_lvalue_reference
<element_type
>::type
657 operator[](size_t __i
) const
659 __glibcxx_assert(get() != pointer());
663 /// Return the stored pointer.
666 { return _M_t
._M_ptr(); }
668 /// Return a reference to the stored deleter.
670 get_deleter() noexcept
671 { return _M_t
._M_deleter(); }
673 /// Return a reference to the stored deleter.
675 get_deleter() const noexcept
676 { return _M_t
._M_deleter(); }
678 /// Return @c true if the stored pointer is not null.
679 explicit operator bool() const noexcept
680 { return get() == pointer() ? false : true; }
684 /// Release ownership of any stored pointer.
687 { return _M_t
.release(); }
689 /** @brief Replace the stored pointer.
691 * @param __p The new pointer to store.
693 * The deleter will be invoked if a pointer is already owned.
695 template <typename _Up
,
697 __or_
<is_same
<_Up
, pointer
>,
698 __and_
<is_same
<pointer
, element_type
*>,
701 typename remove_pointer
<_Up
>::type(*)[],
708 reset(_Up __p
) noexcept
709 { _M_t
.reset(std::move(__p
)); }
711 void reset(nullptr_t
= nullptr) noexcept
712 { reset(pointer()); }
714 /// Exchange the pointer and deleter with another object.
716 swap(unique_ptr
& __u
) noexcept
718 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
722 // Disable copy from lvalue.
723 unique_ptr(const unique_ptr
&) = delete;
724 unique_ptr
& operator=(const unique_ptr
&) = delete;
727 /// @relates unique_ptr @{
729 /// Swap overload for unique_ptr
730 template<typename _Tp
, typename _Dp
>
732 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
733 // Constrained free swap overload, see p0185r1
734 typename enable_if
<__is_swappable
<_Dp
>::value
>::type
738 swap(unique_ptr
<_Tp
, _Dp
>& __x
,
739 unique_ptr
<_Tp
, _Dp
>& __y
) noexcept
742 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
743 template<typename _Tp
, typename _Dp
>
744 typename enable_if
<!__is_swappable
<_Dp
>::value
>::type
745 swap(unique_ptr
<_Tp
, _Dp
>&,
746 unique_ptr
<_Tp
, _Dp
>&) = delete;
749 /// Equality operator for unique_ptr objects, compares the owned pointers
750 template<typename _Tp
, typename _Dp
,
751 typename _Up
, typename _Ep
>
752 _GLIBCXX_NODISCARD
inline bool
753 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
,
754 const unique_ptr
<_Up
, _Ep
>& __y
)
755 { return __x
.get() == __y
.get(); }
757 /// unique_ptr comparison with nullptr
758 template<typename _Tp
, typename _Dp
>
759 _GLIBCXX_NODISCARD
inline bool
760 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
763 #ifndef __cpp_lib_three_way_comparison
764 /// unique_ptr comparison with nullptr
765 template<typename _Tp
, typename _Dp
>
766 _GLIBCXX_NODISCARD
inline bool
767 operator==(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
770 /// Inequality operator for unique_ptr objects, compares the owned pointers
771 template<typename _Tp
, typename _Dp
,
772 typename _Up
, typename _Ep
>
773 _GLIBCXX_NODISCARD
inline bool
774 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
,
775 const unique_ptr
<_Up
, _Ep
>& __y
)
776 { return __x
.get() != __y
.get(); }
778 /// unique_ptr comparison with nullptr
779 template<typename _Tp
, typename _Dp
>
780 _GLIBCXX_NODISCARD
inline bool
781 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
782 { return (bool)__x
; }
784 /// unique_ptr comparison with nullptr
785 template<typename _Tp
, typename _Dp
>
786 _GLIBCXX_NODISCARD
inline bool
787 operator!=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
788 { return (bool)__x
; }
789 #endif // three way comparison
791 /// Relational operator for unique_ptr objects, compares the owned pointers
792 template<typename _Tp
, typename _Dp
,
793 typename _Up
, typename _Ep
>
794 _GLIBCXX_NODISCARD
inline bool
795 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
,
796 const unique_ptr
<_Up
, _Ep
>& __y
)
799 std::common_type
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
800 typename unique_ptr
<_Up
, _Ep
>::pointer
>::type _CT
;
801 return std::less
<_CT
>()(__x
.get(), __y
.get());
804 /// unique_ptr comparison with nullptr
805 template<typename _Tp
, typename _Dp
>
806 _GLIBCXX_NODISCARD
inline bool
807 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
809 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
813 /// unique_ptr comparison with nullptr
814 template<typename _Tp
, typename _Dp
>
815 _GLIBCXX_NODISCARD
inline bool
816 operator<(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
818 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
822 /// Relational operator for unique_ptr objects, compares the owned pointers
823 template<typename _Tp
, typename _Dp
,
824 typename _Up
, typename _Ep
>
825 _GLIBCXX_NODISCARD
inline bool
826 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
,
827 const unique_ptr
<_Up
, _Ep
>& __y
)
828 { return !(__y
< __x
); }
830 /// unique_ptr comparison with nullptr
831 template<typename _Tp
, typename _Dp
>
832 _GLIBCXX_NODISCARD
inline bool
833 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
834 { return !(nullptr < __x
); }
836 /// unique_ptr comparison with nullptr
837 template<typename _Tp
, typename _Dp
>
838 _GLIBCXX_NODISCARD
inline bool
839 operator<=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
840 { return !(__x
< nullptr); }
842 /// Relational operator for unique_ptr objects, compares the owned pointers
843 template<typename _Tp
, typename _Dp
,
844 typename _Up
, typename _Ep
>
845 _GLIBCXX_NODISCARD
inline bool
846 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
,
847 const unique_ptr
<_Up
, _Ep
>& __y
)
848 { return (__y
< __x
); }
850 /// unique_ptr comparison with nullptr
851 template<typename _Tp
, typename _Dp
>
852 _GLIBCXX_NODISCARD
inline bool
853 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
855 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
859 /// unique_ptr comparison with nullptr
860 template<typename _Tp
, typename _Dp
>
861 _GLIBCXX_NODISCARD
inline bool
862 operator>(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
864 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
868 /// Relational operator for unique_ptr objects, compares the owned pointers
869 template<typename _Tp
, typename _Dp
,
870 typename _Up
, typename _Ep
>
871 _GLIBCXX_NODISCARD
inline bool
872 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
,
873 const unique_ptr
<_Up
, _Ep
>& __y
)
874 { return !(__x
< __y
); }
876 /// unique_ptr comparison with nullptr
877 template<typename _Tp
, typename _Dp
>
878 _GLIBCXX_NODISCARD
inline bool
879 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
880 { return !(__x
< nullptr); }
882 /// unique_ptr comparison with nullptr
883 template<typename _Tp
, typename _Dp
>
884 _GLIBCXX_NODISCARD
inline bool
885 operator>=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
886 { return !(nullptr < __x
); }
888 #ifdef __cpp_lib_three_way_comparison
889 template<typename _Tp
, typename _Dp
, typename _Up
, typename _Ep
>
890 requires three_way_comparable_with
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
891 typename unique_ptr
<_Up
, _Ep
>::pointer
>
893 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
894 typename unique_ptr
<_Up
, _Ep
>::pointer
>
895 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
,
896 const unique_ptr
<_Up
, _Ep
>& __y
)
897 { return compare_three_way()(__x
.get(), __y
.get()); }
899 template<typename _Tp
, typename _Dp
>
900 requires three_way_comparable
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
902 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
903 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
905 using pointer
= typename unique_ptr
<_Tp
, _Dp
>::pointer
;
906 return compare_three_way()(__x
.get(), static_cast<pointer
>(nullptr));
909 // @} relates unique_ptr
911 /// @cond undocumented
912 template<typename _Up
, typename _Ptr
= typename
_Up::pointer
,
913 bool = __poison_hash
<_Ptr
>::__enable_hash_call
>
914 struct __uniq_ptr_hash
915 #if ! _GLIBCXX_INLINE_VERSION
916 : private __poison_hash
<_Ptr
>
920 operator()(const _Up
& __u
) const
921 noexcept(noexcept(std::declval
<hash
<_Ptr
>>()(std::declval
<_Ptr
>())))
922 { return hash
<_Ptr
>()(__u
.get()); }
925 template<typename _Up
, typename _Ptr
>
926 struct __uniq_ptr_hash
<_Up
, _Ptr
, false>
927 : private __poison_hash
<_Ptr
>
931 /// std::hash specialization for unique_ptr.
932 template<typename _Tp
, typename _Dp
>
933 struct hash
<unique_ptr
<_Tp
, _Dp
>>
934 : public __hash_base
<size_t, unique_ptr
<_Tp
, _Dp
>>,
935 public __uniq_ptr_hash
<unique_ptr
<_Tp
, _Dp
>>
938 #if __cplusplus >= 201402L
939 /// @relates unique_ptr @{
940 #define __cpp_lib_make_unique 201304
942 /// @cond undocumented
944 template<typename _Tp
>
946 { typedef unique_ptr
<_Tp
> __single_object
; };
948 template<typename _Tp
>
949 struct _MakeUniq
<_Tp
[]>
950 { typedef unique_ptr
<_Tp
[]> __array
; };
952 template<typename _Tp
, size_t _Bound
>
953 struct _MakeUniq
<_Tp
[_Bound
]>
954 { struct __invalid_type
{ }; };
958 /// std::make_unique for single objects
959 template<typename _Tp
, typename
... _Args
>
960 inline typename _MakeUniq
<_Tp
>::__single_object
961 make_unique(_Args
&&... __args
)
962 { return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...)); }
964 /// std::make_unique for arrays of unknown bound
965 template<typename _Tp
>
966 inline typename _MakeUniq
<_Tp
>::__array
967 make_unique(size_t __num
)
968 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]()); }
970 /// Disable std::make_unique for arrays of known bound
971 template<typename _Tp
, typename
... _Args
>
972 typename _MakeUniq
<_Tp
>::__invalid_type
973 make_unique(_Args
&&...) = delete;
975 #if __cplusplus > 201703L
976 /// std::make_unique_for_overwrite for single objects
977 template<typename _Tp
>
978 inline typename _MakeUniq
<_Tp
>::__single_object
979 make_unique_for_overwrite()
980 { return unique_ptr
<_Tp
>(new _Tp
); }
982 /// std::make_unique_for_overwrite for arrays of unknown bound
983 template<typename _Tp
>
984 inline typename _MakeUniq
<_Tp
>::__array
985 make_unique_for_overwrite(size_t __n
)
986 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__n
]); }
988 /// Disable std::make_unique_for_overwrite for arrays of known bound
989 template<typename _Tp
, typename
... _Args
>
990 typename _MakeUniq
<_Tp
>::__invalid_type
991 make_unique_for_overwrite(_Args
&&...) = delete;
994 // @} relates unique_ptr
997 #if __cplusplus > 201703L && __cpp_concepts
998 // _GLIBCXX_RESOLVE_LIB_DEFECTS
999 // 2948. unique_ptr does not define operator<< for stream output
1000 /// Stream output operator for unique_ptr
1001 template<typename _CharT
, typename _Traits
, typename _Tp
, typename _Dp
>
1002 inline basic_ostream
<_CharT
, _Traits
>&
1003 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
1004 const unique_ptr
<_Tp
, _Dp
>& __p
)
1005 requires requires
{ __os
<< __p
.get(); }
1012 // @} group pointer_abstractions
1014 #if __cplusplus >= 201703L
1015 namespace __detail::__variant
1017 template<typename
> struct _Never_valueless_alt
; // see <variant>
1019 // Provide the strong exception-safety guarantee when emplacing a
1020 // unique_ptr into a variant.
1021 template<typename _Tp
, typename _Del
>
1022 struct _Never_valueless_alt
<std::unique_ptr
<_Tp
, _Del
>>
1025 } // namespace __detail::__variant
1028 _GLIBCXX_END_NAMESPACE_VERSION
1031 #endif /* _UNIQUE_PTR_H */