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};
55 static_assert(!is_rvalue_reference<Deleter>::value,
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();
94 ptr_pair_.get_base()(old);
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,
118 bool MoveAssignable = is_move_assignable<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>
424 template <
typename U,
typename Del = deleter_type,
427 data_(ptr, deleter) {}
436 template <
typename U,
typename Del = deleter_type,
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>
879 DeleterU&& deleter = _NEFORCE
move(ptr).get_deleter();
893template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
895 DeleterU&& deleter = _NEFORCE
move(ptr).get_deleter();
909template <
typename T,
typename DeleterT,
typename U,
typename DeleterU>
911 DeleterU&& deleter = _NEFORCE
move(ptr).get_deleter();
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>()};
933 DeleterU&& deleter = _NEFORCE
move(ptr).get_deleter();
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>
993template <
typename T,
typename... Args, enable_if_t<is_bounded_array<T>::value,
int> = 0>
998NEFORCE_END_NAMESPACE__
constexpr unique_ptr(U ptr, const deleter_type &deleter) noexcept
从指针和复制删除器构造
unique_ptr(U, enable_if_t< is_lvalue_reference< Del >::value, DelMoveRef && >)=delete
禁止从右值引用删除器构造
typename inner::__unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
unique_ptr(unique_ptr &&)=default
移动构造函数
constexpr void swap(unique_ptr &other) noexcept
交换两个unique_ptr
unique_ptr(const unique_ptr &)=delete
禁止复制构造
constexpr const deleter_type & get_deleter() const noexcept
获取删除器常量引用
constexpr void reset(U ptr) noexcept
重置管理的指针
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
constexpr unique_ptr(U ptr, enable_if_t<!is_lvalue_reference< Del >::value, Del && > deleter) noexcept
从指针和移动删除器构造
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
constexpr pointer get() const noexcept
获取原始指针
constexpr unique_ptr(U ptr) noexcept
从指针构造
constexpr ~unique_ptr()
析构函数
constexpr deleter_type & get_deleter() noexcept
获取删除器引用
Deleter deleter_type
删除器类型
constexpr void reset(nullptr_t=nullptr) noexcept
重置为空指针
unique_ptr & operator=(unique_ptr &&)=default
移动赋值运算符
constexpr unique_ptr(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr转换构造
constexpr add_lvalue_reference_t< element_type > operator[](size_t idx) const
数组下标运算符
constexpr pointer release() noexcept
释放所有权
constexpr unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
constexpr unique_ptr & operator=(unique_ptr< U, E > &&other) noexcept
从其他unique_ptr移动赋值
constexpr void swap(unique_ptr &other) noexcept
交换两个unique_ptr
constexpr void reset(pointer ptr=pointer()) noexcept
Deleter deleter_type
删除器类型
~unique_ptr() noexcept
析构函数
typename inner::__unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
constexpr const deleter_type & get_deleter() const &noexcept
获取删除器常量引用
constexpr unique_ptr(unique_ptr &&) noexcept=default
移动构造函数
constexpr deleter_type && get_deleter() &&noexcept
获取删除器引用
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
constexpr deleter_type & get_deleter() &noexcept
constexpr unique_ptr & operator=(nullptr_t) noexcept
nullptr赋值运算符
constexpr add_lvalue_reference_t< element_type > operator*() const noexcept(noexcept(*_NEFORCE declval< pointer >()))
解引用运算符
constexpr pointer operator->() const noexcept
成员访问运算符
constexpr pointer get() const noexcept
unique_ptr(const unique_ptr &)=delete
禁止复制构造
constexpr unique_ptr(pointer ptr) noexcept
从指针构造
constexpr const deleter_type && get_deleter() const &&noexcept
获取删除器常量引用
constexpr pointer release() noexcept
unique_ptr & operator=(unique_ptr &&) noexcept=default
移动赋值运算符
unique_ptr & operator=(const unique_ptr &)=delete
禁止复制赋值
constexpr unique_ptr(pointer ptr, Del &&deleter) noexcept
从指针和复制删除器复制构造
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
空指针类型
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
@ release
释放操作,确保前面的读写不会被重排到后面
typename remove_extent< T >::type remove_extent_t
remove_extent的便捷别名
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
@ reset
调用sqlite3_reset重置语句(用于预处理语句复用)
shared_ptr< T > dynamic_pointer_cast(const shared_ptr< U > &ptr)
动态类型转换
shared_ptr< T > reinterpret_pointer_cast(const shared_ptr< U > &ptr)
重解释类型转换
shared_ptr< T > static_pointer_cast(const shared_ptr< U > &ptr)
静态类型转换
shared_ptr< T > const_pointer_cast(const shared_ptr< U > &ptr)
CV类型转换
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
typename common_type< Types... >::type common_type_t
common_type的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
void swap(unique_ptr< T, Deleter > &lhs, unique_ptr< T, Deleter > &rhs) noexcept
交换两个unique_ptr
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
static constexpr bool value