31 #define _UNIQUE_PTR_H 1
35 #include <type_traits>
39 namespace std _GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 #if _GLIBCXX_USE_DEPRECATED
49 template<
typename>
class auto_ptr;
53 template<
typename _Tp>
64 template<
typename _Up,
typename =
typename
65 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
72 static_assert(!is_void<_Tp>::value,
73 "can't delete pointer to incomplete type");
74 static_assert(
sizeof(_Tp)>0,
75 "can't delete pointer to incomplete type");
83 template<
typename _Tp>
87 template<
typename _Up>
88 using __remove_cv =
typename remove_cv<_Up>::type;
91 template<
typename _Up>
93 = __and_< is_base_of<_Tp, _Up>,
94 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
109 template<
typename _Up,
typename =
typename
110 enable_if<!__is_derived_Tp<_Up>::value>::type>
117 static_assert(
sizeof(_Tp)>0,
118 "can't delete pointer to incomplete type");
122 template<
typename _Up>
123 typename enable_if<__is_derived_Tp<_Up>::value>::type
128 template <
typename _Tp,
typename _Dp = default_delete<_Tp> >
134 template<
typename _Up>
135 static typename _Up::pointer __test(
typename _Up::pointer*);
137 template<
typename _Up>
138 static _Tp* __test(...);
140 typedef typename remove_reference<_Dp>::type _Del;
143 typedef decltype(__test<_Del>(0)) type;
146 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
150 typedef typename _Pointer::type pointer;
151 typedef _Tp element_type;
152 typedef _Dp deleter_type;
159 { static_assert(!is_pointer<deleter_type>::value,
160 "constructed with null function pointer deleter"); }
170 : _M_t(__p, deleter_type())
171 { static_assert(!is_pointer<deleter_type>::value,
172 "constructed with null function pointer deleter"); }
182 typename conditional<is_reference<deleter_type>::value,
183 deleter_type,
const deleter_type&>::type __d) noexcept
194 typename remove_reference<deleter_type>::type&& __d) noexcept
196 { static_assert(!std::is_reference<deleter_type>::value,
197 "rvalue deleter bound to reference"); }
214 template<
typename _Up,
typename _Ep,
typename = _Require<
215 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
216 __not_<is_array<_Up>>,
217 typename conditional<is_reference<_Dp>::value,
219 is_convertible<_Ep, _Dp>>::type>>
224 #if _GLIBCXX_USE_DEPRECATED
226 template<
typename _Up,
typename = _Require<
227 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
234 auto& __ptr = std::get<0>(_M_t);
235 if (__ptr !=
nullptr)
251 reset(__u.release());
252 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
263 template<
typename _Up,
typename _Ep>
264 typename enable_if< __and_<
265 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
266 __not_<is_array<_Up>>
271 reset(__u.release());
272 get_deleter() = std::forward<_Ep>(__u.get_deleter());
287 typename add_lvalue_reference<element_type>::type
290 _GLIBCXX_DEBUG_ASSERT(
get() != pointer());
298 _GLIBCXX_DEBUG_ASSERT(
get() != pointer());
305 {
return std::get<0>(_M_t); }
310 {
return std::get<1>(_M_t); }
315 {
return std::get<1>(_M_t); }
318 explicit operator bool() const noexcept
319 {
return get() == pointer() ?
false :
true; }
328 std::get<0>(_M_t) = pointer();
339 reset(pointer __p = pointer()) noexcept
342 swap(std::get<0>(_M_t), __p);
343 if (__p != pointer())
352 swap(_M_t, __u._M_t);
364 template<
typename _Tp,
typename _Dp>
370 template<
typename _Up>
371 static typename _Up::pointer __test(
typename _Up::pointer*);
373 template<
typename _Up>
374 static _Tp* __test(...);
376 typedef typename remove_reference<_Dp>::type _Del;
379 typedef decltype(__test<_Del>(0)) type;
382 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
385 template<
typename _Up>
386 using __remove_cv =
typename remove_cv<_Up>::type;
389 template<
typename _Up>
390 using __is_derived_Tp
391 = __and_< is_base_of<_Tp, _Up>,
392 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
394 template<
typename _Up,
typename _Ep,
395 typename _Tp_pointer =
typename _Pointer::type,
396 typename _Up_pointer =
typename unique_ptr<_Up, _Ep>::pointer>
397 using __safe_conversion = __and_<
398 is_convertible<_Up_pointer, _Tp_pointer>,
400 __or_<__not_<is_pointer<_Up_pointer>>,
401 __not_<is_pointer<_Tp_pointer>>,
402 __not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
407 typedef typename _Pointer::type pointer;
408 typedef _Tp element_type;
409 typedef _Dp deleter_type;
416 { static_assert(!std::is_pointer<deleter_type>::value,
417 "constructed with null function pointer deleter"); }
427 : _M_t(__p, deleter_type())
428 { static_assert(!is_pointer<deleter_type>::value,
429 "constructed with null function pointer deleter"); }
432 template<
typename _Up,
typename = _Require<is_po
inter<po
inter>,
433 is_convertible<_Up*, po
inter>, __is_derived_Tp<_Up>>>
445 typename conditional<is_reference<deleter_type>::value,
446 deleter_type,
const deleter_type&>::type __d) noexcept
457 remove_reference<deleter_type>::type&& __d) noexcept
459 { static_assert(!is_reference<deleter_type>::value,
460 "rvalue deleter bound to reference"); }
469 template<
typename _Up,
typename _Ep,
470 typename = _Require<__safe_conversion<_Up, _Ep>,
471 typename conditional<is_reference<_Dp>::value,
473 is_convertible<_Ep, _Dp>>::type
482 auto& __ptr = std::get<0>(_M_t);
483 if (__ptr !=
nullptr)
499 reset(__u.release());
500 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
511 template<
typename _Up,
typename _Ep>
513 enable_if<__safe_conversion<_Up, _Ep>::value,
unique_ptr&>::type
516 reset(__u.release());
517 get_deleter() = std::forward<_Ep>(__u.get_deleter());
532 typename std::add_lvalue_reference<element_type>::type
535 _GLIBCXX_DEBUG_ASSERT(
get() != pointer());
542 {
return std::get<0>(_M_t); }
547 {
return std::get<1>(_M_t); }
552 {
return std::get<1>(_M_t); }
555 explicit operator bool() const noexcept
556 {
return get() == pointer() ?
false :
true; }
565 std::get<0>(_M_t) = pointer();
576 reset(pointer __p = pointer()) noexcept
579 swap(std::get<0>(_M_t), __p);
585 template<
typename _Up,
typename = _Require<is_po
inter<po
inter>,
586 is_convertible<_Up*, po
inter>, __is_derived_Tp<_Up>>>
587 void reset(_Up*) =
delete;
594 swap(_M_t, __u._M_t);
602 template<
typename _Up,
typename = _Require<is_po
inter<po
inter>,
603 is_convertible<_Up*, po
inter>, __is_derived_Tp<_Up>>>
605 conditional<is_reference<deleter_type>::value,
606 deleter_type,
const deleter_type&>::type) =
delete;
609 template<
typename _Up,
typename = _Require<is_po
inter<po
inter>,
610 is_convertible<_Up*, po
inter>, __is_derived_Tp<_Up>>>
612 remove_reference<deleter_type>::type&&) =
delete;
615 template<
typename _Tp,
typename _Dp>
617 swap(unique_ptr<_Tp, _Dp>& __x,
618 unique_ptr<_Tp, _Dp>& __y) noexcept
621 template<
typename _Tp,
typename _Dp,
622 typename _Up,
typename _Ep>
624 operator==(
const unique_ptr<_Tp, _Dp>& __x,
625 const unique_ptr<_Up, _Ep>& __y)
626 {
return __x.get() == __y.get(); }
628 template<
typename _Tp,
typename _Dp>
630 operator==(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
633 template<
typename _Tp,
typename _Dp>
635 operator==(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
638 template<
typename _Tp,
typename _Dp,
639 typename _Up,
typename _Ep>
641 operator!=(
const unique_ptr<_Tp, _Dp>& __x,
642 const unique_ptr<_Up, _Ep>& __y)
643 {
return __x.get() != __y.get(); }
645 template<
typename _Tp,
typename _Dp>
647 operator!=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
648 {
return (
bool)__x; }
650 template<
typename _Tp,
typename _Dp>
652 operator!=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x) noexcept
653 {
return (
bool)__x; }
655 template<
typename _Tp,
typename _Dp,
656 typename _Up,
typename _Ep>
658 operator<(const unique_ptr<_Tp, _Dp>& __x,
659 const unique_ptr<_Up, _Ep>& __y)
662 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
663 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
667 template<
typename _Tp,
typename _Dp>
669 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
673 template<
typename _Tp,
typename _Dp>
675 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
679 template<
typename _Tp,
typename _Dp,
680 typename _Up,
typename _Ep>
682 operator<=(const unique_ptr<_Tp, _Dp>& __x,
683 const unique_ptr<_Up, _Ep>& __y)
684 {
return !(__y < __x); }
686 template<
typename _Tp,
typename _Dp>
688 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
689 {
return !(
nullptr < __x); }
691 template<
typename _Tp,
typename _Dp>
693 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
694 {
return !(__x <
nullptr); }
696 template<
typename _Tp,
typename _Dp,
697 typename _Up,
typename _Ep>
699 operator>(
const unique_ptr<_Tp, _Dp>& __x,
700 const unique_ptr<_Up, _Ep>& __y)
701 {
return (__y < __x); }
703 template<
typename _Tp,
typename _Dp>
705 operator>(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
709 template<
typename _Tp,
typename _Dp>
711 operator>(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
715 template<
typename _Tp,
typename _Dp,
716 typename _Up,
typename _Ep>
719 const unique_ptr<_Up, _Ep>& __y)
720 {
return !(__x < __y); }
722 template<
typename _Tp,
typename _Dp>
724 operator>=(
const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
725 {
return !(__x <
nullptr); }
727 template<
typename _Tp,
typename _Dp>
729 operator>=(nullptr_t,
const unique_ptr<_Tp, _Dp>& __x)
730 {
return !(
nullptr < __x); }
733 template<
typename _Tp,
typename _Dp>
735 :
public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
745 #if __cplusplus > 201103L
747 #define __cpp_lib_make_unique 201304
749 template<
typename _Tp>
753 template<
typename _Tp>
754 struct _MakeUniq<_Tp[]>
755 {
typedef unique_ptr<_Tp[]> __array; };
757 template<
typename _Tp,
size_t _Bound>
758 struct _MakeUniq<_Tp[_Bound]>
759 {
struct __invalid_type { }; };
762 template<
typename _Tp,
typename... _Args>
763 inline typename _MakeUniq<_Tp>::__single_object
764 make_unique(_Args&&... __args)
765 {
return unique_ptr<_Tp>(
new _Tp(std::forward<_Args>(__args)...)); }
768 template<
typename _Tp>
769 inline typename _MakeUniq<_Tp>::__array
770 make_unique(
size_t __num)
771 {
return unique_ptr<_Tp>(
new typename remove_extent<_Tp>::type[__num]()); }
774 template<
typename _Tp,
typename... _Args>
775 inline typename _MakeUniq<_Tp>::__invalid_type
776 make_unique(_Args&&...) =
delete;
781 _GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
unique_ptr(pointer __p, typename remove_reference< deleter_type >::type &&__d) noexcept
add_lvalue_reference< element_type >::type operator*() const
Dereference the stored pointer.
Primary template of default_delete, used by unique_ptr.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
A simple smart pointer providing strict ownership semantics.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
unique_ptr & operator=(unique_ptr &&__u) noexcept
Move assignment operator.
unique_ptr(pointer __p) noexcept
default_delete(const default_delete< _Up > &) noexcept
Converting constructor.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
constexpr default_delete() noexcept=default
Default constructor.
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
void operator()(_Tp *__ptr) const
Calls delete __ptr.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
ISO C++ entities toplevel namespace is std.
pointer release() noexcept
Release ownership of any stored pointer.
~unique_ptr()
Destructor, invokes the deleter if the stored pointer is not null.
unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
void operator()(_Tp *__ptr) const
Calls delete[] __ptr.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
enable_if< __and_< is_convertible< typename unique_ptr< _Up, _Ep >::pointer, pointer >, __not_< is_array< _Up > > >::value, unique_ptr & >::type operator=(unique_ptr< _Up, _Ep > &&__u) noexcept
Assignment from another type.
const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
pointer operator->() const noexcept
Return the stored pointer.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
bool operator>=(const basic_string< _CharT, _Traits, _Alloc > &__lhs, const basic_string< _CharT, _Traits, _Alloc > &__rhs)
Test if string doesn't precede string.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
enable_if< __safe_conversion< _Up, _Ep >::value, unique_ptr & >::type operator=(unique_ptr< _Up, _Ep > &&__u) noexcept
Assignment from another type.
pointer get() const noexcept
Return the stored pointer.
unique_ptr(pointer __p) noexcept
unique_ptr(pointer __p, typename conditional< is_reference< deleter_type >::value, deleter_type, const deleter_type & >::type __d) noexcept
Primary class template hash.
bool operator>(const basic_string< _CharT, _Traits, _Alloc > &__lhs, const basic_string< _CharT, _Traits, _Alloc > &__rhs)
Test if string follows string.
pointer release() noexcept
Release ownership of any stored pointer.
unique_ptr(pointer __p, typename conditional< is_reference< deleter_type >::value, deleter_type, const deleter_type & >::type __d) noexcept
default_delete(const default_delete< _Up[]> &) noexcept
Converting constructor.
void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
unique_ptr(unique_ptr &&__u) noexcept
Move constructor.
unique_ptr(pointer __p, typename remove_reference< deleter_type >::type &&__d) noexcept
void swap(_Tp &, _Tp &) noexcept(__and_< is_nothrow_move_constructible< _Tp >, is_nothrow_move_assignable< _Tp >>::value)
Swaps two values.
One of the comparison functors.
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
20.7.1.2 unique_ptr for single objects.
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.