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>
37 #include <bits/stl_function.h>
38 #include <bits/functional_hash.h>
39 #if __cplusplus > 201703L
44 namespace std
_GLIBCXX_VISIBILITY(default)
46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 * @addtogroup pointer_abstractions
53 #if _GLIBCXX_USE_DEPRECATED
54 #pragma GCC diagnostic push
55 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
56 template<typename
> class auto_ptr
;
57 #pragma GCC diagnostic pop
60 /// 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() noexcept
{ return std::get
<0>(_M_t
); }
173 pointer
_M_ptr() const noexcept
{ return std::get
<0>(_M_t
); }
174 _Dp
& _M_deleter() noexcept
{ return std::get
<1>(_M_t
); }
175 const _Dp
& _M_deleter() const noexcept
{ 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.
242 /// A move-only smart pointer that manages unique ownership of a resource.
243 /// @headerfile memory
245 template <typename _Tp
, typename _Dp
= default_delete
<_Tp
>>
248 template <typename _Up
>
249 using _DeleterConstraint
=
250 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
252 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
255 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
256 using element_type
= _Tp
;
257 using deleter_type
= _Dp
;
260 // helper template for detecting a safe conversion from another
262 template<typename _Up
, typename _Ep
>
263 using __safe_conversion_up
= __and_
<
264 is_convertible
<typename unique_ptr
<_Up
, _Ep
>::pointer
, pointer
>,
265 __not_
<is_array
<_Up
>>
271 /// Default constructor, creates a unique_ptr that owns nothing.
272 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
273 constexpr unique_ptr() noexcept
277 /** Takes ownership of a pointer.
279 * @param __p A pointer to an object of @c element_type
281 * The deleter will be value-initialized.
283 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
285 unique_ptr(pointer __p
) noexcept
289 /** Takes ownership of a pointer.
291 * @param __p A pointer to an object of @c element_type
292 * @param __d A reference to a deleter.
294 * The deleter will be initialized with @p __d
296 template<typename _Del
= deleter_type
,
297 typename
= _Require
<is_copy_constructible
<_Del
>>>
298 unique_ptr(pointer __p
, const deleter_type
& __d
) noexcept
301 /** Takes ownership of a pointer.
303 * @param __p A pointer to an object of @c element_type
304 * @param __d An rvalue reference to a (non-reference) deleter.
306 * The deleter will be initialized with @p std::move(__d)
308 template<typename _Del
= deleter_type
,
309 typename
= _Require
<is_move_constructible
<_Del
>>>
310 unique_ptr(pointer __p
,
311 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
312 _Del
&&> __d
) noexcept
313 : _M_t(__p
, std::move(__d
))
316 template<typename _Del
= deleter_type
,
317 typename _DelUnref
= typename remove_reference
<_Del
>::type
>
319 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
320 _DelUnref
&&>) = delete;
322 /// Creates a unique_ptr that owns nothing.
323 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
324 constexpr unique_ptr(nullptr_t
) noexcept
328 // Move constructors.
330 /// Move constructor.
331 unique_ptr(unique_ptr
&&) = default;
333 /** @brief Converting constructor from another type
335 * Requires that the pointer owned by @p __u is convertible to the
336 * type of pointer owned by this object, @p __u does not own an array,
337 * and @p __u has a compatible deleter type.
339 template<typename _Up
, typename _Ep
, typename
= _Require
<
340 __safe_conversion_up
<_Up
, _Ep
>,
341 __conditional_t
<is_reference
<_Dp
>::value
,
343 is_convertible
<_Ep
, _Dp
>>>>
344 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
345 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
348 #if _GLIBCXX_USE_DEPRECATED
349 #pragma GCC diagnostic push
350 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
351 /// Converting constructor from @c auto_ptr
352 template<typename _Up
, typename
= _Require
<
353 is_convertible
<_Up
*, _Tp
*>, is_same
<_Dp
, default_delete
<_Tp
>>>>
354 unique_ptr(auto_ptr
<_Up
>&& __u
) noexcept
;
355 #pragma GCC diagnostic pop
358 /// Destructor, invokes the deleter if the stored pointer is not null.
359 ~unique_ptr() noexcept
361 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
362 "unique_ptr's deleter must be invocable with a pointer");
363 auto& __ptr
= _M_t
._M_ptr();
364 if (__ptr
!= nullptr)
365 get_deleter()(std::move(__ptr
));
371 /** @brief Move assignment operator.
373 * Invokes the deleter if this object owns a pointer.
375 unique_ptr
& operator=(unique_ptr
&&) = default;
377 /** @brief Assignment from another type.
379 * @param __u The object to transfer ownership from, which owns a
380 * convertible pointer to a non-array object.
382 * Invokes the deleter if this object owns a pointer.
384 template<typename _Up
, typename _Ep
>
385 typename enable_if
< __and_
<
386 __safe_conversion_up
<_Up
, _Ep
>,
387 is_assignable
<deleter_type
&, _Ep
&&>
390 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
392 reset(__u
.release());
393 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
397 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
399 operator=(nullptr_t
) noexcept
407 /// Dereference the stored pointer.
408 typename add_lvalue_reference
<element_type
>::type
409 operator*() const noexcept(noexcept(*std::declval
<pointer
>()))
411 __glibcxx_assert(get() != pointer());
415 /// Return the stored pointer.
417 operator->() const noexcept
419 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
423 /// Return the stored pointer.
426 { return _M_t
._M_ptr(); }
428 /// Return a reference to the stored deleter.
430 get_deleter() noexcept
431 { return _M_t
._M_deleter(); }
433 /// Return a reference to the stored deleter.
435 get_deleter() const noexcept
436 { return _M_t
._M_deleter(); }
438 /// Return @c true if the stored pointer is not null.
439 explicit operator bool() const noexcept
440 { return get() == pointer() ? false : true; }
444 /// Release ownership of any stored pointer.
447 { return _M_t
.release(); }
449 /** @brief Replace the stored pointer.
451 * @param __p The new pointer to store.
453 * The deleter will be invoked if a pointer is already owned.
456 reset(pointer __p
= pointer()) noexcept
458 static_assert(__is_invocable
<deleter_type
&, pointer
>::value
,
459 "unique_ptr's deleter must be invocable with a pointer");
460 _M_t
.reset(std::move(__p
));
463 /// Exchange the pointer and deleter with another object.
465 swap(unique_ptr
& __u
) noexcept
467 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
471 // Disable copy from lvalue.
472 unique_ptr(const unique_ptr
&) = delete;
473 unique_ptr
& operator=(const unique_ptr
&) = delete;
476 // 20.7.1.3 unique_ptr for array objects with a runtime length
477 // [unique.ptr.runtime]
478 // _GLIBCXX_RESOLVE_LIB_DEFECTS
479 // DR 740 - omit specialization for array objects with a compile time length
481 /// A move-only smart pointer that manages unique ownership of an array.
482 /// @headerfile memory
484 template<typename _Tp
, typename _Dp
>
485 class unique_ptr
<_Tp
[], _Dp
>
487 template <typename _Up
>
488 using _DeleterConstraint
=
489 typename __uniq_ptr_impl
<_Tp
, _Up
>::_DeleterConstraint::type
;
491 __uniq_ptr_data
<_Tp
, _Dp
> _M_t
;
493 template<typename _Up
>
494 using __remove_cv
= typename remove_cv
<_Up
>::type
;
496 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
497 template<typename _Up
>
498 using __is_derived_Tp
499 = __and_
< is_base_of
<_Tp
, _Up
>,
500 __not_
<is_same
<__remove_cv
<_Tp
>, __remove_cv
<_Up
>>> >;
503 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
504 using element_type
= _Tp
;
505 using deleter_type
= _Dp
;
507 // helper template for detecting a safe conversion from another
509 template<typename _Up
, typename _Ep
,
510 typename _UPtr
= unique_ptr
<_Up
, _Ep
>,
511 typename _UP_pointer
= typename
_UPtr::pointer
,
512 typename _UP_element_type
= typename
_UPtr::element_type
>
513 using __safe_conversion_up
= __and_
<
515 is_same
<pointer
, element_type
*>,
516 is_same
<_UP_pointer
, _UP_element_type
*>,
517 is_convertible
<_UP_element_type(*)[], element_type(*)[]>
520 // helper template for detecting a safe conversion from a raw pointer
521 template<typename _Up
>
522 using __safe_conversion_raw
= __and_
<
523 __or_
<__or_
<is_same
<_Up
, pointer
>,
524 is_same
<_Up
, nullptr_t
>>,
525 __and_
<is_pointer
<_Up
>,
526 is_same
<pointer
, element_type
*>,
528 typename remove_pointer
<_Up
>::type(*)[],
536 /// Default constructor, creates a unique_ptr that owns nothing.
537 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
538 constexpr unique_ptr() noexcept
542 /** Takes ownership of a pointer.
544 * @param __p A pointer to an array of a type safely convertible
545 * to an array of @c element_type
547 * The deleter will be value-initialized.
549 template<typename _Up
,
551 typename
= _DeleterConstraint
<_Vp
>,
552 typename
= typename enable_if
<
553 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
555 unique_ptr(_Up __p
) noexcept
559 /** Takes ownership of a pointer.
561 * @param __p A pointer to an array of a type safely convertible
562 * to an array of @c element_type
563 * @param __d A reference to a deleter.
565 * The deleter will be initialized with @p __d
567 template<typename _Up
, typename _Del
= deleter_type
,
568 typename
= _Require
<__safe_conversion_raw
<_Up
>,
569 is_copy_constructible
<_Del
>>>
570 unique_ptr(_Up __p
, const deleter_type
& __d
) noexcept
573 /** Takes ownership of a pointer.
575 * @param __p A pointer to an array of a type safely convertible
576 * to an array of @c element_type
577 * @param __d A reference to a deleter.
579 * The deleter will be initialized with @p std::move(__d)
581 template<typename _Up
, typename _Del
= deleter_type
,
582 typename
= _Require
<__safe_conversion_raw
<_Up
>,
583 is_move_constructible
<_Del
>>>
585 __enable_if_t
<!is_lvalue_reference
<_Del
>::value
,
586 _Del
&&> __d
) noexcept
587 : _M_t(std::move(__p
), std::move(__d
))
590 template<typename _Up
, typename _Del
= deleter_type
,
591 typename _DelUnref
= typename remove_reference
<_Del
>::type
,
592 typename
= _Require
<__safe_conversion_raw
<_Up
>>>
594 __enable_if_t
<is_lvalue_reference
<_Del
>::value
,
595 _DelUnref
&&>) = delete;
597 /// Move constructor.
598 unique_ptr(unique_ptr
&&) = default;
600 /// Creates a unique_ptr that owns nothing.
601 template<typename _Del
= _Dp
, typename
= _DeleterConstraint
<_Del
>>
602 constexpr unique_ptr(nullptr_t
) noexcept
606 template<typename _Up
, typename _Ep
, typename
= _Require
<
607 __safe_conversion_up
<_Up
, _Ep
>,
608 __conditional_t
<is_reference
<_Dp
>::value
,
610 is_convertible
<_Ep
, _Dp
>>>>
611 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
612 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
615 /// Destructor, invokes the deleter if the stored pointer is not null.
618 auto& __ptr
= _M_t
._M_ptr();
619 if (__ptr
!= nullptr)
620 get_deleter()(__ptr
);
626 /** @brief Move assignment operator.
628 * Invokes the deleter if this object owns a pointer.
631 operator=(unique_ptr
&&) = default;
633 /** @brief Assignment from another type.
635 * @param __u The object to transfer ownership from, which owns a
636 * convertible pointer to an array object.
638 * Invokes the deleter if this object owns a pointer.
640 template<typename _Up
, typename _Ep
>
642 enable_if
<__and_
<__safe_conversion_up
<_Up
, _Ep
>,
643 is_assignable
<deleter_type
&, _Ep
&&>
646 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
648 reset(__u
.release());
649 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
653 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
655 operator=(nullptr_t
) noexcept
663 /// Access an element of owned array.
664 typename
std::add_lvalue_reference
<element_type
>::type
665 operator[](size_t __i
) const
667 __glibcxx_assert(get() != pointer());
671 /// Return the stored pointer.
674 { return _M_t
._M_ptr(); }
676 /// Return a reference to the stored deleter.
678 get_deleter() noexcept
679 { return _M_t
._M_deleter(); }
681 /// Return a reference to the stored deleter.
683 get_deleter() const noexcept
684 { return _M_t
._M_deleter(); }
686 /// Return @c true if the stored pointer is not null.
687 explicit operator bool() const noexcept
688 { return get() == pointer() ? false : true; }
692 /// Release ownership of any stored pointer.
695 { return _M_t
.release(); }
697 /** @brief Replace the stored pointer.
699 * @param __p The new pointer to store.
701 * The deleter will be invoked if a pointer is already owned.
703 template <typename _Up
,
705 __or_
<is_same
<_Up
, pointer
>,
706 __and_
<is_same
<pointer
, element_type
*>,
709 typename remove_pointer
<_Up
>::type(*)[],
716 reset(_Up __p
) noexcept
717 { _M_t
.reset(std::move(__p
)); }
719 void reset(nullptr_t
= nullptr) noexcept
720 { reset(pointer()); }
722 /// Exchange the pointer and deleter with another object.
724 swap(unique_ptr
& __u
) noexcept
726 static_assert(__is_swappable
<_Dp
>::value
, "deleter must be swappable");
730 // Disable copy from lvalue.
731 unique_ptr(const unique_ptr
&) = delete;
732 unique_ptr
& operator=(const unique_ptr
&) = delete;
736 /// @relates unique_ptr
738 /// Swap overload for unique_ptr
739 template<typename _Tp
, typename _Dp
>
741 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
742 // Constrained free swap overload, see p0185r1
743 typename enable_if
<__is_swappable
<_Dp
>::value
>::type
747 swap(unique_ptr
<_Tp
, _Dp
>& __x
,
748 unique_ptr
<_Tp
, _Dp
>& __y
) noexcept
751 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
752 template<typename _Tp
, typename _Dp
>
753 typename enable_if
<!__is_swappable
<_Dp
>::value
>::type
754 swap(unique_ptr
<_Tp
, _Dp
>&,
755 unique_ptr
<_Tp
, _Dp
>&) = delete;
758 /// Equality operator for unique_ptr objects, compares the owned pointers
759 template<typename _Tp
, typename _Dp
,
760 typename _Up
, typename _Ep
>
761 _GLIBCXX_NODISCARD
inline bool
762 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
,
763 const unique_ptr
<_Up
, _Ep
>& __y
)
764 { return __x
.get() == __y
.get(); }
766 /// unique_ptr comparison with nullptr
767 template<typename _Tp
, typename _Dp
>
768 _GLIBCXX_NODISCARD
inline bool
769 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
772 #ifndef __cpp_lib_three_way_comparison
773 /// unique_ptr comparison with nullptr
774 template<typename _Tp
, typename _Dp
>
775 _GLIBCXX_NODISCARD
inline bool
776 operator==(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
779 /// Inequality operator for unique_ptr objects, compares the owned pointers
780 template<typename _Tp
, typename _Dp
,
781 typename _Up
, typename _Ep
>
782 _GLIBCXX_NODISCARD
inline bool
783 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
,
784 const unique_ptr
<_Up
, _Ep
>& __y
)
785 { return __x
.get() != __y
.get(); }
787 /// unique_ptr comparison with nullptr
788 template<typename _Tp
, typename _Dp
>
789 _GLIBCXX_NODISCARD
inline bool
790 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
791 { return (bool)__x
; }
793 /// unique_ptr comparison with nullptr
794 template<typename _Tp
, typename _Dp
>
795 _GLIBCXX_NODISCARD
inline bool
796 operator!=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
797 { return (bool)__x
; }
798 #endif // three way comparison
800 /// Relational operator for unique_ptr objects, compares the owned pointers
801 template<typename _Tp
, typename _Dp
,
802 typename _Up
, typename _Ep
>
803 _GLIBCXX_NODISCARD
inline bool
804 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
,
805 const unique_ptr
<_Up
, _Ep
>& __y
)
808 std::common_type
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
809 typename unique_ptr
<_Up
, _Ep
>::pointer
>::type _CT
;
810 return std::less
<_CT
>()(__x
.get(), __y
.get());
813 /// unique_ptr comparison with nullptr
814 template<typename _Tp
, typename _Dp
>
815 _GLIBCXX_NODISCARD
inline bool
816 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
818 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
822 /// unique_ptr comparison with nullptr
823 template<typename _Tp
, typename _Dp
>
824 _GLIBCXX_NODISCARD
inline bool
825 operator<(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
827 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
831 /// Relational operator for unique_ptr objects, compares the owned pointers
832 template<typename _Tp
, typename _Dp
,
833 typename _Up
, typename _Ep
>
834 _GLIBCXX_NODISCARD
inline bool
835 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
,
836 const unique_ptr
<_Up
, _Ep
>& __y
)
837 { return !(__y
< __x
); }
839 /// unique_ptr comparison with nullptr
840 template<typename _Tp
, typename _Dp
>
841 _GLIBCXX_NODISCARD
inline bool
842 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
843 { return !(nullptr < __x
); }
845 /// unique_ptr comparison with nullptr
846 template<typename _Tp
, typename _Dp
>
847 _GLIBCXX_NODISCARD
inline bool
848 operator<=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
849 { return !(__x
< nullptr); }
851 /// Relational operator for unique_ptr objects, compares the owned pointers
852 template<typename _Tp
, typename _Dp
,
853 typename _Up
, typename _Ep
>
854 _GLIBCXX_NODISCARD
inline bool
855 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
,
856 const unique_ptr
<_Up
, _Ep
>& __y
)
857 { return (__y
< __x
); }
859 /// unique_ptr comparison with nullptr
860 template<typename _Tp
, typename _Dp
>
861 _GLIBCXX_NODISCARD
inline bool
862 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
864 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
868 /// unique_ptr comparison with nullptr
869 template<typename _Tp
, typename _Dp
>
870 _GLIBCXX_NODISCARD
inline bool
871 operator>(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
873 return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
877 /// Relational operator for unique_ptr objects, compares the owned pointers
878 template<typename _Tp
, typename _Dp
,
879 typename _Up
, typename _Ep
>
880 _GLIBCXX_NODISCARD
inline bool
881 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
,
882 const unique_ptr
<_Up
, _Ep
>& __y
)
883 { return !(__x
< __y
); }
885 /// unique_ptr comparison with nullptr
886 template<typename _Tp
, typename _Dp
>
887 _GLIBCXX_NODISCARD
inline bool
888 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
889 { return !(__x
< nullptr); }
891 /// unique_ptr comparison with nullptr
892 template<typename _Tp
, typename _Dp
>
893 _GLIBCXX_NODISCARD
inline bool
894 operator>=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
895 { return !(nullptr < __x
); }
897 #ifdef __cpp_lib_three_way_comparison
898 template<typename _Tp
, typename _Dp
, typename _Up
, typename _Ep
>
899 requires three_way_comparable_with
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
900 typename unique_ptr
<_Up
, _Ep
>::pointer
>
902 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
903 typename unique_ptr
<_Up
, _Ep
>::pointer
>
904 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
,
905 const unique_ptr
<_Up
, _Ep
>& __y
)
906 { return compare_three_way()(__x
.get(), __y
.get()); }
908 template<typename _Tp
, typename _Dp
>
909 requires three_way_comparable
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
911 compare_three_way_result_t
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>
912 operator<=>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
914 using pointer
= typename unique_ptr
<_Tp
, _Dp
>::pointer
;
915 return compare_three_way()(__x
.get(), static_cast<pointer
>(nullptr));
918 /// @} relates unique_ptr
920 /// @cond undocumented
921 template<typename _Up
, typename _Ptr
= typename
_Up::pointer
,
922 bool = __poison_hash
<_Ptr
>::__enable_hash_call
>
923 struct __uniq_ptr_hash
924 #if ! _GLIBCXX_INLINE_VERSION
925 : private __poison_hash
<_Ptr
>
929 operator()(const _Up
& __u
) const
930 noexcept(noexcept(std::declval
<hash
<_Ptr
>>()(std::declval
<_Ptr
>())))
931 { return hash
<_Ptr
>()(__u
.get()); }
934 template<typename _Up
, typename _Ptr
>
935 struct __uniq_ptr_hash
<_Up
, _Ptr
, false>
936 : private __poison_hash
<_Ptr
>
940 /// std::hash specialization for unique_ptr.
941 template<typename _Tp
, typename _Dp
>
942 struct hash
<unique_ptr
<_Tp
, _Dp
>>
943 : public __hash_base
<size_t, unique_ptr
<_Tp
, _Dp
>>,
944 public __uniq_ptr_hash
<unique_ptr
<_Tp
, _Dp
>>
947 #if __cplusplus >= 201402L
948 #define __cpp_lib_make_unique 201304
950 /// @cond undocumented
953 template<typename _Tp
>
955 { typedef unique_ptr
<_Tp
> __single_object
; };
957 template<typename _Tp
>
958 struct _MakeUniq
<_Tp
[]>
959 { typedef unique_ptr
<_Tp
[]> __array
; };
961 template<typename _Tp
, size_t _Bound
>
962 struct _MakeUniq
<_Tp
[_Bound
]>
963 { struct __invalid_type
{ }; };
965 template<typename _Tp
>
966 using __unique_ptr_t
= typename _MakeUniq
<_Tp
>::__single_object
;
967 template<typename _Tp
>
968 using __unique_ptr_array_t
= typename _MakeUniq
<_Tp
>::__array
;
969 template<typename _Tp
>
970 using __invalid_make_unique_t
= typename _MakeUniq
<_Tp
>::__invalid_type
;
974 /** Create an object owned by a `unique_ptr`.
975 * @tparam _Tp A non-array object type.
976 * @param __args Constructor arguments for the new object.
977 * @returns A `unique_ptr<_Tp>` that owns the new object.
979 * @relates unique_ptr
981 template<typename _Tp
, typename
... _Args
>
982 inline __detail::__unique_ptr_t
<_Tp
>
983 make_unique(_Args
&&... __args
)
984 { return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...)); }
986 /** Create an array owned by a `unique_ptr`.
987 * @tparam _Tp An array type of unknown bound, such as `U[]`.
988 * @param __num The number of elements of type `U` in the new array.
989 * @returns A `unique_ptr<U[]>` that owns the new array.
991 * @relates unique_ptr
993 * The array elements are value-initialized.
995 template<typename _Tp
>
996 inline __detail::__unique_ptr_array_t
<_Tp
>
997 make_unique(size_t __num
)
998 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]()); }
1000 /** Disable std::make_unique for arrays of known bound.
1001 * @tparam _Tp An array type of known bound, such as `U[N]`.
1003 * @relates unique_ptr
1005 template<typename _Tp
, typename
... _Args
>
1006 __detail::__invalid_make_unique_t
<_Tp
>
1007 make_unique(_Args
&&...) = delete;
1009 #if __cplusplus > 201703L
1010 /** Create a default-initialied object owned by a `unique_ptr`.
1011 * @tparam _Tp A non-array object type.
1012 * @returns A `unique_ptr<_Tp>` that owns the new object.
1014 * @relates unique_ptr
1016 template<typename _Tp
>
1017 inline __detail::__unique_ptr_t
<_Tp
>
1018 make_unique_for_overwrite()
1019 { return unique_ptr
<_Tp
>(new _Tp
); }
1021 /** Create a default-initialized array owned by a `unique_ptr`.
1022 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1023 * @param __num The number of elements of type `U` in the new array.
1024 * @returns A `unique_ptr<U[]>` that owns the new array.
1026 * @relates unique_ptr
1028 template<typename _Tp
>
1029 inline __detail::__unique_ptr_array_t
<_Tp
>
1030 make_unique_for_overwrite(size_t __num
)
1031 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]); }
1033 /** Disable std::make_unique_for_overwrite for arrays of known bound.
1034 * @tparam _Tp An array type of known bound, such as `U[N]`.
1036 * @relates unique_ptr
1038 template<typename _Tp
, typename
... _Args
>
1039 __detail::__invalid_make_unique_t
<_Tp
>
1040 make_unique_for_overwrite(_Args
&&...) = delete;
1045 #if __cplusplus > 201703L && __cpp_concepts
1046 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1047 // 2948. unique_ptr does not define operator<< for stream output
1048 /// Stream output operator for unique_ptr
1049 /// @relates unique_ptr
1051 template<typename _CharT
, typename _Traits
, typename _Tp
, typename _Dp
>
1052 inline basic_ostream
<_CharT
, _Traits
>&
1053 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
1054 const unique_ptr
<_Tp
, _Dp
>& __p
)
1055 requires requires
{ __os
<< __p
.get(); }
1062 /// @} group pointer_abstractions
1064 #if __cplusplus >= 201703L
1065 namespace __detail::__variant
1067 template<typename
> struct _Never_valueless_alt
; // see <variant>
1069 // Provide the strong exception-safety guarantee when emplacing a
1070 // unique_ptr into a variant.
1071 template<typename _Tp
, typename _Del
>
1072 struct _Never_valueless_alt
<std::unique_ptr
<_Tp
, _Del
>>
1075 } // namespace __detail::__variant
1078 _GLIBCXX_END_NAMESPACE_VERSION
1081 #endif /* _UNIQUE_PTR_H */