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>>
132 using type =
typename remove_reference<_Ep>::type::pointer;
136 using _DeleterConstraint = enable_if<
137 __and_<__not_<is_pointer<_Dp>>,
138 is_default_constructible<_Dp>>::value>;
140 using pointer =
typename _Ptr<_Tp, _Dp>::type;
142 static_assert( !is_rvalue_reference<_Dp>::value,
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)
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); }
159 swap(__uniq_ptr_impl& __rhs) noexcept
162 swap(this->_M_ptr(), __rhs._M_ptr());
163 swap(this->_M_deleter(), __rhs._M_deleter());
167 tuple<pointer, _Dp> _M_t;
171 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
174 template <
typename _Up>
175 using _DeleterConstraint =
176 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
178 __uniq_ptr_impl<_Tp, _Dp> _M_t;
181 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
182 using element_type = _Tp;
183 using deleter_type = _Dp;
188 template<
typename _Up,
typename _Ep>
189 using __safe_conversion_up = __and_<
191 __not_<is_array<_Up>>
198 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
209 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
222 template<
typename _Del = deleter_type,
223 typename = _Require<is_copy_constructible<_Del>>>
234 template<
typename _Del = deleter_type,
235 typename = _Require<is_move_constructible<_Del>>>
238 _Del&&> __d) noexcept
239 : _M_t(__p, std::move(__d))
242 template<
typename _Del = deleter_type,
243 typename _DelUnref =
typename remove_reference<_Del>::type>
246 _DelUnref&&>) =
delete;
249 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
258 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
266 template<
typename _Up,
typename _Ep,
typename = _Require<
267 __safe_conversion_up<_Up, _Ep>,
272 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
275 #if _GLIBCXX_USE_DEPRECATED 276 #pragma GCC diagnostic push 277 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 279 template<
typename _Up,
typename = _Require<
282 #pragma GCC diagnostic pop 288 static_assert(__is_invocable<deleter_type&, pointer>::value,
289 "unique_ptr's deleter must be invocable with a pointer");
290 auto& __ptr = _M_t._M_ptr();
291 if (__ptr !=
nullptr)
307 reset(__u.release());
308 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
319 template<
typename _Up,
typename _Ep>
321 __safe_conversion_up<_Up, _Ep>,
327 reset(__u.release());
328 get_deleter() = std::forward<_Ep>(__u.get_deleter());
343 typename add_lvalue_reference<element_type>::type
346 __glibcxx_assert(
get() != pointer());
354 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
361 {
return _M_t._M_ptr(); }
366 {
return _M_t._M_deleter(); }
371 {
return _M_t._M_deleter(); }
374 explicit operator bool() const noexcept
375 {
return get() == pointer() ? false :
true; }
384 _M_t._M_ptr() = pointer();
395 reset(pointer __p = pointer()) noexcept
397 static_assert(__is_invocable<deleter_type&, pointer>::value,
398 "unique_ptr's deleter must be invocable with a pointer");
400 swap(_M_t._M_ptr(), __p);
401 if (__p != pointer())
409 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
422 template<
typename _Tp,
typename _Dp>
425 template <
typename _Up>
426 using _DeleterConstraint =
427 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
429 __uniq_ptr_impl<_Tp, _Dp> _M_t;
431 template<
typename _Up>
432 using __remove_cv =
typename remove_cv<_Up>::type;
435 template<
typename _Up>
436 using __is_derived_Tp
437 = __and_< is_base_of<_Tp, _Up>,
438 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
441 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
442 using element_type = _Tp;
443 using deleter_type = _Dp;
447 template<
typename _Up,
typename _Ep,
449 typename _UP_pointer =
typename _UPtr::pointer,
450 typename _UP_element_type =
typename _UPtr::element_type>
451 using __safe_conversion_up = __and_<
459 template<
typename _Up>
460 using __safe_conversion_raw = __and_<
461 __or_<__or_<is_same<_Up, pointer>,
463 __and_<is_pointer<_Up>,
466 typename remove_pointer<_Up>::type(*)[],
475 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
487 template<
typename _Up,
489 typename = _DeleterConstraint<_Vp>,
491 __safe_conversion_raw<_Up>::value,
bool>::type>
505 template<
typename _Up,
typename _Del = deleter_type,
506 typename = _Require<__safe_conversion_raw<_Up>,
519 template<
typename _Up,
typename _Del = deleter_type,
520 typename = _Require<__safe_conversion_raw<_Up>,
524 _Del&&> __d) noexcept
525 : _M_t(std::move(__p), std::move(__d))
528 template<
typename _Up,
typename _Del = deleter_type,
529 typename _DelUnref =
typename remove_reference<_Del>::type,
530 typename = _Require<__safe_conversion_raw<_Up>>>
533 _DelUnref&&>) =
delete;
537 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
540 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
545 template<
typename _Up,
typename _Ep,
typename = _Require<
546 __safe_conversion_up<_Up, _Ep>,
551 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
557 auto& __ptr = _M_t._M_ptr();
558 if (__ptr !=
nullptr)
574 reset(__u.release());
575 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
586 template<
typename _Up,
typename _Ep>
594 reset(__u.release());
595 get_deleter() = std::forward<_Ep>(__u.get_deleter());
610 typename std::add_lvalue_reference<element_type>::type
613 __glibcxx_assert(
get() != pointer());
620 {
return _M_t._M_ptr(); }
625 {
return _M_t._M_deleter(); }
630 {
return _M_t._M_deleter(); }
633 explicit operator bool() const noexcept
634 {
return get() == pointer() ? false :
true; }
643 _M_t._M_ptr() = pointer();
653 template <
typename _Up,
655 __or_<is_same<_Up, pointer>,
656 __and_<is_same<pointer, element_type*>,
659 typename remove_pointer<_Up>::type(*)[],
670 swap(_M_t._M_ptr(), __ptr);
671 if (__ptr !=
nullptr)
675 void reset(nullptr_t =
nullptr) noexcept
684 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
693 template<
typename _Tp,
typename _Dp>
695 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 697 typename enable_if<__is_swappable<_Dp>::value>::type
701 swap(unique_ptr<_Tp, _Dp>& __x,
702 unique_ptr<_Tp, _Dp>& __y) noexcept
705 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 706 template<
typename _Tp,
typename _Dp>
707 typename enable_if<!__is_swappable<_Dp>::value>::type
708 swap(unique_ptr<_Tp, _Dp>&,
709 unique_ptr<_Tp, _Dp>&) =
delete;
712 template<
typename _Tp,
typename _Dp,
713 typename _Up,
typename _Ep>
714 _GLIBCXX_NODISCARD
inline bool 715 operator==(
const unique_ptr<_Tp, _Dp>& __x,
716 const unique_ptr<_Up, _Ep>& __y)
717 {
return __x.get() == __y.get(); }
719 template<
typename _Tp,
typename _Dp>
720 _GLIBCXX_NODISCARD
inline bool 721 operator==(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
724 template<
typename _Tp,
typename _Dp>
725 _GLIBCXX_NODISCARD
inline bool 726 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
729 template<
typename _Tp,
typename _Dp,
730 typename _Up,
typename _Ep>
731 _GLIBCXX_NODISCARD
inline bool 732 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
733 const unique_ptr<_Up, _Ep>& __y)
734 {
return __x.get() != __y.get(); }
736 template<
typename _Tp,
typename _Dp>
737 _GLIBCXX_NODISCARD
inline bool 738 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
739 {
return (
bool)__x; }
741 template<
typename _Tp,
typename _Dp>
742 _GLIBCXX_NODISCARD
inline bool 743 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
744 {
return (
bool)__x; }
746 template<
typename _Tp,
typename _Dp,
747 typename _Up,
typename _Ep>
748 _GLIBCXX_NODISCARD
inline bool 749 operator<(const unique_ptr<_Tp, _Dp>& __x,
750 const unique_ptr<_Up, _Ep>& __y)
754 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
758 template<
typename _Tp,
typename _Dp>
759 _GLIBCXX_NODISCARD
inline bool 760 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
764 template<
typename _Tp,
typename _Dp>
765 _GLIBCXX_NODISCARD
inline bool 766 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
770 template<
typename _Tp,
typename _Dp,
771 typename _Up,
typename _Ep>
772 _GLIBCXX_NODISCARD
inline bool 773 operator<=(const unique_ptr<_Tp, _Dp>& __x,
774 const unique_ptr<_Up, _Ep>& __y)
775 {
return !(__y < __x); }
777 template<
typename _Tp,
typename _Dp>
778 _GLIBCXX_NODISCARD
inline bool 779 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
780 {
return !(
nullptr < __x); }
782 template<
typename _Tp,
typename _Dp>
783 _GLIBCXX_NODISCARD
inline bool 784 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
785 {
return !(__x <
nullptr); }
787 template<
typename _Tp,
typename _Dp,
788 typename _Up,
typename _Ep>
789 _GLIBCXX_NODISCARD
inline bool 790 operator>(
const unique_ptr<_Tp, _Dp>& __x,
791 const unique_ptr<_Up, _Ep>& __y)
792 {
return (__y < __x); }
794 template<
typename _Tp,
typename _Dp>
795 _GLIBCXX_NODISCARD
inline bool 796 operator>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
800 template<
typename _Tp,
typename _Dp>
801 _GLIBCXX_NODISCARD
inline bool 802 operator>(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
806 template<
typename _Tp,
typename _Dp,
807 typename _Up,
typename _Ep>
808 _GLIBCXX_NODISCARD
inline bool 809 operator>=(
const unique_ptr<_Tp, _Dp>& __x,
810 const unique_ptr<_Up, _Ep>& __y)
811 {
return !(__x < __y); }
813 template<
typename _Tp,
typename _Dp>
814 _GLIBCXX_NODISCARD
inline bool 815 operator>=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
816 {
return !(__x <
nullptr); }
818 template<
typename _Tp,
typename _Dp>
819 _GLIBCXX_NODISCARD
inline bool 820 operator>=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
821 {
return !(
nullptr < __x); }
824 template<
typename _Tp,
typename _Dp>
826 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
827 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
837 #if __cplusplus > 201103L 839 #define __cpp_lib_make_unique 201304 841 template<
typename _Tp>
845 template<
typename _Tp>
846 struct _MakeUniq<_Tp[]>
847 {
typedef unique_ptr<_Tp[]> __array; };
849 template<
typename _Tp,
size_t _Bound>
850 struct _MakeUniq<_Tp[_Bound]>
851 {
struct __invalid_type { }; };
854 template<
typename _Tp,
typename... _Args>
855 inline typename _MakeUniq<_Tp>::__single_object
860 template<
typename _Tp>
861 inline typename _MakeUniq<_Tp>::__array
866 template<
typename _Tp,
typename... _Args>
867 inline typename _MakeUniq<_Tp>::__invalid_type
873 #if __cplusplus >= 201703L 874 namespace __detail::__variant
876 template<
typename>
struct _Never_valueless_alt;
880 template<
typename _Tp,
typename _Del>
881 struct _Never_valueless_alt<
std::unique_ptr<_Tp, _Del>>
887 _GLIBCXX_END_NAMESPACE_VERSION
pointer release() noexcept
Release ownership of any stored pointer.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
ISO C++ entities toplevel namespace is std.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
unique_ptr(pointer __p) noexcept
default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
unique_ptr(pointer __p, const deleter_type &__d) noexcept
unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
Define a member typedef type to one of two argument types.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Primary template of default_delete, used by unique_ptr.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
pointer release() noexcept
Release ownership of any stored pointer.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
pointer operator->() const noexcept
Return the stored pointer.
unique_ptr(_Up __p) 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.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
Primary class template hash.
A simple smart pointer providing strict ownership semantics.
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 unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
pointer get() const noexcept
Return the stored pointer.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
void reset(_Up __p) noexcept
Replace the stored pointer.
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
void operator()(_Tp *__ptr) const
Calls delete __ptr.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
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.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del &&> __d) noexcept
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
_MakeUniq< _Tp >::__single_object make_unique(_Args &&... __args)
std::make_unique for single objects
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
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.
One of the comparison functors.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
20.7.1.2 unique_ptr for single objects.
constexpr default_delete() noexcept=default
Default constructor.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
unique_ptr(_Up __p, const deleter_type &__d) noexcept
Define a member typedef type only if a boolean constant is true.