31 #define _UNIQUE_PTR_H 1
40 #if __cplusplus > 201703L
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
54 #if _GLIBCXX_USE_DEPRECATED
55 #pragma GCC diagnostic push
56 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
57 template<
typename>
class auto_ptr;
58 #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() {
return std::get<0>(_M_t); }
173 pointer _M_ptr()
const {
return std::get<0>(_M_t); }
174 _Dp& _M_deleter() {
return std::get<1>(_M_t); }
175 const _Dp& _M_deleter()
const {
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;
241 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
244 template <
typename _Up>
245 using _DeleterConstraint =
246 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
248 __uniq_ptr_data<_Tp, _Dp> _M_t;
251 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
252 using element_type = _Tp;
253 using deleter_type = _Dp;
258 template<
typename _Up,
typename _Ep>
259 using __safe_conversion_up = __and_<
261 __not_<is_array<_Up>>
268 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
279 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
292 template<
typename _Del = deleter_type,
293 typename = _Require<is_copy_constructible<_Del>>>
304 template<
typename _Del = deleter_type,
305 typename = _Require<is_move_constructible<_Del>>>
308 _Del&&> __d) noexcept
312 template<
typename _Del = deleter_type,
313 typename _DelUnref =
typename remove_reference<_Del>::type>
316 _DelUnref&&>) =
delete;
319 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
335 template<
typename _Up,
typename _Ep,
typename = _Require<
336 __safe_conversion_up<_Up, _Ep>,
341 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
344 #if _GLIBCXX_USE_DEPRECATED
345 #pragma GCC diagnostic push
346 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
348 template<
typename _Up,
typename = _Require<
351 #pragma GCC diagnostic pop
357 static_assert(__is_invocable<deleter_type&, pointer>::value,
358 "unique_ptr's deleter must be invocable with a pointer");
359 auto& __ptr = _M_t._M_ptr();
360 if (__ptr !=
nullptr)
380 template<
typename _Up,
typename _Ep>
382 __safe_conversion_up<_Up, _Ep>,
388 reset(__u.release());
389 get_deleter() = std::forward<_Ep>(__u.get_deleter());
404 typename add_lvalue_reference<element_type>::type
407 __glibcxx_assert(
get() != pointer());
415 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
422 {
return _M_t._M_ptr(); }
427 {
return _M_t._M_deleter(); }
432 {
return _M_t._M_deleter(); }
435 explicit operator bool() const noexcept
436 {
return get() == pointer() ? false :
true; }
443 {
return _M_t.release(); }
452 reset(pointer __p = pointer()) noexcept
454 static_assert(__is_invocable<deleter_type&, pointer>::value,
455 "unique_ptr's deleter must be invocable with a pointer");
463 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
476 template<
typename _Tp,
typename _Dp>
479 template <
typename _Up>
480 using _DeleterConstraint =
481 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
483 __uniq_ptr_data<_Tp, _Dp> _M_t;
485 template<
typename _Up>
486 using __remove_cv =
typename remove_cv<_Up>::type;
489 template<
typename _Up>
490 using __is_derived_Tp
491 = __and_< is_base_of<_Tp, _Up>,
492 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
495 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
496 using element_type = _Tp;
497 using deleter_type = _Dp;
501 template<
typename _Up,
typename _Ep,
503 typename _UP_pointer =
typename _UPtr::pointer,
504 typename _UP_element_type =
typename _UPtr::element_type>
505 using __safe_conversion_up = __and_<
513 template<
typename _Up>
514 using __safe_conversion_raw = __and_<
515 __or_<__or_<is_same<_Up, pointer>,
517 __and_<is_pointer<_Up>,
520 typename remove_pointer<_Up>::type(*)[],
529 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
541 template<
typename _Up,
543 typename = _DeleterConstraint<_Vp>,
545 __safe_conversion_raw<_Up>::value,
bool>::type>
559 template<
typename _Up,
typename _Del = deleter_type,
560 typename = _Require<__safe_conversion_raw<_Up>,
573 template<
typename _Up,
typename _Del = deleter_type,
574 typename = _Require<__safe_conversion_raw<_Up>,
578 _Del&&> __d) noexcept
582 template<
typename _Up,
typename _Del = deleter_type,
583 typename _DelUnref =
typename remove_reference<_Del>::type,
584 typename = _Require<__safe_conversion_raw<_Up>>>
587 _DelUnref&&>) =
delete;
593 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
598 template<
typename _Up,
typename _Ep,
typename = _Require<
599 __safe_conversion_up<_Up, _Ep>,
604 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
610 auto& __ptr = _M_t._M_ptr();
611 if (__ptr !=
nullptr)
632 template<
typename _Up,
typename _Ep>
640 reset(__u.release());
641 get_deleter() = std::forward<_Ep>(__u.get_deleter());
656 typename std::add_lvalue_reference<element_type>::type
659 __glibcxx_assert(
get() != pointer());
666 {
return _M_t._M_ptr(); }
671 {
return _M_t._M_deleter(); }
676 {
return _M_t._M_deleter(); }
679 explicit operator bool() const noexcept
680 {
return get() == pointer() ? false :
true; }
687 {
return _M_t.release(); }
695 template <
typename _Up,
697 __or_<is_same<_Up, pointer>,
698 __and_<is_same<pointer, element_type*>,
701 typename remove_pointer<_Up>::type(*)[],
711 void reset(nullptr_t =
nullptr) noexcept
712 {
reset(pointer()); }
718 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
730 template<
typename _Tp,
typename _Dp>
732 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
734 typename enable_if<__is_swappable<_Dp>::value>::type
742 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
743 template<
typename _Tp,
typename _Dp>
750 template<
typename _Tp,
typename _Dp,
751 typename _Up,
typename _Ep>
752 _GLIBCXX_NODISCARD
inline bool
755 {
return __x.
get() == __y.
get(); }
758 template<
typename _Tp,
typename _Dp>
759 _GLIBCXX_NODISCARD
inline bool
763 #ifndef __cpp_lib_three_way_comparison
765 template<
typename _Tp,
typename _Dp>
766 _GLIBCXX_NODISCARD
inline bool
771 template<
typename _Tp,
typename _Dp,
772 typename _Up,
typename _Ep>
773 _GLIBCXX_NODISCARD
inline bool
776 {
return __x.
get() != __y.
get(); }
779 template<
typename _Tp,
typename _Dp>
780 _GLIBCXX_NODISCARD
inline bool
782 {
return (
bool)__x; }
785 template<
typename _Tp,
typename _Dp>
786 _GLIBCXX_NODISCARD
inline bool
788 {
return (
bool)__x; }
792 template<
typename _Tp,
typename _Dp,
793 typename _Up,
typename _Ep>
794 _GLIBCXX_NODISCARD
inline bool
800 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
805 template<
typename _Tp,
typename _Dp>
806 _GLIBCXX_NODISCARD
inline bool
814 template<
typename _Tp,
typename _Dp>
815 _GLIBCXX_NODISCARD
inline bool
823 template<
typename _Tp,
typename _Dp,
824 typename _Up,
typename _Ep>
825 _GLIBCXX_NODISCARD
inline bool
828 {
return !(__y < __x); }
831 template<
typename _Tp,
typename _Dp>
832 _GLIBCXX_NODISCARD
inline bool
834 {
return !(
nullptr < __x); }
837 template<
typename _Tp,
typename _Dp>
838 _GLIBCXX_NODISCARD
inline bool
840 {
return !(__x <
nullptr); }
843 template<
typename _Tp,
typename _Dp,
844 typename _Up,
typename _Ep>
845 _GLIBCXX_NODISCARD
inline bool
848 {
return (__y < __x); }
851 template<
typename _Tp,
typename _Dp>
852 _GLIBCXX_NODISCARD
inline bool
860 template<
typename _Tp,
typename _Dp>
861 _GLIBCXX_NODISCARD
inline bool
869 template<
typename _Tp,
typename _Dp,
870 typename _Up,
typename _Ep>
871 _GLIBCXX_NODISCARD
inline bool
874 {
return !(__x < __y); }
877 template<
typename _Tp,
typename _Dp>
878 _GLIBCXX_NODISCARD
inline bool
880 {
return !(__x <
nullptr); }
883 template<
typename _Tp,
typename _Dp>
884 _GLIBCXX_NODISCARD
inline bool
886 {
return !(
nullptr < __x); }
888 #ifdef __cpp_lib_three_way_comparison
889 template<
typename _Tp,
typename _Dp,
typename _Up,
typename _Ep>
890 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
891 typename unique_ptr<_Up, _Ep>::pointer>
893 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
894 typename unique_ptr<_Up, _Ep>::pointer>
897 {
return compare_three_way()(__x.
get(), __y.
get()); }
899 template<
typename _Tp,
typename _Dp>
900 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
902 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
903 operator<=>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
905 using pointer =
typename unique_ptr<_Tp, _Dp>::pointer;
906 return compare_three_way()(__x.get(),
static_cast<pointer
>(
nullptr));
912 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
913 bool = __poison_hash<_Ptr>::__enable_hash_call>
914 struct __uniq_ptr_hash
915 #if ! _GLIBCXX_INLINE_VERSION
916 :
private __poison_hash<_Ptr>
920 operator()(
const _Up& __u)
const
921 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
922 {
return hash<_Ptr>()(__u.get()); }
925 template<
typename _Up,
typename _Ptr>
926 struct __uniq_ptr_hash<_Up, _Ptr, false>
927 :
private __poison_hash<_Ptr>
932 template<
typename _Tp,
typename _Dp>
934 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
935 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
938 #if __cplusplus >= 201402L
940 #define __cpp_lib_make_unique 201304
944 template<
typename _Tp>
946 {
typedef unique_ptr<_Tp> __single_object; };
948 template<
typename _Tp>
949 struct _MakeUniq<_Tp[]>
950 {
typedef unique_ptr<_Tp[]> __array; };
952 template<
typename _Tp,
size_t _Bound>
953 struct _MakeUniq<_Tp[_Bound]>
954 {
struct __invalid_type { }; };
959 template<
typename _Tp,
typename... _Args>
960 inline typename _MakeUniq<_Tp>::__single_object
965 template<
typename _Tp>
966 inline typename _MakeUniq<_Tp>::__array
971 template<
typename _Tp,
typename... _Args>
972 inline typename _MakeUniq<_Tp>::__invalid_type
977 #if __cplusplus > 201703L && __cpp_concepts
981 template<
typename _CharT,
typename _Traits,
typename _Tp,
typename _Dp>
985 requires requires { __os << __p.get(); }
994 #if __cplusplus >= 201703L
995 namespace __detail::__variant
997 template<
typename>
struct _Never_valueless_alt;
1001 template<
typename _Tp,
typename _Del>
1002 struct _Never_valueless_alt<
std::unique_ptr<_Tp, _Del>>
1008 _GLIBCXX_END_NAMESPACE_VERSION
bool operator==(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Equality operator for unique_ptr objects, compares the owned pointers.
bool operator==(nullptr_t, const unique_ptr< _Tp, _Dp > &__x) noexcept
unique_ptr comparison with nullptr
bool operator>=(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Relational operator for unique_ptr objects, compares the owned pointers.
bool operator==(const unique_ptr< _Tp, _Dp > &__x, nullptr_t) noexcept
unique_ptr comparison with nullptr
bool operator!=(nullptr_t, const unique_ptr< _Tp, _Dp > &__x) noexcept
unique_ptr comparison with nullptr
bool operator!=(const unique_ptr< _Tp, _Dp > &__x, nullptr_t) noexcept
unique_ptr comparison with nullptr
enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
_MakeUniq< _Tp >::__array make_unique(size_t __num)
std::make_unique for arrays of unknown bound
bool operator>(nullptr_t, const unique_ptr< _Tp, _Dp > &__x)
unique_ptr comparison with nullptr
bool operator>(const unique_ptr< _Tp, _Dp > &__x, nullptr_t)
unique_ptr comparison with nullptr
bool operator>=(const unique_ptr< _Tp, _Dp > &__x, nullptr_t)
unique_ptr comparison with nullptr
bool operator!=(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Inequality operator for unique_ptr objects, compares the owned pointers.
bool operator>=(nullptr_t, const unique_ptr< _Tp, _Dp > &__x)
unique_ptr comparison with nullptr
_MakeUniq< _Tp >::__invalid_type make_unique(_Args &&...)=delete
Disable std::make_unique for arrays of known bound.
bool operator>(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Relational operator for unique_ptr objects, compares the owned pointers.
_MakeUniq< _Tp >::__single_object make_unique(_Args &&... __args)
std::make_unique for single objects
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
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 to one of two argument types.
Define a member typedef type only if a boolean constant is true.
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.
20.7.1.2 unique_ptr for single objects.
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.
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.
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
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
A simple smart pointer providing strict ownership semantics.