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,
70 typename = _Require<is_convertible<_Up*, _Tp*>>>
78 "can't delete pointer to incomplete type");
79 static_assert(
sizeof(_Tp)>0,
80 "can't delete pointer to incomplete type");
89 template<
typename _Tp>
105 template<
typename _Up,
110 template<
typename _Up>
114 static_assert(
sizeof(_Tp)>0,
115 "can't delete pointer to incomplete type");
123 template <
typename _Tp,
typename _Dp>
124 class __uniq_ptr_impl
126 template <
typename _Up,
typename _Ep,
typename =
void>
132 template <
typename _Up,
typename _Ep>
134 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
136 using type =
typename remove_reference<_Ep>::type::pointer;
140 using _DeleterConstraint = enable_if<
141 __and_<__not_<is_pointer<_Dp>>,
142 is_default_constructible<_Dp>>::value>;
144 using pointer =
typename _Ptr<_Tp, _Dp>::type;
146 static_assert( !is_rvalue_reference<_Dp>::value,
147 "unique_ptr's deleter type must be a function object type"
148 " or an lvalue reference type" );
150 __uniq_ptr_impl() =
default;
151 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
153 template<
typename _Del>
154 __uniq_ptr_impl(pointer __p, _Del&& __d)
157 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
159 { __u._M_ptr() =
nullptr; }
161 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
163 reset(__u.release());
164 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
168 pointer& _M_ptr() {
return std::get<0>(_M_t); }
169 pointer _M_ptr()
const {
return std::get<0>(_M_t); }
170 _Dp& _M_deleter() {
return std::get<1>(_M_t); }
171 const _Dp& _M_deleter()
const {
return std::get<1>(_M_t); }
173 void reset(pointer __p) noexcept
175 const pointer __old_p = _M_ptr();
178 _M_deleter()(__old_p);
181 pointer release() noexcept
183 pointer __p = _M_ptr();
189 swap(__uniq_ptr_impl& __rhs) noexcept
192 swap(this->_M_ptr(), __rhs._M_ptr());
193 swap(this->_M_deleter(), __rhs._M_deleter());
197 tuple<pointer, _Dp> _M_t;
201 template <
typename _Tp,
typename _Dp,
202 bool = is_move_constructible<_Dp>::value,
203 bool = is_move_assignable<_Dp>::value>
204 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
206 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
207 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
208 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
211 template <
typename _Tp,
typename _Dp>
212 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
214 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
215 __uniq_ptr_data(__uniq_ptr_data&&) =
default;
216 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
219 template <
typename _Tp,
typename _Dp>
220 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
222 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
223 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
224 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
default;
227 template <
typename _Tp,
typename _Dp>
228 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
230 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
231 __uniq_ptr_data(__uniq_ptr_data&&) =
delete;
232 __uniq_ptr_data& operator=(__uniq_ptr_data&&) =
delete;
237 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
240 template <
typename _Up>
241 using _DeleterConstraint =
242 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
244 __uniq_ptr_data<_Tp, _Dp> _M_t;
247 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
248 using element_type = _Tp;
249 using deleter_type = _Dp;
254 template<
typename _Up,
typename _Ep>
255 using __safe_conversion_up = __and_<
257 __not_<is_array<_Up>>
264 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
275 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
288 template<
typename _Del = deleter_type,
289 typename = _Require<is_copy_constructible<_Del>>>
300 template<
typename _Del = deleter_type,
301 typename = _Require<is_move_constructible<_Del>>>
304 _Del&&> __d) noexcept
308 template<
typename _Del = deleter_type,
309 typename _DelUnref =
typename remove_reference<_Del>::type>
312 _DelUnref&&>) =
delete;
315 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
331 template<
typename _Up,
typename _Ep,
typename = _Require<
332 __safe_conversion_up<_Up, _Ep>,
337 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
340 #if _GLIBCXX_USE_DEPRECATED
341 #pragma GCC diagnostic push
342 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
344 template<
typename _Up,
typename = _Require<
347 #pragma GCC diagnostic pop
353 static_assert(__is_invocable<deleter_type&, pointer>::value,
354 "unique_ptr's deleter must be invocable with a pointer");
355 auto& __ptr = _M_t._M_ptr();
356 if (__ptr !=
nullptr)
376 template<
typename _Up,
typename _Ep>
378 __safe_conversion_up<_Up, _Ep>,
384 reset(__u.release());
385 get_deleter() = std::forward<_Ep>(__u.get_deleter());
400 typename add_lvalue_reference<element_type>::type
403 __glibcxx_assert(
get() != pointer());
411 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
418 {
return _M_t._M_ptr(); }
423 {
return _M_t._M_deleter(); }
428 {
return _M_t._M_deleter(); }
431 explicit operator bool() const noexcept
432 {
return get() == pointer() ? false :
true; }
439 {
return _M_t.release(); }
448 reset(pointer __p = pointer()) noexcept
450 static_assert(__is_invocable<deleter_type&, pointer>::value,
451 "unique_ptr's deleter must be invocable with a pointer");
459 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
472 template<
typename _Tp,
typename _Dp>
475 template <
typename _Up>
476 using _DeleterConstraint =
477 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
479 __uniq_ptr_data<_Tp, _Dp> _M_t;
481 template<
typename _Up>
482 using __remove_cv =
typename remove_cv<_Up>::type;
485 template<
typename _Up>
486 using __is_derived_Tp
487 = __and_< is_base_of<_Tp, _Up>,
488 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
491 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
492 using element_type = _Tp;
493 using deleter_type = _Dp;
497 template<
typename _Up,
typename _Ep,
499 typename _UP_pointer =
typename _UPtr::pointer,
500 typename _UP_element_type =
typename _UPtr::element_type>
501 using __safe_conversion_up = __and_<
509 template<
typename _Up>
510 using __safe_conversion_raw = __and_<
511 __or_<__or_<is_same<_Up, pointer>,
513 __and_<is_pointer<_Up>,
516 typename remove_pointer<_Up>::type(*)[],
525 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
537 template<
typename _Up,
539 typename = _DeleterConstraint<_Vp>,
541 __safe_conversion_raw<_Up>::value,
bool>::type>
555 template<
typename _Up,
typename _Del = deleter_type,
556 typename = _Require<__safe_conversion_raw<_Up>,
569 template<
typename _Up,
typename _Del = deleter_type,
570 typename = _Require<__safe_conversion_raw<_Up>,
574 _Del&&> __d) noexcept
578 template<
typename _Up,
typename _Del = deleter_type,
579 typename _DelUnref =
typename remove_reference<_Del>::type,
580 typename = _Require<__safe_conversion_raw<_Up>>>
583 _DelUnref&&>) =
delete;
589 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
594 template<
typename _Up,
typename _Ep,
typename = _Require<
595 __safe_conversion_up<_Up, _Ep>,
600 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
606 auto& __ptr = _M_t._M_ptr();
607 if (__ptr !=
nullptr)
628 template<
typename _Up,
typename _Ep>
636 reset(__u.release());
637 get_deleter() = std::forward<_Ep>(__u.get_deleter());
652 typename std::add_lvalue_reference<element_type>::type
655 __glibcxx_assert(
get() != pointer());
662 {
return _M_t._M_ptr(); }
667 {
return _M_t._M_deleter(); }
672 {
return _M_t._M_deleter(); }
675 explicit operator bool() const noexcept
676 {
return get() == pointer() ? false :
true; }
683 {
return _M_t.release(); }
691 template <
typename _Up,
693 __or_<is_same<_Up, pointer>,
694 __and_<is_same<pointer, element_type*>,
697 typename remove_pointer<_Up>::type(*)[],
707 void reset(nullptr_t =
nullptr) noexcept
708 {
reset(pointer()); }
714 static_assert(__is_swappable<_Dp>::value,
"deleter must be swappable");
726 template<
typename _Tp,
typename _Dp>
728 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
730 typename enable_if<__is_swappable<_Dp>::value>::type
738 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
739 template<
typename _Tp,
typename _Dp>
746 template<
typename _Tp,
typename _Dp,
747 typename _Up,
typename _Ep>
748 _GLIBCXX_NODISCARD
inline bool
751 {
return __x.
get() == __y.
get(); }
754 template<
typename _Tp,
typename _Dp>
755 _GLIBCXX_NODISCARD
inline bool
760 template<
typename _Tp,
typename _Dp>
761 _GLIBCXX_NODISCARD
inline bool
766 template<
typename _Tp,
typename _Dp,
767 typename _Up,
typename _Ep>
768 _GLIBCXX_NODISCARD
inline bool
771 {
return __x.
get() != __y.
get(); }
774 template<
typename _Tp,
typename _Dp>
775 _GLIBCXX_NODISCARD
inline bool
777 {
return (
bool)__x; }
780 template<
typename _Tp,
typename _Dp>
781 _GLIBCXX_NODISCARD
inline bool
783 {
return (
bool)__x; }
786 template<
typename _Tp,
typename _Dp,
787 typename _Up,
typename _Ep>
788 _GLIBCXX_NODISCARD
inline bool
794 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
799 template<
typename _Tp,
typename _Dp>
800 _GLIBCXX_NODISCARD
inline bool
808 template<
typename _Tp,
typename _Dp>
809 _GLIBCXX_NODISCARD
inline bool
817 template<
typename _Tp,
typename _Dp,
818 typename _Up,
typename _Ep>
819 _GLIBCXX_NODISCARD
inline bool
822 {
return !(__y < __x); }
825 template<
typename _Tp,
typename _Dp>
826 _GLIBCXX_NODISCARD
inline bool
828 {
return !(
nullptr < __x); }
831 template<
typename _Tp,
typename _Dp>
832 _GLIBCXX_NODISCARD
inline bool
834 {
return !(__x <
nullptr); }
837 template<
typename _Tp,
typename _Dp,
838 typename _Up,
typename _Ep>
839 _GLIBCXX_NODISCARD
inline bool
842 {
return (__y < __x); }
845 template<
typename _Tp,
typename _Dp>
846 _GLIBCXX_NODISCARD
inline bool
854 template<
typename _Tp,
typename _Dp>
855 _GLIBCXX_NODISCARD
inline bool
863 template<
typename _Tp,
typename _Dp,
864 typename _Up,
typename _Ep>
865 _GLIBCXX_NODISCARD
inline bool
868 {
return !(__x < __y); }
871 template<
typename _Tp,
typename _Dp>
872 _GLIBCXX_NODISCARD
inline bool
874 {
return !(__x <
nullptr); }
877 template<
typename _Tp,
typename _Dp>
878 _GLIBCXX_NODISCARD
inline bool
880 {
return !(
nullptr < __x); }
884 template<
typename _Up,
typename _Ptr =
typename _Up::pointer,
885 bool = __poison_hash<_Ptr>::__enable_hash_call>
886 struct __uniq_ptr_hash
887 #if ! _GLIBCXX_INLINE_VERSION
888 :
private __poison_hash<_Ptr>
892 operator()(
const _Up& __u)
const
893 noexcept(noexcept(std::declval<
hash<_Ptr>>()(std::declval<_Ptr>())))
897 template<
typename _Up,
typename _Ptr>
898 struct __uniq_ptr_hash<_Up, _Ptr, false>
899 :
private __poison_hash<_Ptr>
904 template<
typename _Tp,
typename _Dp>
906 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
907 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
910 #if __cplusplus > 201103L
912 #define __cpp_lib_make_unique 201304
916 template<
typename _Tp>
918 {
typedef unique_ptr<_Tp> __single_object; };
920 template<
typename _Tp>
921 struct _MakeUniq<_Tp[]>
922 {
typedef unique_ptr<_Tp[]> __array; };
924 template<
typename _Tp,
size_t _Bound>
925 struct _MakeUniq<_Tp[_Bound]>
926 {
struct __invalid_type { }; };
931 template<
typename _Tp,
typename... _Args>
932 inline typename _MakeUniq<_Tp>::__single_object
937 template<
typename _Tp>
938 inline typename _MakeUniq<_Tp>::__array
943 template<
typename _Tp,
typename... _Args>
944 inline typename _MakeUniq<_Tp>::__invalid_type
945 make_unique(_Args&&...) =
delete;
951 #if __cplusplus >= 201703L
952 namespace __detail::__variant
954 template<
typename>
struct _Never_valueless_alt;
958 template<
typename _Tp,
typename _Del>
965 _GLIBCXX_END_NAMESPACE_VERSION