1#ifndef NEFORCE_CORE_MEMORY_UNIQUE_PTR_HPP__
2#define NEFORCE_CORE_MEMORY_UNIQUE_PTR_HPP__
16NEFORCE_BEGIN_NAMESPACE__
35template <
typename T,
typename Deleter>
36class __unique_ptr_impl {
38 template <
typename U,
typename E,
typename =
void>
43 template <
typename U,
typename E>
45 using type =
typename remove_reference<E>::type::pointer;
49 using DeleterConstraint = enable_if<is_default_constructible<Deleter>::value>;
50 using pointer =
typename inner_ptr<T, Deleter>::type;
53 compressed_pair<Deleter, pointer> ptr_pair_{default_construct_tag{},
nullptr};
56 "deleter type of unique_ptr must be a function object type or an lvalue reference type");
59 __unique_ptr_impl() =
default;
61 NEFORCE_CONSTEXPR20 __unique_ptr_impl(pointer ptr) :
62 ptr_pair_(default_construct_tag{}, ptr) {}
64 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
65 NEFORCE_CONSTEXPR20 __unique_ptr_impl(pointer ptr, Del&& deleter) :
66 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE
forward<Del>(deleter), ptr) {}
68 NEFORCE_CONSTEXPR20 __unique_ptr_impl(__unique_ptr_impl&& other) noexcept :
69 ptr_pair_(_NEFORCE
move(other.ptr_pair_)) {
70 other.get_ptr() =
nullptr;
73 NEFORCE_CONSTEXPR20 __unique_ptr_impl& operator=(__unique_ptr_impl&& other)
noexcept {
74 this->reset(other.release());
78 NEFORCE_CONSTEXPR20 pointer& get_ptr() noexcept {
return ptr_pair_.
value; }
80 NEFORCE_CONSTEXPR20 pointer get_ptr() const noexcept {
return ptr_pair_.
value; }
82 NEFORCE_CONSTEXPR20 Deleter& get_deleter() &
noexcept {
return ptr_pair_.
get_base(); }
84 NEFORCE_CONSTEXPR20
const Deleter& get_deleter() const& noexcept {
return ptr_pair_.
get_base(); }
86 NEFORCE_CONSTEXPR20 Deleter&& get_deleter() &&
noexcept {
return _NEFORCE
move(ptr_pair_).get_base(); }
88 NEFORCE_CONSTEXPR20
const Deleter&& get_deleter() const&& noexcept {
return _NEFORCE
move(ptr_pair_).get_base(); }
90 NEFORCE_CONSTEXPR20
void reset(pointer ptr)
noexcept {
91 const pointer old = get_ptr();
98 NEFORCE_CONSTEXPR20 pointer
release() noexcept {
99 pointer p = get_ptr();
104 NEFORCE_CONSTEXPR20
void swap(__unique_ptr_impl& other)
noexcept { _NEFORCE
swap(ptr_pair_, other.ptr_pair_); }
117template <typename T, typename Deleter, bool MoveConstructible = is_move_constructible<Deleter>::value,
119struct __unique_ptr_data : __unique_ptr_impl<T, Deleter> {
120 using base_type = __unique_ptr_impl<T, Deleter>;
121 using pointer =
typename base_type::pointer;
123 __unique_ptr_data() =
default;
125 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
128 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
129 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& deleter) :
130 base_type(ptr, _NEFORCE
forward<Del>(deleter)) {}
132 __unique_ptr_data(__unique_ptr_data&&) =
default;
133 __unique_ptr_data& operator=(__unique_ptr_data&&) =
default;
137template <
typename T,
typename Deleter>
138struct __unique_ptr_data<T, Deleter, true, false> : __unique_ptr_impl<T, Deleter> {
139 using base_type = __unique_ptr_impl<T, Deleter>;
140 using pointer =
typename base_type::pointer;
142 __unique_ptr_data() =
default;
144 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
147 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
148 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& deleter) :
149 base_type(ptr, _NEFORCE
forward<Del>(deleter)) {}
151 __unique_ptr_data(__unique_ptr_data&&) =
default;
152 __unique_ptr_data& operator=(__unique_ptr_data&&) =
delete;
156template <
typename T,
typename Deleter>
157struct __unique_ptr_data<T, Deleter, false, true> : __unique_ptr_impl<T, Deleter> {
158 using base_type = __unique_ptr_impl<T, Deleter>;
159 using pointer =
typename base_type::pointer;
161 __unique_ptr_data() =
default;
163 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
166 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
167 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& deleter) :
168 base_type(ptr, _NEFORCE
forward<Del>(deleter)) {}
170 __unique_ptr_data(__unique_ptr_data&&) =
delete;
171 __unique_ptr_data& operator=(__unique_ptr_data&&) =
default;
175template <
typename T,
typename Deleter>
176struct __unique_ptr_data<T, Deleter, false, false> : __unique_ptr_impl<T, Deleter> {
177 using base_type = __unique_ptr_impl<T, Deleter>;
178 using pointer =
typename base_type::pointer;
180 __unique_ptr_data() =
default;
182 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
185 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
186 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& deleter) :
187 base_type(ptr, _NEFORCE
forward<Del>(deleter)) {}
189 __unique_ptr_data(__unique_ptr_data&&) =
delete;
190 __unique_ptr_data& operator=(__unique_ptr_data&&) =
delete;
205template <
typename T,
typename Deleter = default_deleter<T>>
208 template <
typename U>
209 using DeleterConstraint =
typename inner::__unique_ptr_impl<T, U>::DeleterConstraint::type;
211 inner::__unique_ptr_data<T, Deleter> data_{};
214 using pointer =
typename inner::__unique_ptr_impl<T, Deleter>::pointer;
219 template <
typename U,
typename E>
228 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
236 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
245 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
257 template <typename U, typename E,
269 auto& ptr = data_.get_ptr();
270 if (ptr !=
nullptr) {
285 template <typename U, typename E,
288 reset(other.release());
320 NEFORCE_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
339 return _NEFORCE
move(data_).get_deleter();
346 NEFORCE_CONSTEXPR20
explicit operator bool() const noexcept {
return get() !=
pointer(); }
358 "deleter of unique_ptr must be invocable with a pointer");
359 data_.reset(_NEFORCE
move(ptr));
368 data_.swap(other.data_);
380template <
typename T,
typename Deleter>
382 template <
typename U>
383 using DeleterConstraint =
typename inner::__unique_ptr_impl<T, U>::DeleterConstraint::type;
385 inner::__unique_ptr_data<T, Deleter> data_{};
388 using pointer =
typename inner::__unique_ptr_impl<T, Deleter>::pointer;
393 template <
typename U,
typename E,
typename UP = unique_ptr<U, E>,
typename UP_po
inter =
typename UP::po
inter,
394 typename UP_element_type =
typename UP::element_type>
395 using safe_conversion =
399 template <
typename U>
400 using safe_conversion_raw =
412 template <
typename U,
typename Del = Deleter,
typename = DeleterConstra
int<Del>,
413 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
427 data_(ptr, deleter) {}
439 data_(_NEFORCE
move(ptr), _NEFORCE
move(deleter)) {}
444 template <
typename U,
typename Del = deleter_type,
typename DelMoveRef = remove_reference_t<Del>,
445 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
454 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
463 template <
typename U,
typename E,
469 data_(other.release(), _NEFORCE
forward<E>(other.get_deleter())) {}
475 auto& ptr = data_.get_ptr();
476 if (ptr !=
nullptr) {
491 template <
typename U,
typename E,
514 NEFORCE_DEBUG_VERIFY(
get() !=
pointer(),
"_NEFORCE add_lvalue_reference_t<element_type> failed");
521 NEFORCE_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
537 NEFORCE_CONSTEXPR20
explicit operator bool() const noexcept {
return get() !=
pointer(); }
549 template <
typename U,
555 NEFORCE_CONSTEXPR20
void reset(U ptr)
noexcept {
556 data_.reset(_NEFORCE
move(ptr));
568 NEFORCE_CONSTEXPR20
void swap(
unique_ptr& other)
noexcept { data_.swap(other.data_); }
581template <typename T, typename Deleter, enable_if_t<is_swappable<Deleter>::value &&
is_swappable<T>::value,
int> = 0>
596template <
typename T,
typename D,
typename U,
typename E>
598 return lhs.
get() == rhs.
get();
608template <
typename T,
typename D>
620template <
typename T,
typename D>
635template <
typename T,
typename D,
typename U,
typename E>
637 return lhs.
get() != rhs.
get();
647template <
typename T,
typename D>
649 return static_cast<bool>(lhs);
659template <
typename T,
typename D>
661 return static_cast<bool>(rhs);
674template <
typename T,
typename D,
typename U,
typename E>
687template <
typename T,
typename D>
699template <
typename T,
typename D>
714template <
typename T,
typename D,
typename U,
typename E>
716 return rhs.
get() < lhs.
get();
726template <
typename T,
typename D>
738template <
typename T,
typename D>
753template <
typename T,
typename D,
typename U,
typename E>
765template <
typename T,
typename D>
767 return !(lhs >
nullptr);
777template <
typename T,
typename D>
779 return !(
nullptr > rhs);
792template <
typename T,
typename D,
typename U,
typename E>
804template <
typename T,
typename D>
806 return !(lhs <
nullptr);
816template <
typename T,
typename D>
818 return !(
nullptr < rhs);
830template <
typename T,
typename U,
typename Deleter>
841template <
typename T,
typename U,
typename Deleter>
852template <
typename T,
typename U,
typename Deleter>
863template <
typename T,
typename U,
typename Deleter>
877template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
893template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
909template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
925template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
927 T* tmp =
dynamic_cast<T*
>(ptr.get());
928 if (tmp !=
nullptr) {
929 (void) ptr.release();
930 DeleterU&& deleter = _NEFORCE
move(ptr).get_deleter();
931 return {tmp, _NEFORCE
move(deleter).template rebind<T>()};
934 return {
nullptr, _NEFORCE
move(deleter).template rebind<T>()};
949template <
typename T,
typename Deleter>
983template <typename T, enable_if_t<is_unbounded_array<T>::value,
int> = 0>
998NEFORCE_END_NAMESPACE__
unique_ptr(unique_ptr &&)=default
移动构造函数
constexpr pointer get() const noexcept
获取原始指针
typename inner::__unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
unique_ptr & operator=(unique_ptr &&)=default
移动赋值运算符
unique_ptr(U, enable_if_t< is_lvalue_reference< Del >::value, DelMoveRef && >)=delete
禁止从右值引用删除器构造
constexpr void reset(nullptr_t=nullptr) noexcept
重置为空指针
constexpr unique_ptr(U ptr, enable_if_t<!is_lvalue_reference< Del >::value, Del && > deleter) noexcept
从指针和移动删除器构造
constexpr void reset(U ptr) noexcept
重置管理的指针
constexpr pointer release() noexcept
释放所有权
constexpr const deleter_type & get_deleter() const noexcept
获取删除器常量引用
constexpr deleter_type & get_deleter() noexcept
获取删除器引用
constexpr unique_ptr(U ptr) noexcept
从指针构造
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
constexpr unique_ptr(U ptr, const deleter_type &deleter) noexcept
从指针和复制删除器构造
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
constexpr unique_ptr & operator=(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr移动赋值
Deleter deleter_type
删除器类型
constexpr unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
constexpr unique_ptr(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr转换构造
constexpr void swap(unique_ptr &other) noexcept
交换两个unique_ptr
constexpr ~unique_ptr()
析构函数
unique_ptr(const unique_ptr &)=delete
禁止复制构造
constexpr add_lvalue_reference_t< element_type > operator[](size_t idx) const
数组下标运算符
~unique_ptr() noexcept
析构函数
unique_ptr(const unique_ptr &)=delete
禁止复制构造
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
constexpr unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
constexpr const deleter_type && get_deleter() const &&noexcept
获取删除器常量引用
constexpr pointer operator->() const noexcept
成员访问运算符
constexpr unique_ptr(pointer ptr) noexcept
从指针构造
constexpr const deleter_type & get_deleter() const &noexcept
获取删除器常量引用
constexpr pointer release() noexcept
constexpr deleter_type && get_deleter() &&noexcept
获取删除器引用
constexpr pointer get() const noexcept
获取原始指针
Deleter deleter_type
删除器类型
unique_ptr & operator=(unique_ptr &&) noexcept=default
移动赋值运算符
constexpr void reset(pointer ptr=pointer()) noexcept
重置管理的指针
constexpr unique_ptr(unique_ptr &&) noexcept=default
移动构造函数
constexpr deleter_type & get_deleter() &noexcept
constexpr void swap(unique_ptr &other) noexcept
交换两个unique_ptr
typename inner::__unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
constexpr unique_ptr(pointer ptr, Del &&deleter) noexcept
从指针和复制删除器复制构造
constexpr add_lvalue_reference_t< element_type > operator*() const noexcept(noexcept(*_NEFORCE declval< pointer >()))
解引用运算符
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
decltype(nullptr) nullptr_t
空指针类型
@ release
释放操作,确保前面的读写不会被重排到后面
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
typename remove_extent< T >::type remove_extent_t
remove_extent的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
typename common_type< Types... >::type common_type_t
common_type的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr bool operator>(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
大于比较运算符
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
constexpr bool operator<=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于等于比较运算符
unique_ptr< T, Deleter > reinterpret_pointer_cast(const unique_ptr< U, Deleter > &ptr)=delete
禁止的reinterpret_pointer_cast
constexpr bool operator>=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
大于等于比较运算符
unique_ptr< T, Deleter > dynamic_pointer_cast(const unique_ptr< U, Deleter > &ptr)=delete
禁止的dynamic_pointer_cast
constexpr bool operator==(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
相等比较运算符
unique_ptr< T, Deleter > static_pointer_cast(const unique_ptr< U, Deleter > &ptr)=delete
禁止的static_pointer_cast
unique_ptr< T, Deleter > const_pointer_cast(const unique_ptr< U, Deleter > &ptr)=delete
禁止的const_pointer_cast
constexpr bool operator<(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于比较运算符
constexpr bool operator!=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
不等比较运算符
constexpr compressed_pair & get_base() &noexcept
获取基类引用
static constexpr bool value