31 #define _UNIQUE_PTR_H 1 39 #if __cplusplus > 201703L 44 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 45 # if __cpp_lib_constexpr_memory < 202202L 47 # undef __cpp_lib_constexpr_memory 48 # define __cpp_lib_constexpr_memory 202202L 52 namespace std _GLIBCXX_VISIBILITY(default)
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
61 #if _GLIBCXX_USE_DEPRECATED 62 #pragma GCC diagnostic push 63 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 64 template<
typename>
class auto_ptr;
65 #pragma GCC diagnostic pop 73 template<
typename _Tp>
84 template<
typename _Up,
85 typename = _Require<is_convertible<_Up*, _Tp*>>>
95 "can't delete pointer to incomplete type");
96 static_assert(
sizeof(_Tp)>0,
97 "can't delete pointer to incomplete type");
110 template<
typename _Tp>
126 template<
typename _Up,
127 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
132 template<
typename _Up>
137 static_assert(
sizeof(_Tp)>0,
138 "can't delete pointer to incomplete type");
146 template <
typename _Tp,
typename _Dp>
147 class __uniq_ptr_impl
149 template <
typename _Up,
typename _Ep,
typename =
void>
155 template <
typename _Up,
typename _Ep>
157 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
164 __and_<__not_<is_pointer<_Dp>>,
167 using pointer =
typename _Ptr<_Tp, _Dp>::type;
170 "unique_ptr's deleter type must be a function object type" 171 " or an lvalue reference type" );
173 __uniq_ptr_impl() =
default;
175 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
177 template<
typename _Del>
179 __uniq_ptr_impl(pointer __p, _Del&& __d)
180 : _M_t(__p, std::forward<_Del>(__d)) { }
183 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
185 { __u._M_ptr() =
nullptr; }
188 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
190 reset(__u.release());
191 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
196 pointer& _M_ptr() noexcept {
return std::get<0>(_M_t); }
198 pointer _M_ptr()
const noexcept {
return std::get<0>(_M_t); }
200 _Dp& _M_deleter() noexcept {
return std::get<1>(_M_t); }
202 const _Dp& _M_deleter()
const noexcept {
return std::get<1>(_M_t); }
205 void reset(pointer __p) noexcept
207 const pointer __old_p = _M_ptr();
210 _M_deleter()(__old_p);
214 pointer release() noexcept
216 pointer __p = _M_ptr();
223 swap(__uniq_ptr_impl& __rhs) noexcept
226 swap(this->_M_ptr(), __rhs._M_ptr());
227 swap(this->_M_deleter(), __rhs._M_deleter());
235 template <
typename _Tp,
typename _Dp,
238 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
240 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
241 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
242 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
245 template <
typename _Tp,
typename _Dp>
246 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
248 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
249 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
250 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
253 template <
typename _Tp,
typename _Dp>
254 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
256 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
257 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
258 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
261 template <
typename _Tp,
typename _Dp>
262 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
264 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
265 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
266 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
275 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
278 template <
typename _Up>
279 using _DeleterConstraint =
280 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
282 __uniq_ptr_data<_Tp, _Dp> _M_t;
285 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
286 using element_type = _Tp;
287 using deleter_type = _Dp;
292 template<
typename _Up,
typename _Ep>
293 using __safe_conversion_up = __and_<
295 __not_<is_array<_Up>>
302 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
313 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
327 template<
typename _Del = deleter_type,
328 typename = _Require<is_copy_constructible<_Del>>>
340 template<
typename _Del = deleter_type,
341 typename = _Require<is_move_constructible<_Del>>>
345 _Del&&> __d) noexcept
349 template<
typename _Del = deleter_type,
350 typename _DelUnref =
typename remove_reference<_Del>::type>
354 _DelUnref&&>) =
delete;
357 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
373 template<
typename _Up,
typename _Ep,
typename = _Require<
374 __safe_conversion_up<_Up, _Ep>,
375 __conditional_t<is_reference<_Dp>::value,
380 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
383 #if _GLIBCXX_USE_DEPRECATED 384 #pragma GCC diagnostic push 385 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 387 template<
typename _Up,
typename = _Require<
390 #pragma GCC diagnostic pop 394 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 399 static_assert(__is_invocable<deleter_type&, pointer>::value,
400 "unique_ptr's deleter must be invocable with a pointer");
401 auto& __ptr = _M_t._M_ptr();
402 if (__ptr !=
nullptr)
422 template<
typename _Up,
typename _Ep>
425 __safe_conversion_up<_Up, _Ep>,
431 reset(__u.release());
432 get_deleter() = std::forward<_Ep>(__u.get_deleter());
449 typename add_lvalue_reference<element_type>::type
452 __glibcxx_assert(
get() != pointer());
461 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
469 {
return _M_t._M_ptr(); }
475 {
return _M_t._M_deleter(); }
481 {
return _M_t._M_deleter(); }
485 explicit operator bool() const noexcept
486 {
return get() == pointer() ? false :
true; }
494 {
return _M_t.release(); }
504 reset(pointer __p = pointer()) noexcept
506 static_assert(__is_invocable<deleter_type&, pointer>::value,
507 "unique_ptr's deleter must be invocable with a pointer");
516 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
533 template<
typename _Tp,
typename _Dp>
536 template <
typename _Up>
537 using _DeleterConstraint =
538 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
540 __uniq_ptr_data<_Tp, _Dp> _M_t;
542 template<
typename _Up>
543 using __remove_cv =
typename remove_cv<_Up>::type;
546 template<
typename _Up>
547 using __is_derived_Tp
548 = __and_< is_base_of<_Tp, _Up>,
549 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
552 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
553 using element_type = _Tp;
554 using deleter_type = _Dp;
558 template<
typename _Up,
typename _Ep,
560 typename _UP_pointer =
typename _UPtr::pointer,
561 typename _UP_element_type =
typename _UPtr::element_type>
562 using __safe_conversion_up = __and_<
570 template<
typename _Up>
571 using __safe_conversion_raw = __and_<
572 __or_<__or_<is_same<_Up, pointer>,
574 __and_<is_pointer<_Up>,
575 is_same<pointer, element_type*>,
577 typename remove_pointer<_Up>::type(*)[],
586 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
598 template<
typename _Up,
600 typename = _DeleterConstraint<_Vp>,
602 __safe_conversion_raw<_Up>::value,
bool>::type>
617 template<
typename _Up,
typename _Del = deleter_type,
618 typename = _Require<__safe_conversion_raw<_Up>,
632 template<
typename _Up,
typename _Del = deleter_type,
633 typename = _Require<__safe_conversion_raw<_Up>,
638 _Del&&> __d) noexcept
642 template<
typename _Up,
typename _Del = deleter_type,
643 typename _DelUnref =
typename remove_reference<_Del>::type,
644 typename = _Require<__safe_conversion_raw<_Up>>>
647 _DelUnref&&>) =
delete;
653 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
658 template<
typename _Up,
typename _Ep,
typename = _Require<
659 __safe_conversion_up<_Up, _Ep>,
660 __conditional_t<is_reference<_Dp>::value,
665 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
669 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 674 auto& __ptr = _M_t._M_ptr();
675 if (__ptr !=
nullptr)
676 get_deleter()(__ptr);
696 template<
typename _Up,
typename _Ep>
705 reset(__u.release());
706 get_deleter() = std::forward<_Ep>(__u.get_deleter());
723 typename std::add_lvalue_reference<element_type>::type
726 __glibcxx_assert(
get() != pointer());
734 {
return _M_t._M_ptr(); }
740 {
return _M_t._M_deleter(); }
746 {
return _M_t._M_deleter(); }
750 explicit operator bool() const noexcept
751 {
return get() == pointer() ? false :
true; }
759 {
return _M_t.release(); }
767 template <
typename _Up,
769 __or_<is_same<_Up, pointer>,
770 __and_<is_same<pointer, element_type*>,
773 typename remove_pointer<_Up>::type(*)[],
785 void reset(nullptr_t =
nullptr) noexcept
786 { reset(pointer()); }
793 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
806 template<
typename _Tp,
typename _Dp>
808 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 819 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 820 template<
typename _Tp,
typename _Dp>
827 template<
typename _Tp,
typename _Dp,
828 typename _Up,
typename _Ep>
829 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
833 {
return __x.
get() == __y.
get(); }
836 template<
typename _Tp,
typename _Dp>
837 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
842 #ifndef __cpp_lib_three_way_comparison 844 template<
typename _Tp,
typename _Dp>
851 template<
typename _Tp,
typename _Dp,
852 typename _Up,
typename _Ep>
857 {
return __x.
get() != __y.
get(); }
860 template<
typename _Tp,
typename _Dp>
864 {
return (
bool)__x; }
867 template<
typename _Tp,
typename _Dp>
871 {
return (
bool)__x; }
872 #endif // three way comparison 875 template<
typename _Tp,
typename _Dp,
876 typename _Up,
typename _Ep>
877 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
879 operator<(const unique_ptr<_Tp, _Dp>& __x,
884 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
889 template<
typename _Tp,
typename _Dp>
890 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
892 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
899 template<
typename _Tp,
typename _Dp>
900 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
902 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
909 template<
typename _Tp,
typename _Dp,
910 typename _Up,
typename _Ep>
911 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
913 operator<=(const unique_ptr<_Tp, _Dp>& __x,
915 {
return !(__y < __x); }
918 template<
typename _Tp,
typename _Dp>
919 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
921 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
922 {
return !(
nullptr < __x); }
925 template<
typename _Tp,
typename _Dp>
926 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
928 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
929 {
return !(__x <
nullptr); }
932 template<
typename _Tp,
typename _Dp,
933 typename _Up,
typename _Ep>
934 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
938 {
return (__y < __x); }
941 template<
typename _Tp,
typename _Dp>
942 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
951 template<
typename _Tp,
typename _Dp>
952 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
961 template<
typename _Tp,
typename _Dp,
962 typename _Up,
typename _Ep>
963 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
967 {
return !(__x < __y); }
970 template<
typename _Tp,
typename _Dp>
971 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
974 {
return !(__x <
nullptr); }
977 template<
typename _Tp,
typename _Dp>
978 _GLIBCXX_NODISCARD
inline bool 980 {
return !(
nullptr < __x); }
982 #ifdef __cpp_lib_three_way_comparison 983 template<
typename _Tp,
typename _Dp,
typename _Up,
typename _Ep>
984 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
985 typename unique_ptr<_Up, _Ep>::pointer>
989 typename unique_ptr<_Up, _Ep>::pointer>
992 {
return compare_three_way()(__x.
get(), __y.
get()); }
994 template<
typename _Tp,
typename _Dp>
995 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
998 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
1001 using pointer =
typename unique_ptr<_Tp, _Dp>::pointer;
1002 return compare_three_way()(__x.
get(),
static_cast<pointer
>(
nullptr));
1008 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
1009 bool = __poison_hash<_Ptr>::__enable_hash_call>
1010 struct __uniq_ptr_hash
1011 #if ! _GLIBCXX_INLINE_VERSION
1012 :
private __poison_hash<_Ptr>
1021 template<
typename _Up,
typename _Ptr>
1022 struct __uniq_ptr_hash<_Up, _Ptr, false>
1023 :
private __poison_hash<_Ptr>
1028 template<
typename _Tp,
typename _Dp>
1030 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
1031 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
1034 #if __cplusplus >= 201402L 1035 #define __cpp_lib_make_unique 201304L 1040 template<
typename _Tp>
1044 template<
typename _Tp>
1045 struct _MakeUniq<_Tp[]>
1048 template<
typename _Tp,
size_t _Bound>
1049 struct _MakeUniq<_Tp[_Bound]>
1050 {
struct __invalid_type { }; };
1052 template<
typename _Tp>
1053 using __unique_ptr_t =
typename _MakeUniq<_Tp>::__single_object;
1054 template<
typename _Tp>
1055 using __unique_ptr_array_t =
typename _MakeUniq<_Tp>::__array;
1056 template<
typename _Tp>
1057 using __invalid_make_unique_t =
typename _MakeUniq<_Tp>::__invalid_type;
1068 template<
typename _Tp,
typename... _Args>
1069 _GLIBCXX23_CONSTEXPR
1070 inline __detail::__unique_ptr_t<_Tp>
1083 template<
typename _Tp>
1084 _GLIBCXX23_CONSTEXPR
1085 inline __detail::__unique_ptr_array_t<_Tp>
1094 template<
typename _Tp,
typename... _Args>
1095 __detail::__invalid_make_unique_t<_Tp>
1096 make_unique(_Args&&...) =
delete;
1098 #if __cplusplus > 201703L 1105 template<
typename _Tp>
1106 _GLIBCXX23_CONSTEXPR
1107 inline __detail::__unique_ptr_t<_Tp>
1118 template<
typename _Tp>
1119 _GLIBCXX23_CONSTEXPR
1120 inline __detail::__unique_ptr_array_t<_Tp>
1129 template<
typename _Tp,
typename... _Args>
1130 __detail::__invalid_make_unique_t<_Tp>
1131 make_unique_for_overwrite(_Args&&...) =
delete;
1136 #if __cplusplus > 201703L && __cpp_concepts 1142 template<
typename _CharT,
typename _Traits,
typename _Tp,
typename _Dp>
1144 operator<<(basic_ostream<_CharT, _Traits>& __os,
1146 requires requires { __os << __p.
get(); }
1155 #if __cplusplus >= 201703L 1156 namespace __detail::__variant
1158 template<
typename>
struct _Never_valueless_alt;
1162 template<
typename _Tp,
typename _Del>
1163 struct _Never_valueless_alt<std::
unique_ptr<_Tp, _Del>>
1169 _GLIBCXX_END_NAMESPACE_VERSION
constexpr enable_if< __and_< __safe_conversion_up< _Up, _Ep >, is_assignable< deleter_type &, _Ep && > >::value, unique_ptr & >::type operator=(unique_ptr< _Up, _Ep > &&__u) noexcept
Assignment from another type.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
constexpr const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
constexpr default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
constexpr unique_ptr(pointer __p, const deleter_type &__d) noexcept
constexpr unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
constexpr pointer operator->() const noexcept
Return the stored pointer.
Template class basic_ostream.
constexpr deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
constexpr unique_ptr(_Up __p, const deleter_type &__d) noexcept
constexpr unique_ptr(_Up __p) noexcept
typename __detail::__cmp3way_res_impl< _Tp, _Up >::type compare_three_way_result_t
[cmp.result], result of three-way comparison
constexpr add_lvalue_reference< element_type >::type operator*() const noexcept(noexcept(*std::declval< pointer >()))
Dereference the stored pointer.
constexpr unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
constexpr unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
constexpr default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
constexpr unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
constexpr deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
ISO C++ entities toplevel namespace is std.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
constexpr __detail::__unique_ptr_t< _Tp > make_unique(_Args &&... __args)
constexpr pointer release() noexcept
Release ownership of any stored pointer.
constexpr const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
constexpr enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
constexpr void reset(_Up __p) noexcept
Replace the stored pointer.
A move-only smart pointer that manages unique ownership of a resource.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
constexpr void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
A simple smart pointer providing strict ownership semantics.
constexpr std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
constexpr void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr __detail::__unique_ptr_t< _Tp > make_unique_for_overwrite()
constexpr enable_if< __and_< __safe_conversion_up< _Up, _Ep >, is_assignable< deleter_type &, _Ep && > >::value, unique_ptr & >::type operator=(unique_ptr< _Up, _Ep > &&__u) noexcept
Assignment from another type.
constexpr void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
constexpr enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
constexpr pointer release() noexcept
Release ownership of any stored pointer.
constexpr __detail::__unique_ptr_array_t< _Tp > make_unique(size_t __num)
constexpr unique_ptr(pointer __p) noexcept
constexpr __detail::__unique_ptr_array_t< _Tp > make_unique_for_overwrite(size_t __num)
constexpr void operator()(_Tp *__ptr) const
Calls delete __ptr
One of the comparison functors.
Define a member typedef type only if a boolean constant is true.
constexpr default_delete() noexcept=default
Default constructor.
constexpr pointer get() const noexcept
Return the stored pointer.
Primary class template, tuple.
Primary class template hash.