31 #define _UNIQUE_PTR_H 1 40 #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 61 template<
typename _Tp>
72 template<
typename _Up,
73 typename = _Require<is_convertible<_Up*, _Tp*>>>
81 "can't delete pointer to incomplete type");
82 static_assert(
sizeof(_Tp)>0,
83 "can't delete pointer to incomplete type");
92 template<
typename _Tp>
108 template<
typename _Up,
109 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
113 template<
typename _Up>
117 static_assert(
sizeof(_Tp)>0,
118 "can't delete pointer to incomplete type");
126 template <
typename _Tp,
typename _Dp>
127 class __uniq_ptr_impl
129 template <
typename _Up,
typename _Ep,
typename =
void>
135 template <
typename _Up,
typename _Ep>
137 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
139 using type =
typename remove_reference<_Ep>::type::pointer;
143 using _DeleterConstraint = enable_if<
144 __and_<__not_<is_pointer<_Dp>>,
145 is_default_constructible<_Dp>>::value>;
147 using pointer =
typename _Ptr<_Tp, _Dp>::type;
149 static_assert( !is_rvalue_reference<_Dp>::value,
150 "unique_ptr's deleter type must be a function object type" 151 " or an lvalue reference type" );
153 __uniq_ptr_impl() =
default;
154 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
156 template<
typename _Del>
157 __uniq_ptr_impl(pointer __p, _Del&& __d)
160 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
162 { __u._M_ptr() =
nullptr; }
164 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
166 reset(__u.release());
167 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
171 pointer& _M_ptr() {
return std::get<0>(_M_t); }
172 pointer _M_ptr()
const {
return std::get<0>(_M_t); }
173 _Dp& _M_deleter() {
return std::get<1>(_M_t); }
174 const _Dp& _M_deleter()
const {
return std::get<1>(_M_t); }
176 void reset(pointer __p) noexcept
178 const pointer __old_p = _M_ptr();
181 _M_deleter()(__old_p);
184 pointer release() noexcept
186 pointer __p = _M_ptr();
192 swap(__uniq_ptr_impl& __rhs) noexcept
195 swap(this->_M_ptr(), __rhs._M_ptr());
196 swap(this->_M_deleter(), __rhs._M_deleter());
200 tuple<pointer, _Dp> _M_t;
204 template <
typename _Tp,
typename _Dp,
205 bool = is_move_constructible<_Dp>::value,
206 bool = is_move_assignable<_Dp>::value>
207 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
209 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
210 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
211 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
214 template <
typename _Tp,
typename _Dp>
215 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
217 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
218 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
219 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
222 template <
typename _Tp,
typename _Dp>
223 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
225 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
226 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
227 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
230 template <
typename _Tp,
typename _Dp>
231 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
233 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
234 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
235 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
240 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
243 template <
typename _Up>
244 using _DeleterConstraint =
245 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
247 __uniq_ptr_data<_Tp, _Dp> _M_t;
250 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
251 using element_type = _Tp;
252 using deleter_type = _Dp;
257 template<
typename _Up,
typename _Ep>
258 using __safe_conversion_up = __and_<
260 __not_<is_array<_Up>>
267 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
278 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
291 template<
typename _Del = deleter_type,
292 typename = _Require<is_copy_constructible<_Del>>>
303 template<
typename _Del = deleter_type,
304 typename = _Require<is_move_constructible<_Del>>>
307 _Del&&> __d) noexcept
311 template<
typename _Del = deleter_type,
312 typename _DelUnref =
typename remove_reference<_Del>::type>
315 _DelUnref&&>) =
delete;
318 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
334 template<
typename _Up,
typename _Ep,
typename = _Require<
335 __safe_conversion_up<_Up, _Ep>,
340 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
343 #if _GLIBCXX_USE_DEPRECATED 344 #pragma GCC diagnostic push 345 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 347 template<
typename _Up,
typename = _Require<
350 #pragma GCC diagnostic pop 356 static_assert(__is_invocable<deleter_type&, pointer>::value,
357 "unique_ptr's deleter must be invocable with a pointer");
358 auto& __ptr = _M_t._M_ptr();
359 if (__ptr !=
nullptr)
379 template<
typename _Up,
typename _Ep>
381 __safe_conversion_up<_Up, _Ep>,
387 reset(__u.release());
388 get_deleter() = std::forward<_Ep>(__u.get_deleter());
403 typename add_lvalue_reference<element_type>::type
406 __glibcxx_assert(
get() != pointer());
414 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
421 {
return _M_t._M_ptr(); }
426 {
return _M_t._M_deleter(); }
431 {
return _M_t._M_deleter(); }
434 explicit operator bool() const noexcept
435 {
return get() == pointer() ? false :
true; }
442 {
return _M_t.release(); }
451 reset(pointer __p = pointer()) noexcept
453 static_assert(__is_invocable<deleter_type&, pointer>::value,
454 "unique_ptr's deleter must be invocable with a pointer");
462 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
475 template<
typename _Tp,
typename _Dp>
478 template <
typename _Up>
479 using _DeleterConstraint =
480 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
482 __uniq_ptr_data<_Tp, _Dp> _M_t;
484 template<
typename _Up>
485 using __remove_cv =
typename remove_cv<_Up>::type;
488 template<
typename _Up>
489 using __is_derived_Tp
490 = __and_< is_base_of<_Tp, _Up>,
491 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
494 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
495 using element_type = _Tp;
496 using deleter_type = _Dp;
500 template<
typename _Up,
typename _Ep,
502 typename _UP_pointer =
typename _UPtr::pointer,
503 typename _UP_element_type =
typename _UPtr::element_type>
504 using __safe_conversion_up = __and_<
512 template<
typename _Up>
513 using __safe_conversion_raw = __and_<
514 __or_<__or_<is_same<_Up, pointer>,
516 __and_<is_pointer<_Up>,
519 typename remove_pointer<_Up>::type(*)[],
528 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
540 template<
typename _Up,
542 typename = _DeleterConstraint<_Vp>,
544 __safe_conversion_raw<_Up>::value,
bool>::type>
558 template<
typename _Up,
typename _Del = deleter_type,
559 typename = _Require<__safe_conversion_raw<_Up>,
572 template<
typename _Up,
typename _Del = deleter_type,
573 typename = _Require<__safe_conversion_raw<_Up>,
577 _Del&&> __d) noexcept
581 template<
typename _Up,
typename _Del = deleter_type,
582 typename _DelUnref =
typename remove_reference<_Del>::type,
583 typename = _Require<__safe_conversion_raw<_Up>>>
586 _DelUnref&&>) =
delete;
592 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
597 template<
typename _Up,
typename _Ep,
typename = _Require<
598 __safe_conversion_up<_Up, _Ep>,
603 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
609 auto& __ptr = _M_t._M_ptr();
610 if (__ptr !=
nullptr)
631 template<
typename _Up,
typename _Ep>
639 reset(__u.release());
640 get_deleter() = std::forward<_Ep>(__u.get_deleter());
655 typename std::add_lvalue_reference<element_type>::type
658 __glibcxx_assert(
get() != pointer());
665 {
return _M_t._M_ptr(); }
670 {
return _M_t._M_deleter(); }
675 {
return _M_t._M_deleter(); }
678 explicit operator bool() const noexcept
679 {
return get() == pointer() ? false :
true; }
686 {
return _M_t.release(); }
694 template <
typename _Up,
696 __or_<is_same<_Up, pointer>,
697 __and_<is_same<pointer, element_type*>,
700 typename remove_pointer<_Up>::type(*)[],
710 void reset(nullptr_t =
nullptr) noexcept
711 {
reset(pointer()); }
717 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
729 template<
typename _Tp,
typename _Dp>
731 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 733 typename enable_if<__is_swappable<_Dp>::value>::type
741 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 742 template<
typename _Tp,
typename _Dp>
749 template<
typename _Tp,
typename _Dp,
750 typename _Up,
typename _Ep>
751 _GLIBCXX_NODISCARD
inline bool 754 {
return __x.
get() == __y.
get(); }
757 template<
typename _Tp,
typename _Dp>
758 _GLIBCXX_NODISCARD
inline bool 762 #ifndef __cpp_lib_three_way_comparison 764 template<
typename _Tp,
typename _Dp>
765 _GLIBCXX_NODISCARD
inline bool 770 template<
typename _Tp,
typename _Dp,
771 typename _Up,
typename _Ep>
772 _GLIBCXX_NODISCARD
inline bool 775 {
return __x.
get() != __y.
get(); }
778 template<
typename _Tp,
typename _Dp>
779 _GLIBCXX_NODISCARD
inline bool 781 {
return (
bool)__x; }
784 template<
typename _Tp,
typename _Dp>
785 _GLIBCXX_NODISCARD
inline bool 787 {
return (
bool)__x; }
788 #endif // three way comparison 791 template<
typename _Tp,
typename _Dp,
792 typename _Up,
typename _Ep>
793 _GLIBCXX_NODISCARD
inline bool 794 operator<(const unique_ptr<_Tp, _Dp>& __x,
799 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
804 template<
typename _Tp,
typename _Dp>
805 _GLIBCXX_NODISCARD
inline bool 806 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
813 template<
typename _Tp,
typename _Dp>
814 _GLIBCXX_NODISCARD
inline bool 815 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
822 template<
typename _Tp,
typename _Dp,
823 typename _Up,
typename _Ep>
824 _GLIBCXX_NODISCARD
inline bool 825 operator<=(const unique_ptr<_Tp, _Dp>& __x,
827 {
return !(__y < __x); }
830 template<
typename _Tp,
typename _Dp>
831 _GLIBCXX_NODISCARD
inline bool 832 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
833 {
return !(
nullptr < __x); }
836 template<
typename _Tp,
typename _Dp>
837 _GLIBCXX_NODISCARD
inline bool 838 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
839 {
return !(__x <
nullptr); }
842 template<
typename _Tp,
typename _Dp,
843 typename _Up,
typename _Ep>
844 _GLIBCXX_NODISCARD
inline bool 847 {
return (__y < __x); }
850 template<
typename _Tp,
typename _Dp>
851 _GLIBCXX_NODISCARD
inline bool 859 template<
typename _Tp,
typename _Dp>
860 _GLIBCXX_NODISCARD
inline bool 868 template<
typename _Tp,
typename _Dp,
869 typename _Up,
typename _Ep>
870 _GLIBCXX_NODISCARD
inline bool 873 {
return !(__x < __y); }
876 template<
typename _Tp,
typename _Dp>
877 _GLIBCXX_NODISCARD
inline bool 879 {
return !(__x <
nullptr); }
882 template<
typename _Tp,
typename _Dp>
883 _GLIBCXX_NODISCARD
inline bool 885 {
return !(
nullptr < __x); }
887 #ifdef __cpp_lib_three_way_comparison 888 template<
typename _Tp,
typename _Dp,
typename _Up,
typename _Ep>
889 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
890 typename unique_ptr<_Up, _Ep>::pointer>
892 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
893 typename unique_ptr<_Up, _Ep>::pointer>
896 {
return compare_three_way()(__x.
get(), __y.
get()); }
898 template<
typename _Tp,
typename _Dp>
899 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
901 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
902 operator<=>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
904 using pointer =
typename unique_ptr<_Tp, _Dp>::pointer;
905 return compare_three_way()(__x.get(),
static_cast<pointer
>(
nullptr));
911 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
912 bool = __poison_hash<_Ptr>::__enable_hash_call>
913 struct __uniq_ptr_hash
914 #if ! _GLIBCXX_INLINE_VERSION
915 :
private __poison_hash<_Ptr>
919 operator()(
const _Up& __u)
const 920 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
921 {
return hash<_Ptr>()(__u.get()); }
924 template<
typename _Up,
typename _Ptr>
925 struct __uniq_ptr_hash<_Up, _Ptr, false>
926 :
private __poison_hash<_Ptr>
931 template<
typename _Tp,
typename _Dp>
933 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
934 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
937 #if __cplusplus > 201103L 939 #define __cpp_lib_make_unique 201304 943 template<
typename _Tp>
945 {
typedef unique_ptr<_Tp> __single_object; };
947 template<
typename _Tp>
948 struct _MakeUniq<_Tp[]>
949 {
typedef unique_ptr<_Tp[]> __array; };
951 template<
typename _Tp,
size_t _Bound>
952 struct _MakeUniq<_Tp[_Bound]>
953 {
struct __invalid_type { }; };
958 template<
typename _Tp,
typename... _Args>
959 inline typename _MakeUniq<_Tp>::__single_object
964 template<
typename _Tp>
965 inline typename _MakeUniq<_Tp>::__array
970 template<
typename _Tp,
typename... _Args>
971 inline typename _MakeUniq<_Tp>::__invalid_type
972 make_unique(_Args&&...) =
delete;
978 #if __cplusplus >= 201703L 979 namespace __detail::__variant
981 template<
typename>
struct _Never_valueless_alt;
985 template<
typename _Tp,
typename _Del>
992 _GLIBCXX_END_NAMESPACE_VERSION
20.7.1.2 unique_ptr for single objects.
One of the comparison functors.
constexpr default_delete() noexcept=default
Default constructor.
void operator()(_Tp *__ptr) const
Calls delete __ptr
bool operator==(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Equality operator for unique_ptr objects, compares the owned pointers.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
bool operator>(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Relational operator for unique_ptr objects, compares the owned pointers.
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
bool operator>(nullptr_t, const unique_ptr< _Tp, _Dp > &__x)
unique_ptr comparison with nullptr
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.
bool operator>=(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Relational operator for unique_ptr objects, compares the owned pointers.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
pointer release() noexcept
Release ownership of any stored pointer.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
bool operator!=(nullptr_t, const unique_ptr< _Tp, _Dp > &__x) noexcept
unique_ptr comparison with nullptr
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
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 _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
bool operator!=(const unique_ptr< _Tp, _Dp > &__x, const unique_ptr< _Up, _Ep > &__y)
Inequality operator for unique_ptr objects, compares the owned pointers.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
unique_ptr(pointer __p, const deleter_type &__d) noexcept
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
Define a member typedef type to one of two argument types.
Define a member typedef type only if a boolean constant is true.
unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
Primary template of default_delete, used by unique_ptr for single objects.
default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
unique_ptr(pointer __p) noexcept
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
Primary class template hash.
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
pointer release() noexcept
Release ownership of any stored pointer.
enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
pointer get() const noexcept
Return the stored pointer.
void reset(_Up __p) noexcept
Replace the stored pointer.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
ISO C++ entities toplevel namespace is std.
_MakeUniq< _Tp >::__array make_unique(size_t __num)
std::make_unique for arrays of unknown bound
pointer operator->() const noexcept
Return the stored pointer.
default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
bool operator!=(const unique_ptr< _Tp, _Dp > &__x, nullptr_t) noexcept
unique_ptr comparison with nullptr
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
bool operator==(const unique_ptr< _Tp, _Dp > &__x, nullptr_t) noexcept
unique_ptr comparison with nullptr
unique_ptr(_Up __p) noexcept
A simple smart pointer providing strict ownership semantics.
bool operator==(nullptr_t, const unique_ptr< _Tp, _Dp > &__x) noexcept
unique_ptr comparison with nullptr
_MakeUniq< _Tp >::__single_object make_unique(_Args &&... __args)
std::make_unique for single objects
enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
Swap overload for unique_ptr.
unique_ptr(_Up __p, const deleter_type &__d) noexcept
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept