31 #define _UNIQUE_PTR_H 1
39 #if __cplusplus >= 202002L
46 namespace std _GLIBCXX_VISIBILITY(default)
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 #if _GLIBCXX_USE_DEPRECATED
56 #pragma GCC diagnostic push
57 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58 template<
typename>
class auto_ptr;
59 #pragma GCC diagnostic pop
67 template<
typename _Tp>
78 template<
typename _Up,
79 typename = _Require<is_convertible<_Up*, _Tp*>>>
89 "can't delete pointer to incomplete type");
90 static_assert(
sizeof(_Tp)>0,
91 "can't delete pointer to incomplete type");
104 template<
typename _Tp>
120 template<
typename _Up,
126 template<
typename _Up>
131 static_assert(
sizeof(_Tp)>0,
132 "can't delete pointer to incomplete type");
140 template <
typename _Tp,
typename _Dp>
141 class __uniq_ptr_impl
143 template <
typename _Up,
typename _Ep,
typename =
void>
149 template <
typename _Up,
typename _Ep>
151 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
153 using type =
typename remove_reference<_Ep>::type::pointer;
157 using _DeleterConstraint = enable_if<
158 __and_<__not_<is_pointer<_Dp>>,
159 is_default_constructible<_Dp>>::value>;
161 using pointer =
typename _Ptr<_Tp, _Dp>::type;
163 static_assert( !is_rvalue_reference<_Dp>::value,
164 "unique_ptr's deleter type must be a function object type"
165 " or an lvalue reference type" );
167 __uniq_ptr_impl() =
default;
169 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
171 template<
typename _Del>
173 __uniq_ptr_impl(pointer __p, _Del&& __d)
177 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
179 { __u._M_ptr() =
nullptr; }
182 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
184 reset(__u.release());
185 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
190 pointer& _M_ptr() noexcept {
return std::get<0>(_M_t); }
192 pointer _M_ptr() const noexcept {
return std::get<0>(_M_t); }
194 _Dp& _M_deleter() noexcept {
return std::get<1>(_M_t); }
196 const _Dp& _M_deleter() const noexcept {
return std::get<1>(_M_t); }
199 void reset(pointer __p) noexcept
201 const pointer __old_p = _M_ptr();
204 _M_deleter()(__old_p);
208 pointer release() noexcept
210 pointer __p = _M_ptr();
217 swap(__uniq_ptr_impl& __rhs) noexcept
220 swap(this->_M_ptr(), __rhs._M_ptr());
221 swap(this->_M_deleter(), __rhs._M_deleter());
225 tuple<pointer, _Dp> _M_t;
229 template <
typename _Tp,
typename _Dp,
230 bool = is_move_constructible<_Dp>::value,
231 bool = is_move_assignable<_Dp>::value>
232 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
234 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
235 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
236 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
239 template <
typename _Tp,
typename _Dp>
240 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __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&&) =
delete;
247 template <
typename _Tp,
typename _Dp>
248 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
250 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
251 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
252 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
255 template <
typename _Tp,
typename _Dp>
256 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __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&&) =
delete;
269 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
272 template <
typename _Up>
273 using _DeleterConstraint =
274 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
276 __uniq_ptr_data<_Tp, _Dp> _M_t;
279 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
280 using element_type = _Tp;
281 using deleter_type = _Dp;
286 template<
typename _Up,
typename _Ep>
287 using __safe_conversion_up = __and_<
289 __not_<is_array<_Up>>
296 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
307 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
321 template<
typename _Del = deleter_type,
322 typename = _Require<is_copy_constructible<_Del>>>
334 template<
typename _Del = deleter_type,
335 typename = _Require<is_move_constructible<_Del>>>
339 _Del&&> __d) noexcept
343 template<
typename _Del = deleter_type,
344 typename _DelUnref =
typename remove_reference<_Del>::type>
348 _DelUnref&&>) =
delete;
351 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
367 template<
typename _Up,
typename _Ep,
typename = _Require<
368 __safe_conversion_up<_Up, _Ep>,
369 __conditional_t<is_reference<_Dp>::value,
374 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
377 #if _GLIBCXX_USE_DEPRECATED
378 #pragma GCC diagnostic push
379 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
381 template<
typename _Up,
382 typename = _Require<is_convertible<_Up*, pointer>,
385 #pragma GCC diagnostic pop
389 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
394 static_assert(__is_invocable<deleter_type&, pointer>::value,
395 "unique_ptr's deleter must be invocable with a pointer");
396 auto& __ptr = _M_t._M_ptr();
397 if (__ptr !=
nullptr)
417 template<
typename _Up,
typename _Ep>
420 __safe_conversion_up<_Up, _Ep>,
426 reset(__u.release());
427 get_deleter() = std::forward<_Ep>(__u.get_deleter());
444 typename add_lvalue_reference<element_type>::type
447 __glibcxx_assert(
get() != pointer());
456 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
464 {
return _M_t._M_ptr(); }
470 {
return _M_t._M_deleter(); }
476 {
return _M_t._M_deleter(); }
480 explicit operator bool() const noexcept
481 {
return get() == pointer() ? false :
true; }
489 {
return _M_t.release(); }
499 reset(pointer __p = pointer()) noexcept
501 static_assert(__is_invocable<deleter_type&, pointer>::value,
502 "unique_ptr's deleter must be invocable with a pointer");
511 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
520 #ifdef __glibcxx_out_ptr
521 template<
typename,
typename,
typename...>
522 friend class out_ptr_t;
523 template<
typename,
typename,
typename...>
524 friend class inout_ptr_t;
536 template<
typename _Tp,
typename _Dp>
539 template <
typename _Up>
540 using _DeleterConstraint =
541 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
543 __uniq_ptr_data<_Tp, _Dp> _M_t;
546 template<
typename _Up>
547 using __is_derived_Tp
548 = __and_< is_base_of<_Tp, _Up>,
549 __not_<is_same<__remove_cv_t<_Tp>, __remove_cv_t<_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>,
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");
802 #ifdef __glibcxx_out_ptr
803 template<
typename,
typename,
typename...>
friend class out_ptr_t;
804 template<
typename,
typename,
typename...>
friend class inout_ptr_t;
812 template<
typename _Tp,
typename _Dp>
814 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
817 typename enable_if<__is_swappable<_Dp>::value>::type
825 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
826 template<
typename _Tp,
typename _Dp>
833 template<
typename _Tp,
typename _Dp,
834 typename _Up,
typename _Ep>
835 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
839 {
return __x.
get() == __y.
get(); }
842 template<
typename _Tp,
typename _Dp>
843 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
848 #ifndef __cpp_lib_three_way_comparison
850 template<
typename _Tp,
typename _Dp>
857 template<
typename _Tp,
typename _Dp,
858 typename _Up,
typename _Ep>
863 {
return __x.
get() != __y.
get(); }
866 template<
typename _Tp,
typename _Dp>
870 {
return (
bool)__x; }
873 template<
typename _Tp,
typename _Dp>
877 {
return (
bool)__x; }
878 #endif // three way comparison
881 template<
typename _Tp,
typename _Dp,
882 typename _Up,
typename _Ep>
883 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
890 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
895 template<
typename _Tp,
typename _Dp>
896 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
905 template<
typename _Tp,
typename _Dp>
906 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
915 template<
typename _Tp,
typename _Dp,
916 typename _Up,
typename _Ep>
917 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
921 {
return !(__y < __x); }
924 template<
typename _Tp,
typename _Dp>
925 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
928 {
return !(
nullptr < __x); }
931 template<
typename _Tp,
typename _Dp>
932 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
935 {
return !(__x <
nullptr); }
938 template<
typename _Tp,
typename _Dp,
939 typename _Up,
typename _Ep>
940 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
944 {
return (__y < __x); }
947 template<
typename _Tp,
typename _Dp>
948 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
957 template<
typename _Tp,
typename _Dp>
958 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
967 template<
typename _Tp,
typename _Dp,
968 typename _Up,
typename _Ep>
969 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
973 {
return !(__x < __y); }
976 template<
typename _Tp,
typename _Dp>
977 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
980 {
return !(__x <
nullptr); }
983 template<
typename _Tp,
typename _Dp>
984 _GLIBCXX_NODISCARD
inline bool
986 {
return !(
nullptr < __x); }
988 #ifdef __cpp_lib_three_way_comparison
989 template<
typename _Tp,
typename _Dp,
typename _Up,
typename _Ep>
990 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
991 typename unique_ptr<_Up, _Ep>::pointer>
994 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
995 typename unique_ptr<_Up, _Ep>::pointer>
996 operator<=>(
const unique_ptr<_Tp, _Dp>& __x,
997 const unique_ptr<_Up, _Ep>& __y)
998 {
return compare_three_way()(__x.get(), __y.get()); }
1000 template<
typename _Tp,
typename _Dp>
1001 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
1002 _GLIBCXX23_CONSTEXPR
1004 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
1005 operator<=>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
1007 using pointer =
typename unique_ptr<_Tp, _Dp>::pointer;
1008 return compare_three_way()(__x.get(),
static_cast<pointer
>(
nullptr));
1014 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
1015 bool = __poison_hash<_Ptr>::__enable_hash_call>
1016 struct __uniq_ptr_hash
1017 #if ! _GLIBCXX_INLINE_VERSION
1018 :
private __poison_hash<_Ptr>
1022 operator()(
const _Up& __u)
const
1023 noexcept(noexcept(
std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
1024 {
return hash<_Ptr>()(__u.get()); }
1027 template<
typename _Up,
typename _Ptr>
1028 struct __uniq_ptr_hash<_Up, _Ptr, false>
1029 :
private __poison_hash<_Ptr>
1034 template<
typename _Tp,
typename _Dp>
1036 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
1037 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
1040 #ifdef __glibcxx_make_unique // C++ >= 14 && HOSTED
1044 template<
typename _Tp>
1048 template<
typename _Tp>
1049 struct _MakeUniq<_Tp[]>
1050 {
typedef unique_ptr<_Tp[]> __array; };
1052 template<
typename _Tp,
size_t _Bound>
1053 struct _MakeUniq<_Tp[_Bound]>
1054 {
struct __invalid_type { }; };
1056 template<
typename _Tp>
1057 using __unique_ptr_t =
typename _MakeUniq<_Tp>::__single_object;
1058 template<
typename _Tp>
1059 using __unique_ptr_array_t =
typename _MakeUniq<_Tp>::__array;
1060 template<
typename _Tp>
1061 using __invalid_make_unique_t =
typename _MakeUniq<_Tp>::__invalid_type;
1072 template<
typename _Tp,
typename... _Args>
1073 _GLIBCXX23_CONSTEXPR
1074 inline __detail::__unique_ptr_t<_Tp>
1087 template<
typename _Tp>
1088 _GLIBCXX23_CONSTEXPR
1089 inline __detail::__unique_ptr_array_t<_Tp>
1098 template<
typename _Tp,
typename... _Args>
1099 __detail::__invalid_make_unique_t<_Tp>
1100 make_unique(_Args&&...) =
delete;
1102 #if __cplusplus > 201703L
1109 template<
typename _Tp>
1110 _GLIBCXX23_CONSTEXPR
1111 inline __detail::__unique_ptr_t<_Tp>
1122 template<
typename _Tp>
1123 _GLIBCXX23_CONSTEXPR
1124 inline __detail::__unique_ptr_array_t<_Tp>
1133 template<
typename _Tp,
typename... _Args>
1134 __detail::__invalid_make_unique_t<_Tp>
1135 make_unique_for_overwrite(_Args&&...) =
delete;
1138 #endif // C++14 && HOSTED
1140 #if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
1146 template<
typename _CharT,
typename _Traits,
typename _Tp,
typename _Dp>
1150 requires requires { __os << __p.get(); }
1155 #endif // C++20 && HOSTED
1157 #if __cpp_variable_templates
1158 template<
typename _Tp>
1159 static constexpr
bool __is_unique_ptr =
false;
1160 template<
typename _Tp,
typename _Del>
1161 static constexpr
bool __is_unique_ptr<unique_ptr<_Tp, _Del>> =
true;
1166 #if __cplusplus >= 201703L
1167 namespace __detail::__variant
1169 template<
typename>
struct _Never_valueless_alt;
1173 template<
typename _Tp,
typename _Del>
1174 struct _Never_valueless_alt<
std::unique_ptr<_Tp, _Del>>
1180 _GLIBCXX_END_NAMESPACE_VERSION