31 #define _UNIQUE_PTR_H 1 41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 #if _GLIBCXX_USE_DEPRECATED 51 #pragma GCC diagnostic push 52 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 53 template<
typename>
class auto_ptr;
54 #pragma GCC diagnostic pop 58 template<
typename _Tp>
69 template<
typename _Up,
typename =
typename 78 "can't delete pointer to incomplete type");
79 static_assert(
sizeof(_Tp)>0,
80 "can't delete pointer to incomplete type");
88 template<
typename _Tp>
104 template<
typename _Up,
typename =
typename 109 template<
typename _Up>
113 static_assert(
sizeof(_Tp)>0,
114 "can't delete pointer to incomplete type");
119 template <
typename _Tp,
typename _Dp>
120 class __uniq_ptr_impl
122 template <
typename _Up,
typename _Ep,
typename =
void>
128 template <
typename _Up,
typename _Ep>
130 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
137 __and_<__not_<is_pointer<_Dp>>,
140 using pointer =
typename _Ptr<_Tp, _Dp>::type;
143 "unique_ptr's deleter type must be a function object type" 144 " or an lvalue reference type" );
146 __uniq_ptr_impl() =
default;
147 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
149 template<
typename _Del>
150 __uniq_ptr_impl(pointer __p, _Del&& __d)
151 : _M_t(__p, std::forward<_Del>(__d)) { }
153 pointer& _M_ptr() {
return std::get<0>(_M_t); }
154 pointer _M_ptr()
const {
return std::get<0>(_M_t); }
155 _Dp& _M_deleter() {
return std::get<1>(_M_t); }
156 const _Dp& _M_deleter()
const {
return std::get<1>(_M_t); }
163 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
166 template <
typename _Up>
167 using _DeleterConstraint =
168 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
170 __uniq_ptr_impl<_Tp, _Dp> _M_t;
173 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
174 using element_type = _Tp;
175 using deleter_type = _Dp;
180 template<
typename _Up,
typename _Ep>
181 using __safe_conversion_up = __and_<
183 __not_<is_array<_Up>>
190 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
201 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
215 typename = _Require<is_copy_constructible<_Del>>>
227 typename = _Require<is_move_constructible<_Del>>>
230 _Del&&> __d) noexcept
231 : _M_t(__p, std::move(__d))
235 typename _DelUnref =
typename remove_reference<_Del>::type>
238 _DelUnref&&>) =
delete;
241 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
250 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
258 template<
typename _Up,
typename _Ep,
typename = _Require<
259 __safe_conversion_up<_Up, _Ep>,
264 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
267 #if _GLIBCXX_USE_DEPRECATED 268 #pragma GCC diagnostic push 269 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 271 template<
typename _Up,
typename = _Require<
274 #pragma GCC diagnostic pop 280 static_assert(__is_invocable<deleter_type&, pointer>::value,
281 "unique_ptr's deleter must be invocable with a pointer");
282 auto& __ptr = _M_t._M_ptr();
283 if (__ptr !=
nullptr)
284 get_deleter()(std::move(__ptr));
299 reset(__u.release());
300 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
311 template<
typename _Up,
typename _Ep>
313 __safe_conversion_up<_Up, _Ep>,
319 reset(__u.release());
320 get_deleter() = std::forward<_Ep>(__u.get_deleter());
335 typename add_lvalue_reference<element_type>::type
338 __glibcxx_assert(
get() != pointer());
346 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
353 {
return _M_t._M_ptr(); }
358 {
return _M_t._M_deleter(); }
363 {
return _M_t._M_deleter(); }
366 explicit operator bool() const noexcept
367 {
return get() == pointer() ? false :
true; }
376 _M_t._M_ptr() = pointer();
387 reset(pointer __p = pointer()) noexcept
389 static_assert(__is_invocable<deleter_type&, pointer>::value,
390 "unique_ptr's deleter must be invocable with a pointer");
392 swap(_M_t._M_ptr(), __p);
393 if (__p != pointer())
394 get_deleter()(std::move(__p));
402 swap(_M_t, __u._M_t);
414 template<
typename _Tp,
typename _Dp>
417 template <
typename _Up>
418 using _DeleterConstraint =
419 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
421 __uniq_ptr_impl<_Tp, _Dp> _M_t;
423 template<
typename _Up>
424 using __remove_cv =
typename remove_cv<_Up>::type;
427 template<
typename _Up>
428 using __is_derived_Tp
429 = __and_< is_base_of<_Tp, _Up>,
430 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
433 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
434 using element_type = _Tp;
435 using deleter_type = _Dp;
439 template<
typename _Up,
typename _Ep,
441 typename _UP_pointer =
typename _UPtr::pointer,
442 typename _UP_element_type =
typename _UPtr::element_type>
443 using __safe_conversion_up = __and_<
451 template<
typename _Up>
452 using __safe_conversion_raw = __and_<
453 __or_<__or_<is_same<_Up, pointer>,
455 __and_<is_pointer<_Up>,
456 is_same<pointer, element_type*>,
458 typename remove_pointer<_Up>::type(*)[],
467 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
479 template<
typename _Up,
481 typename = _DeleterConstraint<_Vp>,
483 __safe_conversion_raw<_Up>::value,
bool>::type>
497 template<
typename _Up,
typename _Del = deleter_type,
498 typename = _Require<__safe_conversion_raw<_Up>,
511 template<
typename _Up,
typename _Del = deleter_type,
512 typename = _Require<__safe_conversion_raw<_Up>,
516 _Del&&> __d) noexcept
517 : _M_t(std::move(__p), std::move(__d))
520 template<
typename _Up,
typename _Del = deleter_type,
521 typename _DelUnref =
typename remove_reference<_Del>::type,
522 typename = _Require<__safe_conversion_raw<_Up>>>
525 _DelUnref&&>) =
delete;
529 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
532 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
537 template<
typename _Up,
typename _Ep,
typename = _Require<
538 __safe_conversion_up<_Up, _Ep>,
539 typename conditional<is_reference<_Dp>::value,
543 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
549 auto& __ptr = _M_t._M_ptr();
550 if (__ptr !=
nullptr)
551 get_deleter()(__ptr);
566 reset(__u.release());
567 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
578 template<
typename _Up,
typename _Ep>
586 reset(__u.release());
587 get_deleter() = std::forward<_Ep>(__u.get_deleter());
602 typename std::add_lvalue_reference<element_type>::type
605 __glibcxx_assert(
get() != pointer());
612 {
return _M_t._M_ptr(); }
617 {
return _M_t._M_deleter(); }
622 {
return _M_t._M_deleter(); }
625 explicit operator bool() const noexcept
626 {
return get() == pointer() ? false :
true; }
635 _M_t._M_ptr() = pointer();
645 template <
typename _Up,
647 __or_<is_same<_Up, pointer>,
648 __and_<is_same<pointer, element_type*>,
651 typename remove_pointer<_Up>::type(*)[],
662 swap(_M_t._M_ptr(), __ptr);
663 if (__ptr !=
nullptr)
664 get_deleter()(__ptr);
667 void reset(nullptr_t =
nullptr) noexcept
677 swap(_M_t, __u._M_t);
685 template<
typename _Tp,
typename _Dp>
687 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 697 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 698 template<
typename _Tp,
typename _Dp>
704 template<
typename _Tp,
typename _Dp,
705 typename _Up,
typename _Ep>
706 _GLIBCXX_NODISCARD
inline bool 709 {
return __x.
get() == __y.
get(); }
711 template<
typename _Tp,
typename _Dp>
712 _GLIBCXX_NODISCARD
inline bool 716 template<
typename _Tp,
typename _Dp>
717 _GLIBCXX_NODISCARD
inline bool 721 template<
typename _Tp,
typename _Dp,
722 typename _Up,
typename _Ep>
723 _GLIBCXX_NODISCARD
inline bool 726 {
return __x.
get() != __y.
get(); }
728 template<
typename _Tp,
typename _Dp>
729 _GLIBCXX_NODISCARD
inline bool 731 {
return (
bool)__x; }
733 template<
typename _Tp,
typename _Dp>
734 _GLIBCXX_NODISCARD
inline bool 736 {
return (
bool)__x; }
738 template<
typename _Tp,
typename _Dp,
739 typename _Up,
typename _Ep>
740 _GLIBCXX_NODISCARD
inline bool 741 operator<(const unique_ptr<_Tp, _Dp>& __x,
746 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
750 template<
typename _Tp,
typename _Dp>
751 _GLIBCXX_NODISCARD
inline bool 752 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
756 template<
typename _Tp,
typename _Dp>
757 _GLIBCXX_NODISCARD
inline bool 758 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
762 template<
typename _Tp,
typename _Dp,
763 typename _Up,
typename _Ep>
764 _GLIBCXX_NODISCARD
inline bool 765 operator<=(const unique_ptr<_Tp, _Dp>& __x,
767 {
return !(__y < __x); }
769 template<
typename _Tp,
typename _Dp>
770 _GLIBCXX_NODISCARD
inline bool 771 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
772 {
return !(
nullptr < __x); }
774 template<
typename _Tp,
typename _Dp>
775 _GLIBCXX_NODISCARD
inline bool 776 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
777 {
return !(__x <
nullptr); }
779 template<
typename _Tp,
typename _Dp,
780 typename _Up,
typename _Ep>
781 _GLIBCXX_NODISCARD
inline bool 784 {
return (__y < __x); }
786 template<
typename _Tp,
typename _Dp>
787 _GLIBCXX_NODISCARD
inline bool 792 template<
typename _Tp,
typename _Dp>
793 _GLIBCXX_NODISCARD
inline bool 798 template<
typename _Tp,
typename _Dp,
799 typename _Up,
typename _Ep>
800 _GLIBCXX_NODISCARD
inline bool 803 {
return !(__x < __y); }
805 template<
typename _Tp,
typename _Dp>
806 _GLIBCXX_NODISCARD
inline bool 808 {
return !(__x <
nullptr); }
810 template<
typename _Tp,
typename _Dp>
811 _GLIBCXX_NODISCARD
inline bool 813 {
return !(
nullptr < __x); }
816 template<
typename _Tp,
typename _Dp>
818 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
819 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
829 #if __cplusplus > 201103L 831 #define __cpp_lib_make_unique 201304 833 template<
typename _Tp>
837 template<
typename _Tp>
838 struct _MakeUniq<_Tp[]>
841 template<
typename _Tp,
size_t _Bound>
842 struct _MakeUniq<_Tp[_Bound]>
843 {
struct __invalid_type { }; };
846 template<
typename _Tp,
typename... _Args>
852 template<
typename _Tp>
853 inline typename _MakeUniq<_Tp>::__array
858 template<
typename _Tp,
typename... _Args>
859 inline typename _MakeUniq<_Tp>::__invalid_type
865 #if __cplusplus >= 201703L 866 namespace __detail::__variant
868 template<
typename>
struct _Never_valueless_alt;
872 template<
typename _Tp,
typename _Del>
873 struct _Never_valueless_alt<std::
unique_ptr<_Tp, _Del>>
879 _GLIBCXX_END_NAMESPACE_VERSION
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
unique_ptr(_Up __p) noexcept
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
_MakeUniq< _Tp >::__single_object make_unique(_Args &&... __args)
std::make_unique for single objects
Primary template of default_delete, used by unique_ptr.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
pointer operator->() const noexcept
Return the stored pointer.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
void operator()(_Tp *__ptr) const
Calls delete __ptr.
Primary class template hash.
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.
ISO C++ entities toplevel namespace is std.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
unique_ptr(pointer __p) noexcept
default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
Define a member typedef type only if a boolean constant is true.
~unique_ptr() noexcept
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.
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.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
Define a member typedef type to one of two argument types.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
unique_ptr(pointer __p, const deleter_type &__d) noexcept
unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
pointer release() noexcept
Release ownership of any stored pointer.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
unique_ptr(_Up __p, const deleter_type &__d) noexcept
constexpr default_delete() noexcept=default
Default constructor.
One of the comparison functors.
pointer get() const noexcept
Return the stored pointer.
20.7.1.2 unique_ptr for single objects.
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
void reset(_Up __p) noexcept
Replace the stored pointer.
A simple smart pointer providing strict ownership semantics.
pointer release() noexcept
Release ownership of any stored pointer.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr.