32#define _UNIQUE_PTR_H 1
40#if __cplusplus >= 202002L
47namespace std _GLIBCXX_VISIBILITY(default)
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
56#if _GLIBCXX_USE_DEPRECATED
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
59 template<
typename>
class auto_ptr;
60#pragma GCC diagnostic pop
68 template<
typename _Tp>
79 template<typename _Up,
80 typename = _Require<is_convertible<_Up*, _Tp*>>>
90 "can't delete pointer to incomplete type");
91 static_assert(
sizeof(_Tp)>0,
92 "can't delete pointer to incomplete type");
105 template<
typename _Tp>
121 template<typename _Up,
122 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
127 template<
typename _Up>
129 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
132 static_assert(
sizeof(_Tp)>0,
133 "can't delete pointer to incomplete type");
141 template <
typename _Tp,
typename _Dp>
142 class __uniq_ptr_impl
144 template <
typename _Up,
typename _Ep,
typename =
void>
150 template <
typename _Up,
typename _Ep>
152 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
154 using type =
typename remove_reference<_Ep>::type::pointer;
158 using _DeleterConstraint = enable_if<
159 __and_<__not_<is_pointer<_Dp>>,
160 is_default_constructible<_Dp>>::value>;
162 using pointer =
typename _Ptr<_Tp, _Dp>::type;
164 static_assert( !is_rvalue_reference<_Dp>::value,
165 "unique_ptr's deleter type must be a function object type"
166 " or an lvalue reference type" );
168 __uniq_ptr_impl() =
default;
170 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
172 template<
typename _Del>
174 __uniq_ptr_impl(pointer __p, _Del&& __d)
178 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
180 { __u._M_ptr() =
nullptr; }
183 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u)
noexcept
185 reset(__u.release());
191 pointer& _M_ptr() noexcept {
return std::get<0>(_M_t); }
193 pointer _M_ptr() const noexcept {
return std::get<0>(_M_t); }
195 _Dp& _M_deleter() noexcept {
return std::get<1>(_M_t); }
197 const _Dp& _M_deleter() const noexcept {
return std::get<1>(_M_t); }
200 void reset(pointer __p)
noexcept
202 const pointer __old_p = _M_ptr();
205 _M_deleter()(__old_p);
209 pointer release() noexcept
211 pointer __p = _M_ptr();
218 swap(__uniq_ptr_impl& __rhs)
noexcept
221 swap(this->_M_ptr(), __rhs._M_ptr());
222 swap(this->_M_deleter(), __rhs._M_deleter());
226 tuple<pointer, _Dp> _M_t;
230 template <
typename _Tp,
typename _Dp,
231 bool = is_move_constructible<_Dp>::value,
232 bool = is_move_assignable<_Dp>::value>
233 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
235 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
236 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
237 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
240 template <
typename _Tp,
typename _Dp>
241 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
243 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
244 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
245 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
248 template <
typename _Tp,
typename _Dp>
249 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
251 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
252 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
253 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
256 template <
typename _Tp,
typename _Dp>
257 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
259 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
260 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
261 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
270 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
273 template <
typename _Up>
274 using _DeleterConstraint =
275 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
277 __uniq_ptr_data<_Tp, _Dp> _M_t;
280 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
281 using element_type = _Tp;
282 using deleter_type = _Dp;
287 template<
typename _Up,
typename _Ep>
288 using __safe_conversion_up = __and_<
289 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
290 __not_<is_array<_Up>>
297 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
308 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
322 template<
typename _Del = deleter_type,
323 typename = _Require<is_copy_constructible<_Del>>>
335 template<
typename _Del = deleter_type,
336 typename = _Require<is_move_constructible<_Del>>>
340 _Del&&> __d) noexcept
344 template<
typename _Del = deleter_type,
345 typename _DelUnref =
typename remove_reference<_Del>::type>
349 _DelUnref&&>) =
delete;
352 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
368 template<
typename _Up,
typename _Ep,
typename = _Require<
369 __safe_conversion_up<_Up, _Ep>,
370 __conditional_t<is_reference<_Dp>::value,
372 is_convertible<_Ep, _Dp>>>>
378#if _GLIBCXX_USE_DEPRECATED
379#pragma GCC diagnostic push
380#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
382 template<
typename _Up,
383 typename = _Require<is_convertible<_Up*, pointer>,
386#pragma GCC diagnostic pop
390#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
395 static_assert(__is_invocable<deleter_type&, pointer>::value,
396 "unique_ptr's deleter must be invocable with a pointer");
397 auto& __ptr = _M_t._M_ptr();
398 if (__ptr !=
nullptr)
418 template<
typename _Up,
typename _Ep>
421 __safe_conversion_up<_Up, _Ep>,
427 reset(__u.release());
445 typename add_lvalue_reference<element_type>::type
448 __glibcxx_assert(
get() != pointer());
457 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
465 {
return _M_t._M_ptr(); }
471 {
return _M_t._M_deleter(); }
477 {
return _M_t._M_deleter(); }
481 explicit operator bool() const noexcept
482 {
return get() == pointer() ? false :
true; }
490 {
return _M_t.release(); }
500 reset(pointer __p = pointer()) noexcept
502 static_assert(__is_invocable<deleter_type&, pointer>::value,
503 "unique_ptr's deleter must be invocable with a pointer");
512 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
521#ifdef __glibcxx_out_ptr
522 template<
typename,
typename,
typename...>
523 friend class out_ptr_t;
524 template<
typename,
typename,
typename...>
525 friend class inout_ptr_t;
537 template<
typename _Tp,
typename _Dp>
540 template <
typename _Up>
541 using _DeleterConstraint =
542 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
544 __uniq_ptr_data<_Tp, _Dp> _M_t;
547 template<
typename _Up>
548 using __is_derived_Tp
549 = __and_< is_base_of<_Tp, _Up>,
550 __not_<is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up>>> >;
553 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
554 using element_type = _Tp;
555 using deleter_type = _Dp;
559 template<
typename _Up,
typename _Ep,
561 typename _UP_pointer =
typename _UPtr::pointer,
562 typename _UP_element_type =
typename _UPtr::element_type>
563 using __safe_conversion_up = __and_<
567 is_convertible<_UP_element_type(*)[], element_type(*)[]>
571 template<
typename _Up>
572 using __safe_conversion_raw = __and_<
573 __or_<__or_<is_same<_Up, pointer>,
575 __and_<is_pointer<_Up>,
578 typename remove_pointer<_Up>::type(*)[],
587 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
599 template<
typename _Up,
601 typename = _DeleterConstraint<_Vp>,
603 __safe_conversion_raw<_Up>::value,
bool>::type>
618 template<
typename _Up,
typename _Del = deleter_type,
619 typename = _Require<__safe_conversion_raw<_Up>,
622 unique_ptr(_Up __p,
const deleter_type& __d) noexcept
633 template<
typename _Up,
typename _Del = deleter_type,
634 typename = _Require<__safe_conversion_raw<_Up>,
639 _Del&&> __d) noexcept
643 template<
typename _Up,
typename _Del = deleter_type,
644 typename _DelUnref =
typename remove_reference<_Del>::type,
645 typename = _Require<__safe_conversion_raw<_Up>>>
648 _DelUnref&&>) =
delete;
654 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
659 template<
typename _Up,
typename _Ep,
typename = _Require<
660 __safe_conversion_up<_Up, _Ep>,
661 __conditional_t<is_reference<_Dp>::value,
663 is_convertible<_Ep, _Dp>>>>
670#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
675 auto& __ptr = _M_t._M_ptr();
676 if (__ptr !=
nullptr)
677 get_deleter()(__ptr);
697 template<
typename _Up,
typename _Ep>
706 reset(__u.release());
714 operator=(nullptr_t)
noexcept
724 typename std::add_lvalue_reference<element_type>::type
725 operator[](
size_t __i)
const
727 __glibcxx_assert(get() != pointer());
735 {
return _M_t._M_ptr(); }
740 get_deleter() noexcept
741 {
return _M_t._M_deleter(); }
746 get_deleter() const noexcept
747 {
return _M_t._M_deleter(); }
751 explicit operator bool() const noexcept
752 {
return get() == pointer() ? false :
true; }
760 {
return _M_t.release(); }
768 template <
typename _Up,
770 __or_<is_same<_Up, pointer>,
771 __and_<is_same<pointer, element_type*>,
774 typename remove_pointer<_Up>::type(*)[],
782 reset(_Up __p)
noexcept
786 void reset(nullptr_t =
nullptr) noexcept
787 { reset(pointer()); }
794 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
803#ifdef __glibcxx_out_ptr
804 template<
typename,
typename,
typename...>
friend class out_ptr_t;
805 template<
typename,
typename,
typename...>
friend class inout_ptr_t;
813 template<
typename _Tp,
typename _Dp>
815#if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
818 typename enable_if<__is_swappable<_Dp>::value>::type
826#if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
827 template<
typename _Tp,
typename _Dp>
834 template<
typename _Tp,
typename _Dp,
835 typename _Up,
typename _Ep>
836 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
840 {
return __x.
get() == __y.get(); }
843 template<
typename _Tp,
typename _Dp>
844 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
849#ifndef __cpp_lib_three_way_comparison
851 template<
typename _Tp,
typename _Dp>
854 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
noexcept
858 template<
typename _Tp,
typename _Dp,
859 typename _Up,
typename _Ep>
862 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
863 const unique_ptr<_Up, _Ep>& __y)
864 {
return __x.get() != __y.get(); }
867 template<
typename _Tp,
typename _Dp>
870 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
noexcept
871 {
return (
bool)__x; }
874 template<
typename _Tp,
typename _Dp>
877 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
noexcept
878 {
return (
bool)__x; }
882 template<
typename _Tp,
typename _Dp,
883 typename _Up,
typename _Ep>
884 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
891 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
896 template<
typename _Tp,
typename _Dp>
897 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
906 template<
typename _Tp,
typename _Dp>
907 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
916 template<
typename _Tp,
typename _Dp,
917 typename _Up,
typename _Ep>
918 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
922 {
return !(__y < __x); }
925 template<
typename _Tp,
typename _Dp>
926 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
929 {
return !(
nullptr < __x); }
932 template<
typename _Tp,
typename _Dp>
933 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
936 {
return !(__x <
nullptr); }
939 template<
typename _Tp,
typename _Dp,
940 typename _Up,
typename _Ep>
941 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
945 {
return (__y < __x); }
948 template<
typename _Tp,
typename _Dp>
949 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
958 template<
typename _Tp,
typename _Dp>
959 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
968 template<
typename _Tp,
typename _Dp,
969 typename _Up,
typename _Ep>
970 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
974 {
return !(__x < __y); }
977 template<
typename _Tp,
typename _Dp>
978 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
981 {
return !(__x <
nullptr); }
984 template<
typename _Tp,
typename _Dp>
985 _GLIBCXX_NODISCARD
inline bool
987 {
return !(
nullptr < __x); }
989#ifdef __cpp_lib_three_way_comparison
990 template<
typename _Tp,
typename _Dp,
typename _Up,
typename _Ep>
991 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
992 typename unique_ptr<_Up, _Ep>::pointer>
995 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
996 typename unique_ptr<_Up, _Ep>::pointer>
997 operator<=>(
const unique_ptr<_Tp, _Dp>& __x,
998 const unique_ptr<_Up, _Ep>& __y)
999 {
return compare_three_way()(__x.get(), __y.get()); }
1001 template<
typename _Tp,
typename _Dp>
1002 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
1003 _GLIBCXX23_CONSTEXPR
1005 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
1006 operator<=>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
1008 using pointer =
typename unique_ptr<_Tp, _Dp>::pointer;
1009 return compare_three_way()(__x.get(),
static_cast<pointer
>(
nullptr));
1015 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
1016 bool = __poison_hash<_Ptr>::__enable_hash_call>
1017 struct __uniq_ptr_hash
1018#if ! _GLIBCXX_INLINE_VERSION
1019 :
private __poison_hash<_Ptr>
1023 operator()(
const _Up& __u)
const
1025 {
return hash<_Ptr>()(__u.get()); }
1028 template<
typename _Up,
typename _Ptr>
1029 struct __uniq_ptr_hash<_Up, _Ptr, false>
1030 :
private __poison_hash<_Ptr>
1035 template<
typename _Tp,
typename _Dp>
1037 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
1038 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
1041#ifdef __glibcxx_make_unique
1045 template<
typename _Tp>
1049 template<
typename _Tp>
1050 struct _MakeUniq<_Tp[]>
1051 {
typedef unique_ptr<_Tp[]> __array; };
1053 template<
typename _Tp,
size_t _Bound>
1054 struct _MakeUniq<_Tp[_Bound]>
1055 {
struct __invalid_type { }; };
1057 template<
typename _Tp>
1058 using __unique_ptr_t =
typename _MakeUniq<_Tp>::__single_object;
1059 template<
typename _Tp>
1060 using __unique_ptr_array_t =
typename _MakeUniq<_Tp>::__array;
1061 template<
typename _Tp>
1062 using __invalid_make_unique_t =
typename _MakeUniq<_Tp>::__invalid_type;
1073 template<
typename _Tp,
typename... _Args>
1074 _GLIBCXX23_CONSTEXPR
1075 inline __detail::__unique_ptr_t<_Tp>
1088 template<
typename _Tp>
1089 _GLIBCXX23_CONSTEXPR
1090 inline __detail::__unique_ptr_array_t<_Tp>
1099 template<
typename _Tp,
typename... _Args>
1100 __detail::__invalid_make_unique_t<_Tp>
1103#if __cplusplus > 201703L
1110 template<
typename _Tp>
1111 _GLIBCXX23_CONSTEXPR
1112 inline __detail::__unique_ptr_t<_Tp>
1123 template<
typename _Tp>
1124 _GLIBCXX23_CONSTEXPR
1125 inline __detail::__unique_ptr_array_t<_Tp>
1134 template<
typename _Tp,
typename... _Args>
1135 __detail::__invalid_make_unique_t<_Tp>
1141#if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
1147 template<
typename _CharT,
typename _Traits,
typename _Tp,
typename _Dp>
1151 requires requires { __os << __p.
get(); }
1158#if __cpp_variable_templates
1159 template<
typename _Tp>
1160 static constexpr bool __is_unique_ptr =
false;
1161 template<
typename _Tp,
typename _Del>
1162 static constexpr bool __is_unique_ptr<unique_ptr<_Tp, _Del>> =
true;
1167#if __cplusplus >= 201703L
1168 namespace __detail::__variant
1170 template<
typename>
struct _Never_valueless_alt;
1174 template<
typename _Tp,
typename _Del>
1175 struct _Never_valueless_alt<
std::unique_ptr<_Tp, _Del>>
1181_GLIBCXX_END_NAMESPACE_VERSION
__detail::__invalid_make_unique_t< _Tp > make_unique_for_overwrite(_Args &&...)=delete
constexpr __detail::__unique_ptr_array_t< _Tp > make_unique_for_overwrite(size_t __num)
constexpr __detail::__unique_ptr_array_t< _Tp > make_unique(size_t __num)
constexpr enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
__detail::__invalid_make_unique_t< _Tp > make_unique(_Args &&...)=delete
constexpr __detail::__unique_ptr_t< _Tp > make_unique_for_overwrite()
constexpr __detail::__unique_ptr_t< _Tp > make_unique(_Args &&... __args)
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Template class basic_ostream.
Primary class template hash.
Define a member typedef type only if a boolean constant is true.
A simple smart pointer providing strict ownership semantics.
One of the comparison functors.
constexpr void operator()(_Tp *__ptr) const
Calls delete __ptr
constexpr default_delete() noexcept=default
Default constructor.
constexpr enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr
constexpr default_delete() noexcept=default
Default constructor.
A move-only smart pointer that manages unique ownership of a resource.
constexpr pointer operator->() const noexcept
Return the stored pointer.
constexpr unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
constexpr unique_ptr(pointer __p) noexcept
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
constexpr unique_ptr(pointer __p, const deleter_type &__d) noexcept
unique_ptr(unique_ptr &&)=default
Move constructor.
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
constexpr void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
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.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
constexpr unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
constexpr deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
constexpr add_lvalue_reference< element_type >::type operator*() const noexcept(noexcept(*std::declval< pointer >()))
Dereference the stored pointer.
constexpr void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
constexpr pointer get() const noexcept
Return the stored pointer.
constexpr unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept
constexpr pointer release() noexcept
Release ownership of any stored pointer.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
constexpr const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.