31 #define _UNIQUE_PTR_H 1
39 #if __cplusplus > 201703L
44 namespace std _GLIBCXX_VISIBILITY(default)
46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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
62 template<
typename _Tp>
73 template<typename _Up,
82 "can't delete pointer to incomplete type");
83 static_assert(
sizeof(_Tp)>0,
84 "can't delete pointer to incomplete type");
93 template<
typename _Tp>
109 template<typename _Up,
114 template<
typename _Up>
118 static_assert(
sizeof(_Tp)>0,
119 "can't delete pointer to incomplete type");
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)
161 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
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;
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;
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;
262 template<
typename _Up,
typename _Ep>
263 using __safe_conversion_up = __and_<
265 __not_<is_array<_Up>>
272 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
283 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
296 template<
typename _Del = deleter_type,
297 typename = _Require<is_copy_constructible<_Del>>>
308 template<
typename _Del = deleter_type,
309 typename = _Require<is_move_constructible<_Del>>>
312 _Del&&> __d) noexcept
316 template<
typename _Del = deleter_type,
317 typename _DelUnref =
typename remove_reference<_Del>::type>
320 _DelUnref&&>) =
delete;
323 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
339 template<
typename _Up,
typename _Ep,
typename = _Require<
340 __safe_conversion_up<_Up, _Ep>,
341 __conditional_t<is_reference<_Dp>::value,
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"
352 template<
typename _Up,
typename = _Require<
355 #pragma GCC diagnostic pop
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)
384 template<
typename _Up,
typename _Ep>
386 __safe_conversion_up<_Up, _Ep>,
392 reset(__u.release());
393 get_deleter() = std::forward<_Ep>(__u.get_deleter());
408 typename add_lvalue_reference<element_type>::type
411 __glibcxx_assert(
get() != pointer());
419 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
426 {
return _M_t._M_ptr(); }
431 {
return _M_t._M_deleter(); }
436 {
return _M_t._M_deleter(); }
439 explicit operator bool() const noexcept
440 {
return get() == pointer() ? false :
true; }
447 {
return _M_t.release(); }
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");
467 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
484 template<
typename _Tp,
typename _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;
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;
509 template<
typename _Up,
typename _Ep,
511 typename _UP_pointer =
typename _UPtr::pointer,
512 typename _UP_element_type =
typename _UPtr::element_type>
513 using __safe_conversion_up = __and_<
521 template<
typename _Up>
522 using __safe_conversion_raw = __and_<
523 __or_<__or_<is_same<_Up, pointer>,
525 __and_<is_pointer<_Up>,
528 typename remove_pointer<_Up>::type(*)[],
537 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
549 template<
typename _Up,
551 typename = _DeleterConstraint<_Vp>,
553 __safe_conversion_raw<_Up>::value,
bool>::type>
567 template<
typename _Up,
typename _Del = deleter_type,
568 typename = _Require<__safe_conversion_raw<_Up>,
581 template<
typename _Up,
typename _Del = deleter_type,
582 typename = _Require<__safe_conversion_raw<_Up>,
586 _Del&&> __d) noexcept
590 template<
typename _Up,
typename _Del = deleter_type,
591 typename _DelUnref =
typename remove_reference<_Del>::type,
592 typename = _Require<__safe_conversion_raw<_Up>>>
595 _DelUnref&&>) =
delete;
601 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
606 template<
typename _Up,
typename _Ep,
typename = _Require<
607 __safe_conversion_up<_Up, _Ep>,
608 __conditional_t<is_reference<_Dp>::value,
612 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
618 auto& __ptr = _M_t._M_ptr();
619 if (__ptr !=
nullptr)
640 template<
typename _Up,
typename _Ep>
648 reset(__u.release());
649 get_deleter() = std::forward<_Ep>(__u.get_deleter());
664 typename std::add_lvalue_reference<element_type>::type
667 __glibcxx_assert(
get() != pointer());
674 {
return _M_t._M_ptr(); }
679 {
return _M_t._M_deleter(); }
684 {
return _M_t._M_deleter(); }
687 explicit operator bool() const noexcept
688 {
return get() == pointer() ? false :
true; }
695 {
return _M_t.release(); }
703 template <
typename _Up,
705 __or_<is_same<_Up, pointer>,
706 __and_<is_same<pointer, element_type*>,
709 typename remove_pointer<_Up>::type(*)[],
719 void reset(nullptr_t =
nullptr) noexcept
720 {
reset(pointer()); }
726 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
739 template<
typename _Tp,
typename _Dp>
741 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
743 typename enable_if<__is_swappable<_Dp>::value>::type
751 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
752 template<
typename _Tp,
typename _Dp>
759 template<
typename _Tp,
typename _Dp,
760 typename _Up,
typename _Ep>
761 _GLIBCXX_NODISCARD
inline bool
764 {
return __x.
get() == __y.
get(); }
767 template<
typename _Tp,
typename _Dp>
768 _GLIBCXX_NODISCARD
inline bool
772 #ifndef __cpp_lib_three_way_comparison
774 template<
typename _Tp,
typename _Dp>
775 _GLIBCXX_NODISCARD
inline bool
780 template<
typename _Tp,
typename _Dp,
781 typename _Up,
typename _Ep>
782 _GLIBCXX_NODISCARD
inline bool
785 {
return __x.
get() != __y.
get(); }
788 template<
typename _Tp,
typename _Dp>
789 _GLIBCXX_NODISCARD
inline bool
791 {
return (
bool)__x; }
794 template<
typename _Tp,
typename _Dp>
795 _GLIBCXX_NODISCARD
inline bool
797 {
return (
bool)__x; }
801 template<
typename _Tp,
typename _Dp,
802 typename _Up,
typename _Ep>
803 _GLIBCXX_NODISCARD
inline bool
809 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
814 template<
typename _Tp,
typename _Dp>
815 _GLIBCXX_NODISCARD
inline bool
823 template<
typename _Tp,
typename _Dp>
824 _GLIBCXX_NODISCARD
inline bool
832 template<
typename _Tp,
typename _Dp,
833 typename _Up,
typename _Ep>
834 _GLIBCXX_NODISCARD
inline bool
837 {
return !(__y < __x); }
840 template<
typename _Tp,
typename _Dp>
841 _GLIBCXX_NODISCARD
inline bool
843 {
return !(
nullptr < __x); }
846 template<
typename _Tp,
typename _Dp>
847 _GLIBCXX_NODISCARD
inline bool
849 {
return !(__x <
nullptr); }
852 template<
typename _Tp,
typename _Dp,
853 typename _Up,
typename _Ep>
854 _GLIBCXX_NODISCARD
inline bool
857 {
return (__y < __x); }
860 template<
typename _Tp,
typename _Dp>
861 _GLIBCXX_NODISCARD
inline bool
869 template<
typename _Tp,
typename _Dp>
870 _GLIBCXX_NODISCARD
inline bool
878 template<
typename _Tp,
typename _Dp,
879 typename _Up,
typename _Ep>
880 _GLIBCXX_NODISCARD
inline bool
883 {
return !(__x < __y); }
886 template<
typename _Tp,
typename _Dp>
887 _GLIBCXX_NODISCARD
inline bool
889 {
return !(__x <
nullptr); }
892 template<
typename _Tp,
typename _Dp>
893 _GLIBCXX_NODISCARD
inline bool
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));
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>
941 template<
typename _Tp,
typename _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 201304L
953 template<
typename _Tp>
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;
981 template<
typename _Tp,
typename... _Args>
982 inline __detail::__unique_ptr_t<_Tp>
995 template<
typename _Tp>
996 inline __detail::__unique_ptr_array_t<_Tp>
1005 template<
typename _Tp,
typename... _Args>
1006 __detail::__invalid_make_unique_t<_Tp>
1009 #if __cplusplus > 201703L
1016 template<
typename _Tp>
1017 inline __detail::__unique_ptr_t<_Tp>
1028 template<
typename _Tp>
1029 inline __detail::__unique_ptr_array_t<_Tp>
1038 template<
typename _Tp,
typename... _Args>
1039 __detail::__invalid_make_unique_t<_Tp>
1045 #if __cplusplus > 201703L && __cpp_concepts
1051 template<
typename _CharT,
typename _Traits,
typename _Tp,
typename _Dp>
1055 requires requires { __os << __p.get(); }
1064 #if __cplusplus >= 201703L
1065 namespace __detail::__variant
1067 template<
typename>
struct _Never_valueless_alt;
1071 template<
typename _Tp,
typename _Del>
1072 struct _Never_valueless_alt<
std::unique_ptr<_Tp, _Del>>
1078 _GLIBCXX_END_NAMESPACE_VERSION
__detail::__invalid_make_unique_t< _Tp > make_unique_for_overwrite(_Args &&...)=delete
__detail::__unique_ptr_t< _Tp > make_unique_for_overwrite()
__detail::__unique_ptr_t< _Tp > make_unique(_Args &&... __args)
enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
__detail::__unique_ptr_array_t< _Tp > make_unique(size_t __num)
__detail::__unique_ptr_array_t< _Tp > make_unique_for_overwrite(size_t __num)
__detail::__invalid_make_unique_t< _Tp > make_unique(_Args &&...)=delete
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.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
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.
Primary template of default_delete, used by unique_ptr for single objects.
constexpr default_delete() noexcept=default
Default constructor.
void operator()(_Tp *__ptr) const
Calls delete __ptr
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.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
unique_ptr(pointer __p, const deleter_type &__d) noexcept
unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
add_lvalue_reference< element_type >::type operator*() const noexcept(noexcept(*std::declval< pointer >()))
Dereference the stored pointer.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
unique_ptr(unique_ptr &&)=default
Move constructor.
unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
unique_ptr(pointer __p) noexcept
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
pointer operator->() const noexcept
Return the stored pointer.
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.
pointer get() const noexcept
Return the stored pointer.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
pointer release() noexcept
Release ownership of any stored pointer.
pointer release() noexcept
Release ownership of any stored pointer.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
void reset(_Up __p) noexcept
Replace the stored pointer.
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
unique_ptr(_Up __p, const deleter_type &__d) noexcept
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
unique_ptr(_Up __p) noexcept
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(unique_ptr &&)=default
Move constructor.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
pointer get() const noexcept
Return the stored pointer.
unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept