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 NEFORCE_CONSTEXPR20 __unique_ptr_impl(pointer ptr, Deleter&& deleter) :
65 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE
move(deleter), ptr) {}
67 NEFORCE_CONSTEXPR20 __unique_ptr_impl(pointer ptr,
const Deleter& deleter) :
68 ptr_pair_(exact_arg_construct_tag{}, deleter, ptr) {}
70 NEFORCE_CONSTEXPR20 __unique_ptr_impl(__unique_ptr_impl&& other) noexcept :
71 ptr_pair_(_NEFORCE
move(other.ptr_pair_)) {
72 other.get_ptr() =
nullptr;
75 NEFORCE_CONSTEXPR20 __unique_ptr_impl& operator=(__unique_ptr_impl&& other)
noexcept {
76 this->reset(other.release());
80 NEFORCE_CONSTEXPR20 pointer& get_ptr() noexcept {
return ptr_pair_.
value; }
82 NEFORCE_CONSTEXPR20 pointer get_ptr() const noexcept {
return ptr_pair_.
value; }
84 NEFORCE_CONSTEXPR20 Deleter& get_deleter() noexcept {
return ptr_pair_.
get_base(); }
86 NEFORCE_CONSTEXPR20
const Deleter& get_deleter() const noexcept {
return ptr_pair_.
get_base(); }
88 NEFORCE_CONSTEXPR20
void reset(pointer ptr)
noexcept {
89 const pointer old = get_ptr();
96 NEFORCE_CONSTEXPR20 pointer
release() noexcept {
97 pointer p = get_ptr();
102 NEFORCE_CONSTEXPR20
void swap(__unique_ptr_impl& other)
noexcept { _NEFORCE
swap(ptr_pair_, other.ptr_pair_); }
115template <typename T, typename Deleter, bool MoveConstructible = is_move_constructible<Deleter>::value,
117struct __unique_ptr_data : __unique_ptr_impl<T, Deleter> {
118 using base_type = __unique_ptr_impl<T, Deleter>;
119 using pointer =
typename base_type::pointer;
121 __unique_ptr_data() =
default;
123 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
126 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Deleter&& deleter) :
127 base_type(ptr, _NEFORCE
move(deleter)) {}
129 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr,
const Deleter& deleter) :
130 base_type(ptr, 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 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Deleter&& deleter) :
148 base_type(ptr, _NEFORCE
move(deleter)) {}
150 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr,
const Deleter& deleter) :
151 base_type(ptr, deleter) {}
153 __unique_ptr_data(__unique_ptr_data&&) =
default;
154 __unique_ptr_data& operator=(__unique_ptr_data&&) =
delete;
158template <
typename T,
typename Deleter>
159struct __unique_ptr_data<T, Deleter, false, true> : __unique_ptr_impl<T, Deleter> {
160 using base_type = __unique_ptr_impl<T, Deleter>;
161 using pointer =
typename base_type::pointer;
163 __unique_ptr_data() =
default;
165 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
168 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Deleter&& deleter) :
169 base_type(ptr, _NEFORCE
move(deleter)) {}
171 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr,
const Deleter& deleter) :
172 base_type(ptr, deleter) {}
174 __unique_ptr_data(__unique_ptr_data&&) =
delete;
175 __unique_ptr_data& operator=(__unique_ptr_data&&) =
default;
179template <
typename T,
typename Deleter>
180struct __unique_ptr_data<T, Deleter, false, false> : __unique_ptr_impl<T, Deleter> {
181 using base_type = __unique_ptr_impl<T, Deleter>;
182 using pointer =
typename base_type::pointer;
184 __unique_ptr_data() =
default;
186 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr) :
189 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr, Deleter&& deleter) :
190 base_type(ptr, _NEFORCE
move(deleter)) {}
192 NEFORCE_CONSTEXPR20 __unique_ptr_data(pointer ptr,
const Deleter& deleter) :
193 base_type(ptr, deleter) {}
195 __unique_ptr_data(__unique_ptr_data&&) =
delete;
196 __unique_ptr_data& operator=(__unique_ptr_data&&) =
delete;
211template <
typename T,
typename Deleter = default_delete<T>>
214 template <
typename U>
215 using DeleterConstraint =
typename inner::__unique_ptr_impl<T, U>::DeleterConstraint::type;
217 inner::__unique_ptr_data<T, Deleter> data_{};
220 using pointer =
typename inner::__unique_ptr_impl<T, Deleter>::pointer;
225 template <
typename U,
typename E>
234 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
242 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
252 data_(ptr, deleter) {}
260 data_(ptr, _NEFORCE
move(deleter)) {}
265 template <
typename Del = deleter_type,
typename DelMoveRef = remove_reference_t<Del>>
276 template <
typename U,
typename E,
282 data_(other.release(), _NEFORCE
forward<E>(other.get_deleter())) {}
289 "deleter of unique_ptr must be invocable with a pointer");
291 auto& ptr = data_.get_ptr();
292 if (ptr !=
nullptr) {
307 template <
typename U,
typename E,
310 reset(other.release());
342 NEFORCE_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
358 NEFORCE_CONSTEXPR20
explicit operator bool() const noexcept {
return get() ==
pointer() ? false :
true; }
370 "deleter of unique_ptr must be invocable with a pointer");
371 data_.reset(_NEFORCE
move(ptr));
380 data_.swap(other.data_);
392template <
typename T,
typename Deleter>
394 template <
typename U>
395 using DeleterConstraint =
typename inner::__unique_ptr_impl<T, U>::DeleterConstraint::type;
397 inner::__unique_ptr_data<T, Deleter> data_{};
400 using pointer =
typename inner::__unique_ptr_impl<T, Deleter>::pointer;
405 template <
typename U,
typename E,
typename UP = unique_ptr<U, E>,
typename UP_po
inter =
typename UP::po
inter,
406 typename UP_element_type =
typename UP::element_type>
407 using safe_conversion =
411 template <
typename U>
412 using safe_conversion_raw =
424 template <
typename U,
typename Del = Deleter,
typename = DeleterConstra
int<Del>,
425 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
439 data_(ptr, deleter) {}
451 data_(_NEFORCE
move(ptr), _NEFORCE
move(deleter)) {}
456 template <
typename U,
typename Del = deleter_type,
typename DelMoveRef = remove_reference_t<Del>,
457 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
466 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
475 template <
typename U,
typename E,
481 data_(other.release(), _NEFORCE
forward<E>(other.get_deleter())) {}
487 auto& ptr = data_.get_ptr();
488 if (ptr !=
nullptr) {
503 template <
typename U,
typename E,
533 NEFORCE_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
549 NEFORCE_CONSTEXPR20
explicit operator bool() const noexcept {
return get() ==
pointer() ? false :
true; }
561 template <
typename U,
567 NEFORCE_CONSTEXPR20
void reset(U ptr)
noexcept {
568 data_.reset(_NEFORCE
move(ptr));
580 NEFORCE_CONSTEXPR20
void swap(
unique_ptr& other)
noexcept { data_.swap(other.data_); }
593template <typename T, typename Deleter, enable_if_t<is_swappable<Deleter>::value &&
is_swappable<T>::value,
int> = 0>
608template <
typename T,
typename D,
typename U,
typename E>
610 return lhs.
get() == rhs.
get();
620template <
typename T,
typename D>
632template <
typename T,
typename D>
647template <
typename T,
typename D,
typename U,
typename E>
649 return lhs.
get() != rhs.
get();
659template <
typename T,
typename D>
661 return static_cast<bool>(lhs);
671template <
typename T,
typename D>
673 return static_cast<bool>(rhs);
686template <
typename T,
typename D,
typename U,
typename E>
699template <
typename T,
typename D>
711template <
typename T,
typename D>
726template <
typename T,
typename D,
typename U,
typename E>
728 return rhs.
get() < lhs.
get();
738template <
typename T,
typename D>
750template <
typename T,
typename D>
765template <
typename T,
typename D,
typename U,
typename E>
777template <
typename T,
typename D>
779 return !(lhs >
nullptr);
789template <
typename T,
typename D>
791 return !(
nullptr > rhs);
804template <
typename T,
typename D,
typename U,
typename E>
816template <
typename T,
typename D>
818 return !(lhs <
nullptr);
828template <
typename T,
typename D>
830 return !(
nullptr < rhs);
841template <
typename T,
typename U>
851template <
typename T,
typename U>
861template <
typename T,
typename U>
871template <
typename T,
typename U>
882template <
typename T,
typename U>
884 return unique_ptr<T>(
static_cast<T*
>(ptr.release()), ptr.get_deleter());
894template <
typename T,
typename U>
896 return unique_ptr<T>(
const_cast<T*
>(ptr.release()), ptr.get_deleter());
906template <
typename T,
typename U>
908 return unique_ptr<T>(
reinterpret_cast<T*
>(ptr.release()), ptr.get_deleter());
918template <
typename T,
typename U>
920 T* tmp =
dynamic_cast<T*
>(ptr.release());
921 if (tmp !=
nullptr) {
922 return unique_ptr<T>(tmp, _NEFORCE
move(ptr.get_deleter()).template rebind<T>());
939template <
typename T,
typename Deleter>
973template <typename T, enable_if_t<is_unbounded_array<T>::value,
int> = 0>
988NEFORCE_END_NAMESPACE__
NEFORCE_CONSTEXPR20 unique_ptr(U ptr, enable_if_t<!is_lvalue_reference< Del >::value, Del && > deleter) noexcept
从指针和移动删除器构造
unique_ptr(unique_ptr &&)=default
移动构造函数
NEFORCE_CONSTEXPR20 const deleter_type & get_deleter() 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
禁止从右值引用删除器构造
NEFORCE_CONSTEXPR20 unique_ptr(U ptr) noexcept
从指针构造
NEFORCE_CONSTEXPR20 void reset(nullptr_t=nullptr) noexcept
重置为空指针
NEFORCE_CONSTEXPR20 add_lvalue_reference_t< element_type > operator[](size_t idx) const
数组下标运算符
NEFORCE_CONSTEXPR20 deleter_type & get_deleter() noexcept
获取删除器引用
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
NEFORCE_CONSTEXPR20 unique_ptr(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr转换构造
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
NEFORCE_CONSTEXPR20 void swap(unique_ptr &other) noexcept
交换两个unique_ptr
NEFORCE_CONSTEXPR20 unique_ptr(U ptr, const deleter_type &deleter) noexcept
从指针和复制删除器构造
NEFORCE_CONSTEXPR20 ~unique_ptr()
析构函数
NEFORCE_CONSTEXPR20 pointer get() const noexcept
获取原始指针
Deleter deleter_type
删除器类型
NEFORCE_CONSTEXPR20 void reset(U ptr) noexcept
重置管理的指针
NEFORCE_CONSTEXPR20 unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
NEFORCE_CONSTEXPR20 unique_ptr & operator=(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr移动赋值
unique_ptr(const unique_ptr &)=delete
禁止复制构造
NEFORCE_CONSTEXPR20 pointer release() noexcept
释放所有权
~unique_ptr() noexcept
析构函数
unique_ptr(const unique_ptr &)=delete
禁止复制构造
NEFORCE_CONSTEXPR20 const deleter_type & get_deleter() const noexcept
获取删除器常量引用
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
NEFORCE_CONSTEXPR20 unique_ptr(pointer ptr, const deleter_type &deleter) noexcept
从指针和复制删除器复制构造
NEFORCE_CONSTEXPR20 void reset(pointer ptr=pointer()) noexcept
重置管理的指针
NEFORCE_CONSTEXPR20 pointer release() noexcept
释放所有权
NEFORCE_CONSTEXPR20 unique_ptr(pointer ptr) noexcept
从指针构造
Deleter deleter_type
删除器类型
NEFORCE_CONSTEXPR20 add_lvalue_reference_t< element_type > operator*() const noexcept(noexcept(*_NEFORCE declval< pointer >()))
解引用运算符
NEFORCE_CONSTEXPR20 deleter_type & get_deleter() noexcept
获取删除器引用
NEFORCE_CONSTEXPR20 unique_ptr(unique_ptr &&)=default
移动构造函数
NEFORCE_CONSTEXPR20 unique_ptr & operator=(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr移动赋值
NEFORCE_CONSTEXPR20 pointer get() const noexcept
获取原始指针
NEFORCE_CONSTEXPR20 unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
NEFORCE_CONSTEXPR20 unique_ptr(pointer, enable_if_t< is_lvalue_reference< Del >::value, DelMoveRef && >)=delete
禁止从右值引用删除器构造
NEFORCE_CONSTEXPR20 unique_ptr(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr转换构造
NEFORCE_CONSTEXPR20 pointer operator->() const noexcept
成员访问运算符
NEFORCE_CONSTEXPR20 void swap(unique_ptr &other) noexcept
交换两个unique_ptr
NEFORCE_CONSTEXPR20 unique_ptr(pointer ptr, deleter_type &&deleter) noexcept
从指针和移动删除器移动构造
typename inner::__unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
unique_ptr & operator=(unique_ptr &&)=default
移动赋值运算符
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
decltype(nullptr) nullptr_t
空指针类型
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
@ 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的便捷别名
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator!=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
不等比较运算符
NEFORCE_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator==(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
相等比较运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator>=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
大于等于比较运算符
unique_ptr< T > reinterpret_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的reinterpret_pointer_cast
unique_ptr< T > const_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的const_pointer_cast
unique_ptr< T > static_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的static_pointer_cast
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator<(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于比较运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator<=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于等于比较运算符
unique_ptr< T > dynamic_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的dynamic_pointer_cast
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator>(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
大于比较运算符
constexpr compressed_pair & get_base() noexcept
获取基类引用
static constexpr bool value