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 __uniq_ptr_impl() =
default;
143 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
145 template<
typename _Del>
146 __uniq_ptr_impl(pointer __p, _Del&& __d)
147 : _M_t(__p, std::
forward<_Del>(__d)) { }
149 pointer& _M_ptr() {
return std::get<0>(_M_t); }
150 pointer _M_ptr()
const {
return std::get<0>(_M_t); }
151 _Dp& _M_deleter() {
return std::get<1>(_M_t); }
152 const _Dp& _M_deleter()
const {
return std::get<1>(_M_t); }
155 tuple<pointer, _Dp> _M_t;
159 template <
typename _Tp,
typename _Dp = default_delete<_Tp>>
163 using _DeleterConstraint =
164 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
166 __uniq_ptr_impl<_Tp, _Dp> _M_t;
169 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
170 using element_type = _Tp;
171 using deleter_type = _Dp;
175 template<
typename _Up,
typename _Ep>
176 using __safe_conversion_up = __and_<
178 __not_<is_array<_Up>>,
179 __or_<__and_<is_reference<deleter_type>,
181 __and_<__not_<is_reference<deleter_type>>,
189 template <
typename _Up = _Dp,
190 typename = _DeleterConstraint<_Up>>
201 template <
typename _Up = _Dp,
202 typename = _DeleterConstraint<_Up>>
228 typename remove_reference<deleter_type>::type&& __d)
noexcept
229 : _M_t(std::move(__p), std::move(__d))
231 "rvalue deleter bound to reference"); }
234 template <
typename _Up = _Dp,
235 typename = _DeleterConstraint<_Up>>
250 template<
typename _Up,
typename _Ep,
typename = _Require<
251 __safe_conversion_up<_Up, _Ep>,
259 #if _GLIBCXX_USE_DEPRECATED
260 #pragma GCC diagnostic push
261 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
263 template<
typename _Up,
typename = _Require<
266 #pragma GCC diagnostic pop
272 auto& __ptr = _M_t._M_ptr();
273 if (__ptr !=
nullptr)
289 reset(__u.release());
290 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
301 template<
typename _Up,
typename _Ep>
303 __safe_conversion_up<_Up, _Ep>,
309 reset(__u.release());
310 get_deleter() = std::forward<_Ep>(__u.get_deleter());
325 typename add_lvalue_reference<element_type>::type
328 __glibcxx_assert(
get() != pointer());
336 _GLIBCXX_DEBUG_PEDASSERT(
get() != pointer());
343 {
return _M_t._M_ptr(); }
348 {
return _M_t._M_deleter(); }
353 {
return _M_t._M_deleter(); }
356 explicit operator bool() const noexcept
357 {
return get() == pointer() ?
false :
true; }
366 _M_t._M_ptr() = pointer();
377 reset(pointer __p = pointer()) noexcept
380 swap(_M_t._M_ptr(), __p);
381 if (__p != pointer())
390 swap(_M_t, __u._M_t);
402 template<
typename _Tp,
typename _Dp>
405 template <
typename _Up>
406 using _DeleterConstraint =
407 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
409 __uniq_ptr_impl<_Tp, _Dp> _M_t;
411 template<
typename _Up>
412 using __remove_cv =
typename remove_cv<_Up>::type;
415 template<
typename _Up>
416 using __is_derived_Tp
417 = __and_< is_base_of<_Tp, _Up>,
418 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
421 using pointer =
typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
422 using element_type = _Tp;
423 using deleter_type = _Dp;
427 template<
typename _Up,
typename _Ep,
429 typename _Up_element_type =
typename _Up_up::element_type>
430 using __safe_conversion_up = __and_<
436 __and_<__not_<is_reference<deleter_type>>,
441 template<
typename _Up>
442 using __safe_conversion_raw = __and_<
443 __or_<__or_<is_same<_Up, pointer>,
445 __and_<is_pointer<_Up>,
448 typename remove_pointer<_Up>::type(*)[],
457 template <
typename _Up = _Dp,
458 typename = _DeleterConstraint<_Up>>
470 template<
typename _Up,
472 typename = _DeleterConstraint<_Vp>,
474 __safe_conversion_raw<_Up>::value,
bool>::type>
488 template<
typename _Up,
490 __safe_conversion_raw<_Up>::value,
bool>::type>
493 deleter_type,
const deleter_type&>::type __d) noexcept
504 template<
typename _Up,
506 __safe_conversion_raw<_Up>::value,
bool>::type>
508 remove_reference<deleter_type>::type&& __d) noexcept
509 : _M_t(std::move(__p), std::move(__d))
511 "rvalue deleter bound to reference"); }
518 template <
typename _Up = _Dp,
519 typename = _DeleterConstraint<_Up>>
522 template<
typename _Up,
typename _Ep,
523 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
531 auto& __ptr = _M_t._M_ptr();
532 if (__ptr !=
nullptr)
548 reset(__u.release());
549 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
560 template<
typename _Up,
typename _Ep>
568 reset(__u.release());
569 get_deleter() = std::forward<_Ep>(__u.get_deleter());
584 typename std::add_lvalue_reference<element_type>::type
587 __glibcxx_assert(
get() != pointer());
594 {
return _M_t._M_ptr(); }
599 {
return _M_t._M_deleter(); }
604 {
return _M_t._M_deleter(); }
607 explicit operator bool() const noexcept
608 {
return get() == pointer() ?
false :
true; }
617 _M_t._M_ptr() = pointer();
627 template <
typename _Up,
629 __or_<is_same<_Up, pointer>,
630 __and_<is_same<pointer, element_type*>,
633 typename remove_pointer<_Up>::type(*)[],
644 swap(_M_t._M_ptr(), __ptr);
645 if (__ptr !=
nullptr)
649 void reset(nullptr_t =
nullptr) noexcept
659 swap(_M_t, __u._M_t);
667 template<
typename _Tp,
typename _Dp>
669 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
671 typename enable_if<__is_swappable<_Dp>::value>::type
675 swap(unique_ptr<_Tp, _Dp>& __x,
676 unique_ptr<_Tp, _Dp>& __y) noexcept
679 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
680 template<
typename _Tp,
typename _Dp>
681 typename enable_if<!__is_swappable<_Dp>::value>::type
682 swap(unique_ptr<_Tp, _Dp>&,
683 unique_ptr<_Tp, _Dp>&) =
delete;
686 template<
typename _Tp,
typename _Dp,
687 typename _Up,
typename _Ep>
689 operator==(
const unique_ptr<_Tp, _Dp>& __x,
690 const unique_ptr<_Up, _Ep>& __y)
691 {
return __x.get() == __y.get(); }
693 template<
typename _Tp,
typename _Dp>
695 operator==(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
698 template<
typename _Tp,
typename _Dp>
700 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
703 template<
typename _Tp,
typename _Dp,
704 typename _Up,
typename _Ep>
706 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
707 const unique_ptr<_Up, _Ep>& __y)
708 {
return __x.get() != __y.get(); }
710 template<
typename _Tp,
typename _Dp>
712 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
713 {
return (
bool)__x; }
715 template<
typename _Tp,
typename _Dp>
717 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
718 {
return (
bool)__x; }
720 template<
typename _Tp,
typename _Dp,
721 typename _Up,
typename _Ep>
723 operator<(const unique_ptr<_Tp, _Dp>& __x,
724 const unique_ptr<_Up, _Ep>& __y)
728 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
732 template<
typename _Tp,
typename _Dp>
734 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
738 template<
typename _Tp,
typename _Dp>
740 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
744 template<
typename _Tp,
typename _Dp,
745 typename _Up,
typename _Ep>
747 operator<=(const unique_ptr<_Tp, _Dp>& __x,
748 const unique_ptr<_Up, _Ep>& __y)
749 {
return !(__y < __x); }
751 template<
typename _Tp,
typename _Dp>
753 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
754 {
return !(
nullptr < __x); }
756 template<
typename _Tp,
typename _Dp>
758 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
759 {
return !(__x <
nullptr); }
761 template<
typename _Tp,
typename _Dp,
762 typename _Up,
typename _Ep>
764 operator>(
const unique_ptr<_Tp, _Dp>& __x,
765 const unique_ptr<_Up, _Ep>& __y)
766 {
return (__y < __x); }
768 template<
typename _Tp,
typename _Dp>
770 operator>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
774 template<
typename _Tp,
typename _Dp>
776 operator>(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
780 template<
typename _Tp,
typename _Dp,
781 typename _Up,
typename _Ep>
783 operator>=(
const unique_ptr<_Tp, _Dp>& __x,
784 const unique_ptr<_Up, _Ep>& __y)
785 {
return !(__x < __y); }
787 template<
typename _Tp,
typename _Dp>
789 operator>=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
790 {
return !(__x <
nullptr); }
792 template<
typename _Tp,
typename _Dp>
794 operator>=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
795 {
return !(
nullptr < __x); }
798 template<
typename _Tp,
typename _Dp>
800 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
801 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
811 #if __cplusplus > 201103L
813 #define __cpp_lib_make_unique 201304
815 template<
typename _Tp>
819 template<
typename _Tp>
820 struct _MakeUniq<_Tp[]>
821 {
typedef unique_ptr<_Tp[]> __array; };
823 template<
typename _Tp,
size_t _Bound>
824 struct _MakeUniq<_Tp[_Bound]>
825 {
struct __invalid_type { }; };
828 template<
typename _Tp,
typename... _Args>
829 inline typename _MakeUniq<_Tp>::__single_object
834 template<
typename _Tp>
835 inline typename _MakeUniq<_Tp>::__array
840 template<
typename _Tp,
typename... _Args>
841 inline typename _MakeUniq<_Tp>::__invalid_type
847 _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.
_MakeUniq< _Tp >::__single_object make_unique(_Args &&...__args)
std::make_unique for single objects
unique_ptr(_Up __p) noexcept
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
void operator()(_Tp *__ptr) const
Calls delete __ptr.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
unique_ptr(pointer __p) noexcept
unique_ptr(_Up __p, typename remove_reference< deleter_type >::type &&__d) noexcept
enable_if< ::__array_traits< _Tp, _Nm >::_Is_swappable::value >::type noexcept(noexcept(__one.swap(__two)))
swap
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
unique_ptr(pointer __p, typename remove_reference< deleter_type >::type &&__d) noexcept
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.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
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.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
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.
One of the comparison functors.
unique_ptr(pointer __p, typename conditional< is_reference< deleter_type >::value, deleter_type, const deleter_type & >::type __d) noexcept
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.
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.
unique_ptr(_Up __p, typename conditional< is_reference< deleter_type >::value, deleter_type, const deleter_type & >::type __d) noexcept
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.