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)
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); }
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>>,
184 __or_<__and_<is_reference<deleter_type>,
186 __and_<__not_<is_reference<deleter_type>>,
195 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
206 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
219 template<
typename _Del = deleter_type,
220 typename = _Require<is_copy_constructible<_Del>>>
231 template<
typename _Del = deleter_type,
232 typename = _Require<is_move_constructible<_Del>>>
236 : _M_t(__p, std::move(__d))
239 template<
typename _Del = deleter_type,
240 typename _DelUnref =
typename remove_reference<_Del>::type>
243 _DelUnref&&>) =
delete;
246 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
263 template<
typename _Up,
typename _Ep,
typename = _Require<
264 __safe_conversion_up<_Up, _Ep>,
272 #if _GLIBCXX_USE_DEPRECATED
273 #pragma GCC diagnostic push
274 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
276 template<
typename _Up,
typename = _Require<
279 #pragma GCC diagnostic pop
285 static_assert(__is_invocable<deleter_type&, pointer>::value,
286 "unique_ptr's deleter must be invocable with a pointer");
287 auto& __ptr = _M_t._M_ptr();
288 if (__ptr !=
nullptr)
304 reset(__u.release());
305 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
316 template<
typename _Up,
typename _Ep>
318 __safe_conversion_up<_Up, _Ep>,
324 reset(__u.release());
325 get_deleter() = std::forward<_Ep>(__u.get_deleter());
340 typename add_lvalue_reference<element_type>::type
343 __glibcxx_assert(
get() != pointer());
351 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
358 {
return _M_t._M_ptr(); }
363 {
return _M_t._M_deleter(); }
368 {
return _M_t._M_deleter(); }
371 explicit operator bool() const noexcept
372 {
return get() == pointer() ?
false :
true; }
381 _M_t._M_ptr() = pointer();
392 reset(pointer __p = pointer()) noexcept
394 static_assert(__is_invocable<deleter_type&, pointer>::value,
395 "unique_ptr's deleter must be invocable with a pointer");
397 swap(_M_t._M_ptr(), __p);
398 if (__p != pointer())
407 swap(_M_t, __u._M_t);
419 template<
typename _Tp,
typename _Dp>
422 template <
typename _Up>
423 using _DeleterConstraint =
424 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
426 __uniq_ptr_impl<_Tp, _Dp> _M_t;
428 template<
typename _Up>
429 using __remove_cv =
typename remove_cv<_Up>::type;
432 template<
typename _Up>
433 using __is_derived_Tp
434 = __and_< is_base_of<_Tp, _Up>,
435 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
438 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
439 using element_type = _Tp;
440 using deleter_type = _Dp;
444 template<
typename _Up,
typename _Ep,
446 typename _Up_element_type =
typename _Up_up::element_type>
447 using __safe_conversion_up = __and_<
453 __and_<__not_<is_reference<deleter_type>>,
458 template<
typename _Up>
459 using __safe_conversion_raw = __and_<
460 __or_<__or_<is_same<_Up, pointer>,
462 __and_<is_pointer<_Up>,
465 typename remove_pointer<_Up>::type(*)[],
474 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
486 template<
typename _Up,
488 typename = _DeleterConstraint<_Vp>,
490 __safe_conversion_raw<_Up>::value,
bool>::type>
504 template<
typename _Up,
typename _Del = deleter_type,
505 typename = _Require<__safe_conversion_raw<_Up>,
518 template<
typename _Up,
typename _Del = deleter_type,
519 typename = _Require<__safe_conversion_raw<_Up>,
523 _Del&&> __d) noexcept
524 : _M_t(std::move(__p), std::move(__d))
527 template<
typename _Up,
typename _Del = deleter_type,
528 typename _DelUnref =
typename remove_reference<_Del>::type,
529 typename = _Require<__safe_conversion_raw<_Up>>>
532 _DelUnref&&>) =
delete;
539 template<
typename _Del = _Dp,
typename = _DeleterConstra
int<_Del>>
544 template<
typename _Up,
typename _Ep,
545 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
553 auto& __ptr = _M_t._M_ptr();
554 if (__ptr !=
nullptr)
570 reset(__u.release());
571 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
582 template<
typename _Up,
typename _Ep>
590 reset(__u.release());
591 get_deleter() = std::forward<_Ep>(__u.get_deleter());
606 typename std::add_lvalue_reference<element_type>::type
609 __glibcxx_assert(
get() != pointer());
616 {
return _M_t._M_ptr(); }
621 {
return _M_t._M_deleter(); }
626 {
return _M_t._M_deleter(); }
629 explicit operator bool() const noexcept
630 {
return get() == pointer() ?
false :
true; }
639 _M_t._M_ptr() = pointer();
649 template <
typename _Up,
651 __or_<is_same<_Up, pointer>,
652 __and_<is_same<pointer, element_type*>,
655 typename remove_pointer<_Up>::type(*)[],
666 swap(_M_t._M_ptr(), __ptr);
667 if (__ptr !=
nullptr)
671 void reset(nullptr_t =
nullptr) noexcept
681 swap(_M_t, __u._M_t);
689 template<
typename _Tp,
typename _Dp>
691 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
693 typename enable_if<__is_swappable<_Dp>::value>::type
697 swap(unique_ptr<_Tp, _Dp>& __x,
698 unique_ptr<_Tp, _Dp>& __y) noexcept
701 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
702 template<
typename _Tp,
typename _Dp>
703 typename enable_if<!__is_swappable<_Dp>::value>::type
704 swap(unique_ptr<_Tp, _Dp>&,
705 unique_ptr<_Tp, _Dp>&) =
delete;
708 template<
typename _Tp,
typename _Dp,
709 typename _Up,
typename _Ep>
710 _GLIBCXX_NODISCARD
inline bool
711 operator==(
const unique_ptr<_Tp, _Dp>& __x,
712 const unique_ptr<_Up, _Ep>& __y)
713 {
return __x.get() == __y.get(); }
715 template<
typename _Tp,
typename _Dp>
716 _GLIBCXX_NODISCARD
inline bool
717 operator==(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
720 template<
typename _Tp,
typename _Dp>
721 _GLIBCXX_NODISCARD
inline bool
722 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
725 template<
typename _Tp,
typename _Dp,
726 typename _Up,
typename _Ep>
727 _GLIBCXX_NODISCARD
inline bool
728 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
729 const unique_ptr<_Up, _Ep>& __y)
730 {
return __x.get() != __y.get(); }
732 template<
typename _Tp,
typename _Dp>
733 _GLIBCXX_NODISCARD
inline bool
734 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
735 {
return (
bool)__x; }
737 template<
typename _Tp,
typename _Dp>
738 _GLIBCXX_NODISCARD
inline bool
739 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
740 {
return (
bool)__x; }
742 template<
typename _Tp,
typename _Dp,
743 typename _Up,
typename _Ep>
744 _GLIBCXX_NODISCARD
inline bool
745 operator<(const unique_ptr<_Tp, _Dp>& __x,
746 const unique_ptr<_Up, _Ep>& __y)
750 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
754 template<
typename _Tp,
typename _Dp>
755 _GLIBCXX_NODISCARD
inline bool
756 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
760 template<
typename _Tp,
typename _Dp>
761 _GLIBCXX_NODISCARD
inline bool
762 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
766 template<
typename _Tp,
typename _Dp,
767 typename _Up,
typename _Ep>
768 _GLIBCXX_NODISCARD
inline bool
769 operator<=(const unique_ptr<_Tp, _Dp>& __x,
770 const unique_ptr<_Up, _Ep>& __y)
771 {
return !(__y < __x); }
773 template<
typename _Tp,
typename _Dp>
774 _GLIBCXX_NODISCARD
inline bool
775 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
776 {
return !(
nullptr < __x); }
778 template<
typename _Tp,
typename _Dp>
779 _GLIBCXX_NODISCARD
inline bool
780 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
781 {
return !(__x <
nullptr); }
783 template<
typename _Tp,
typename _Dp,
784 typename _Up,
typename _Ep>
785 _GLIBCXX_NODISCARD
inline bool
786 operator>(
const unique_ptr<_Tp, _Dp>& __x,
787 const unique_ptr<_Up, _Ep>& __y)
788 {
return (__y < __x); }
790 template<
typename _Tp,
typename _Dp>
791 _GLIBCXX_NODISCARD
inline bool
792 operator>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
796 template<
typename _Tp,
typename _Dp>
797 _GLIBCXX_NODISCARD
inline bool
798 operator>(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
802 template<
typename _Tp,
typename _Dp,
803 typename _Up,
typename _Ep>
804 _GLIBCXX_NODISCARD
inline bool
805 operator>=(
const unique_ptr<_Tp, _Dp>& __x,
806 const unique_ptr<_Up, _Ep>& __y)
807 {
return !(__x < __y); }
809 template<
typename _Tp,
typename _Dp>
810 _GLIBCXX_NODISCARD
inline bool
811 operator>=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
812 {
return !(__x <
nullptr); }
814 template<
typename _Tp,
typename _Dp>
815 _GLIBCXX_NODISCARD
inline bool
816 operator>=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
817 {
return !(
nullptr < __x); }
820 template<
typename _Tp,
typename _Dp>
822 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
823 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
833 #if __cplusplus > 201103L
835 #define __cpp_lib_make_unique 201304
837 template<
typename _Tp>
841 template<
typename _Tp>
842 struct _MakeUniq<_Tp[]>
843 {
typedef unique_ptr<_Tp[]> __array; };
845 template<
typename _Tp,
size_t _Bound>
846 struct _MakeUniq<_Tp[_Bound]>
847 {
struct __invalid_type { }; };
850 template<
typename _Tp,
typename... _Args>
851 inline typename _MakeUniq<_Tp>::__single_object
856 template<
typename _Tp>
857 inline typename _MakeUniq<_Tp>::__array
862 template<
typename _Tp,
typename... _Args>
863 inline typename _MakeUniq<_Tp>::__invalid_type
869 #if __cplusplus >= 201703L
870 namespace __detail::__variant
872 template<
typename>
struct _Never_valueless_alt;
876 template<
typename _Tp,
typename _Del>
877 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
883 _GLIBCXX_END_NAMESPACE_VERSION
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
unique_ptr(_Up __p) noexcept
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
void operator()(_Tp *__ptr) const
Calls delete __ptr.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
unique_ptr(pointer __p, const deleter_type &__d) noexcept
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
unique_ptr(pointer __p) noexcept
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
enable_if< ::__array_traits< _Tp, _Nm >::_Is_swappable::value >::type noexcept(noexcept(__one.swap(__two)))
swap
unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
Define a member typedef type only if a boolean constant is true.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
pointer operator->() const noexcept
Return the stored pointer.
enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
pointer release() noexcept
Release ownership of any stored pointer.
pointer get() const noexcept
Return the stored pointer.
A simple smart pointer providing strict ownership semantics.
Primary template of default_delete, used by unique_ptr.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
20.7.1.2 unique_ptr for single objects.
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.
unique_ptr(_Up __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept
One of the comparison functors.
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.
pointer release() noexcept
Release ownership of any stored pointer.
unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept
_MakeUniq< _Tp >::__single_object make_unique(_Args &&...__args)
std::make_unique for single objects
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
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.
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
constexpr default_delete() noexcept=default
Default constructor.
Define a member typedef type to one of two argument types.
void reset(_Up __p) noexcept
Replace the stored pointer.
unique_ptr(_Up __p, const deleter_type &__d) noexcept