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 tuple<pointer, _Dp> _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>>
214 template<
typename _Del = deleter_type,
215 typename = _Require<is_copy_constructible<_Del>>>
226 template<
typename _Del = deleter_type,
227 typename = _Require<is_move_constructible<_Del>>>
230 _Del&&> __d) noexcept
231 : _M_t(__p, std::move(__d))
234 template<
typename _Del = deleter_type,
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)
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())
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>,
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>,
543 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
549 auto& __ptr = _M_t._M_ptr();
550 if (__ptr !=
nullptr)
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)
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
689 typename enable_if<__is_swappable<_Dp>::value>::type
693 swap(unique_ptr<_Tp, _Dp>& __x,
694 unique_ptr<_Tp, _Dp>& __y) noexcept
697 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
698 template<
typename _Tp,
typename _Dp>
699 typename enable_if<!__is_swappable<_Dp>::value>::type
700 swap(unique_ptr<_Tp, _Dp>&,
701 unique_ptr<_Tp, _Dp>&) =
delete;
704 template<
typename _Tp,
typename _Dp,
705 typename _Up,
typename _Ep>
706 _GLIBCXX_NODISCARD
inline bool
707 operator==(
const unique_ptr<_Tp, _Dp>& __x,
708 const unique_ptr<_Up, _Ep>& __y)
709 {
return __x.get() == __y.get(); }
711 template<
typename _Tp,
typename _Dp>
712 _GLIBCXX_NODISCARD
inline bool
713 operator==(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
716 template<
typename _Tp,
typename _Dp>
717 _GLIBCXX_NODISCARD
inline bool
718 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
721 template<
typename _Tp,
typename _Dp,
722 typename _Up,
typename _Ep>
723 _GLIBCXX_NODISCARD
inline bool
724 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
725 const unique_ptr<_Up, _Ep>& __y)
726 {
return __x.get() != __y.get(); }
728 template<
typename _Tp,
typename _Dp>
729 _GLIBCXX_NODISCARD
inline bool
730 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
731 {
return (
bool)__x; }
733 template<
typename _Tp,
typename _Dp>
734 _GLIBCXX_NODISCARD
inline bool
735 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
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,
742 const unique_ptr<_Up, _Ep>& __y)
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,
766 const unique_ptr<_Up, _Ep>& __y)
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
782 operator>(
const unique_ptr<_Tp, _Dp>& __x,
783 const unique_ptr<_Up, _Ep>& __y)
784 {
return (__y < __x); }
786 template<
typename _Tp,
typename _Dp>
787 _GLIBCXX_NODISCARD
inline bool
788 operator>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
792 template<
typename _Tp,
typename _Dp>
793 _GLIBCXX_NODISCARD
inline bool
794 operator>(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
798 template<
typename _Tp,
typename _Dp,
799 typename _Up,
typename _Ep>
800 _GLIBCXX_NODISCARD
inline bool
801 operator>=(
const unique_ptr<_Tp, _Dp>& __x,
802 const unique_ptr<_Up, _Ep>& __y)
803 {
return !(__x < __y); }
805 template<
typename _Tp,
typename _Dp>
806 _GLIBCXX_NODISCARD
inline bool
807 operator>=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
808 {
return !(__x <
nullptr); }
810 template<
typename _Tp,
typename _Dp>
811 _GLIBCXX_NODISCARD
inline bool
812 operator>=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
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[]>
839 {
typedef unique_ptr<_Tp[]> __array; };
841 template<
typename _Tp,
size_t _Bound>
842 struct _MakeUniq<_Tp[_Bound]>
843 {
struct __invalid_type { }; };
846 template<
typename _Tp,
typename... _Args>
847 inline typename _MakeUniq<_Tp>::__single_object
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