1#ifndef MSTL_CORE_MEMORY_UNIQUE_PTR_HPP__
2#define MSTL_CORE_MEMORY_UNIQUE_PTR_HPP__
45 MSTL_CONSTEXPR20
void operator ()(
const T* ptr)
const noexcept {
80 template <
typename U, enable_if_t<is_convertible<U(*)[], T(*)[]>::value,
int> = 0>
107template <
typename T,
typename Deleter>
108class __unique_ptr_impl {
110 template <
typename U,
typename E,
typename =
void>
114 template <
typename U,
typename E>
116 using type =
typename remove_reference<E>::type::pointer;
120 using DeleterConstraint = enable_if<is_default_constructible<Deleter>::value>;
121 using pointer =
typename inner_ptr<T, Deleter>::type;
124 _MSTL tuple<pointer, Deleter> tup{};
127 "deleter type of unique_ptr must be a function object type or an lvalue reference type");
130 __unique_ptr_impl() =
default;
131 MSTL_CONSTEXPR20 __unique_ptr_impl(pointer ptr) : tup() { get_ptr() = ptr; }
133 template <
typename Del>
134 MSTL_CONSTEXPR20 __unique_ptr_impl(pointer ptr, Del&& del)
137 MSTL_CONSTEXPR20 __unique_ptr_impl(__unique_ptr_impl&& ptr) noexcept
138 : tup(
_MSTL move(ptr.tup)) { ptr.get_ptr() =
nullptr; }
140 MSTL_CONSTEXPR20 __unique_ptr_impl& operator =(__unique_ptr_impl&& x)
noexcept {
146 MSTL_CONSTEXPR20 pointer& get_ptr() noexcept {
return _MSTL get<0>(tup); }
147 MSTL_CONSTEXPR20 pointer get_ptr() const noexcept {
return _MSTL get<0>(tup); }
148 MSTL_CONSTEXPR20 Deleter& get_deleter() noexcept {
return _MSTL get<1>(tup); }
149 MSTL_CONSTEXPR20
const Deleter& get_deleter() const noexcept {
return _MSTL get<1>(tup); }
151 MSTL_CONSTEXPR20
void reset(pointer ptr)
noexcept {
152 const pointer old = get_ptr();
159 MSTL_CONSTEXPR20 pointer
release() noexcept {
160 pointer p = get_ptr();
165 MSTL_CONSTEXPR20
void swap(__unique_ptr_impl& x)
noexcept {
167 _MSTL swap(get_deleter(), x.get_deleter());
181template <
typename T,
typename Deleter,
184struct __unique_ptr_data : __unique_ptr_impl<T, Deleter> {
185 using base_type = __unique_ptr_impl<T, Deleter>;
186 using pointer =
typename base_type::pointer;
188 __unique_ptr_data() =
default;
189 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr) : base_type(ptr) {}
191 template <
typename Del>
192 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& del) : base_type(ptr,
_MSTL forward<Del>(del)) {}
194 __unique_ptr_data(__unique_ptr_data&&) =
default;
195 __unique_ptr_data& operator =(__unique_ptr_data&&) =
default;
199template <
typename T,
typename Deleter>
200struct __unique_ptr_data<T, Deleter, true, false> : __unique_ptr_impl<T, Deleter> {
201 using base_type = __unique_ptr_impl<T, Deleter>;
202 using pointer =
typename base_type::pointer;
204 __unique_ptr_data() =
default;
205 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr) : base_type(ptr) {}
207 template <
typename Del>
208 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& del) : base_type(ptr,
_MSTL forward<Del>(del)) {}
210 __unique_ptr_data(__unique_ptr_data&&) =
default;
211 __unique_ptr_data& operator =(__unique_ptr_data&&) =
delete;
215template <
typename T,
typename Deleter>
216struct __unique_ptr_data<T, Deleter, false, true> : __unique_ptr_impl<T, Deleter> {
217 using base_type = __unique_ptr_impl<T, Deleter>;
218 using pointer =
typename base_type::pointer;
220 __unique_ptr_data() =
default;
221 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr) : base_type(ptr) {}
223 template <
typename Del>
224 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& del) : base_type(ptr,
_MSTL forward<Del>(del)) {}
226 __unique_ptr_data(__unique_ptr_data&&) =
delete;
227 __unique_ptr_data& operator =(__unique_ptr_data&&) =
default;
231template <
typename T,
typename Deleter>
232struct __unique_ptr_data<T, Deleter, false, false> : __unique_ptr_impl<T, Deleter> {
233 using base_type = __unique_ptr_impl<T, Deleter>;
234 using pointer =
typename base_type::pointer;
236 __unique_ptr_data() =
default;
237 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr) : base_type(ptr) {}
239 template <
typename Del>
240 MSTL_CONSTEXPR20 __unique_ptr_data(pointer ptr, Del&& del) : base_type(ptr,
_MSTL forward<Del>(del)) {}
242 __unique_ptr_data(__unique_ptr_data&&) =
delete;
243 __unique_ptr_data& operator =(__unique_ptr_data&&) =
delete;
258template <
typename T,
typename Deleter = default_delete<T>>
261 template <
typename U>
262 using DeleterConstraint =
263 typename _INNER __unique_ptr_impl<T, U>::DeleterConstraint::type;
265 _INNER __unique_ptr_data<T, Deleter> data_{};
273 template <
typename U,
typename E>
283 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
291 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
303 noexcept : data_(ptr, del) {}
314 noexcept : data_(ptr,
_MSTL move(del)) {}
319 template <
typename Del = deleter_type,
typename DelMoveRef = remove_reference_t<Del>>
330 template <
typename U,
typename E, enable_if_t<conjunction<safe_conversion<U, E>,
331 conditional_t<is_reference<Deleter>::value, is_same<E, Deleter>, is_convertible<E, Deleter>>>::value,
int> = 0>
340 auto& ptr = data_.get_ptr();
389 MSTL_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
397 MSTL_CONSTEXPR20
explicit operator bool() const noexcept {
405 return data_.release();
413 "deleter of unique_ptr must be invocable with a pointer");
435template <
typename T,
typename Deleter>
437 template <
typename U>
438 using DeleterConstraint =
439 typename _INNER __unique_ptr_impl<T, U>::DeleterConstraint::type;
441 _INNER __unique_ptr_data<T, Deleter> data_;
449 template <
typename U,
typename E,
typename UP = unique_ptr<U, E>,
450 typename UP_po
inter =
typename UP::po
inter,
451 typename UP_element_type =
typename UP::element_type>
455 template <
typename U>
467 template <
typename U,
typename Del = Deleter,
typename = DeleterConstra
int<Del>,
468 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
469 MSTL_CONSTEXPR20
explicit unique_ptr(U ptr) noexcept : data_(ptr) {}
498 template <
typename U,
typename Del = deleter_type,
typename DelMoveRef = remove_reference_t<Del>,
499 enable_if_t<safe_conversion_raw<U>::value,
int> = 0>
508 template <
typename Del = Deleter,
typename = DeleterConstra
int<Del>>
517 template <
typename U,
typename E, enable_if_t<conjunction<safe_conversion<U, E>,
518 conditional_t<is_reference<Deleter>::value, is_same<E, Deleter>, is_convertible<E, Deleter>>>::value,
int> = 0>
526 auto& ptr = data_.get_ptr();
527 if (ptr !=
nullptr) {
565 MSTL_DEBUG_VERIFY(
get() !=
pointer(),
"_MSTL add_lvalue_reference_t<element_type> failed");
569 MSTL_CONSTEXPR20
pointer get() const noexcept {
return data_.get_ptr(); }
577 MSTL_CONSTEXPR20
explicit operator bool() const noexcept {
585 return data_.release();
628template <
typename T,
typename Deleter,
644template <
typename T,
typename D,
typename U,
typename E>
647 return lhs.
get() == rhs.
get();
657template <
typename T,
typename D>
670template <
typename T,
typename D>
686template <
typename T,
typename D,
typename U,
typename E>
689 return lhs.
get() != rhs.
get();
699template <
typename T,
typename D>
702 return static_cast<bool>(lhs);
712template <
typename T,
typename D>
715 return static_cast<bool>(rhs);
728template <
typename T,
typename D,
typename U,
typename E>
744template <
typename T,
typename D>
757template <
typename T,
typename D>
773template <
typename T,
typename D,
typename U,
typename E>
776 return rhs.
get() < lhs.
get();
786template <
typename T,
typename D>
799template <
typename T,
typename D>
815template <
typename T,
typename D,
typename U,
typename E>
828template <
typename T,
typename D>
831 return !(lhs >
nullptr);
841template <
typename T,
typename D>
844 return !(
nullptr > rhs);
857template <
typename T,
typename D,
typename U,
typename E>
870template <
typename T,
typename D>
873 return !(lhs <
nullptr);
883template <
typename T,
typename D>
886 return !(
nullptr < rhs);
897template <
typename T,
typename U>
907template <
typename T,
typename U>
917template <
typename T,
typename U>
927template <
typename T,
typename U>
938template <
typename T,
typename U>
940 return unique_ptr<T>(
static_cast<T*
>(ptr.release()), ptr.get_deleter());
950template <
typename T,
typename U>
952 return unique_ptr<T>(
const_cast<T*
>(ptr.release()), ptr.get_deleter());
962template <
typename T,
typename U>
964 return unique_ptr<T>(
reinterpret_cast<T*
>(ptr.release()), ptr.get_deleter());
974template <
typename T,
typename U>
976 T* tmp =
dynamic_cast<T*
>(ptr.release());
977 if (tmp !=
nullptr) {
989template <
typename T,
typename Deleter>
997 noexcept(
noexcept(
hash<T>()(ptr.get()))) {
1021template <typename T, enable_if_t<is_unbounded_array<T>::value,
int> = 0>
unique_ptr(unique_ptr &&)=default
移动构造函数
MSTL_CONSTEXPR20 const deleter_type & get_deleter() const noexcept
获取const删除器引用
MSTL_CONSTEXPR20 pointer get() const noexcept
获取原始指针
MSTL_CONSTEXPR20 void reset(nullptr_t=nullptr) noexcept
重置为空指针
MSTL_CONSTEXPR20 void reset(U ptr) noexcept
重置管理的指针
unique_ptr(U, enable_if_t< is_lvalue_reference< Del >::value, DelMoveRef && >)=delete
禁止从右值引用删除器构造
MSTL_CONSTEXPR20 unique_ptr(U ptr) noexcept
从指针构造
MSTL_CONSTEXPR20 unique_ptr(unique_ptr< U, E > &&x) noexcept
从其他unique_ptr转换构造
MSTL_CONSTEXPR20 pointer release() noexcept
释放所有权
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
Deleter deleter_type
删除器类型
MSTL_CONSTEXPR20 ~unique_ptr()
析构函数
MSTL_CONSTEXPR20 unique_ptr(U ptr, const deleter_type &del) noexcept
从指针和复制删除器构造
MSTL_CONSTEXPR20 deleter_type & get_deleter() noexcept
获取删除器引用
typename _INNER __unique_ptr_impl< T, Deleter >::pointer pointer
指针类型
MSTL_CONSTEXPR20 void swap(unique_ptr &x) noexcept
交换两个unique_ptr
unique_ptr(const unique_ptr &)=delete
禁止复制构造
MSTL_CONSTEXPR20 unique_ptr(U ptr, enable_if_t<!is_lvalue_reference< Del >::value, Del && > del) noexcept
从指针和移动删除器构造
~unique_ptr() noexcept
析构函数
unique_ptr(const unique_ptr &)=delete
禁止复制构造
constexpr unique_ptr(nullptr_t=nullptr) noexcept
空指针构造
MSTL_CONSTEXPR20 unique_ptr(unique_ptr< U, E > &&x) noexcept
从其他unique_ptr转换构造
MSTL_CONSTEXPR20 pointer release() noexcept
释放所有权
MSTL_CONSTEXPR20 const deleter_type & get_deleter() const noexcept
获取const删除器引用
MSTL_CONSTEXPR20 deleter_type & get_deleter() noexcept
获取删除器引用
default_delete< env_value > deleter_type
MSTL_CONSTEXPR20 unique_ptr(pointer ptr, const deleter_type &del) noexcept
从指针和复制删除器复制构造
MSTL_CONSTEXPR20 pointer operator->() const noexcept
成员访问运算符
MSTL_CONSTEXPR20 pointer get() const noexcept
获取原始指针
MSTL_CONSTEXPR20 unique_ptr(pointer, enable_if_t< is_lvalue_reference< Del >::value, DelMoveRef && >)=delete
禁止从右值引用删除器构造
MSTL_CONSTEXPR20 void swap(unique_ptr &x) noexcept
交换两个unique_ptr
typename _INNER __unique_ptr_impl< env_value, default_delete< env_value > >::pointer pointer
MSTL_CONSTEXPR20 add_lvalue_reference_t< element_type > operator*() const noexcept(noexcept(*_MSTL declval< pointer >()))
解引用运算符
MSTL_CONSTEXPR20 void reset(pointer ptr=pointer()) noexcept
重置管理的指针
MSTL_CONSTEXPR20 unique_ptr(unique_ptr &&)=default
移动构造函数
MSTL_CONSTEXPR20 unique_ptr(pointer ptr, Del &&del) noexcept
从指针和移动删除器移动构造
MSTL_CONSTEXPR20 unique_ptr(pointer p) noexcept
从指针构造
unique_ptr & operator=(unique_ptr &&)=default
移动赋值运算符
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_ALWAYS_INLINE enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
decltype(nullptr) nullptr_t
空指针类型
@ release
释放操作,确保前面的读写不会被重排到后面
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
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)
移动范围元素
void swap()=delete
删除无参数的swap重载
typename common_type< Types... >::type common_type_t
common_type的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL_NODISCARD MSTL_CONSTEXPR20 bool operator!=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
不等比较运算符
MSTL_NODISCARD MSTL_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
MSTL_NODISCARD MSTL_CONSTEXPR20 bool operator==(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
相等比较运算符
unique_ptr< T > const_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的const_pointer_cast
MSTL_NODISCARD MSTL_CONSTEXPR20 bool operator<=(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于等于比较运算符
unique_ptr< T > static_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的static_pointer_cast
MSTL_NODISCARD MSTL_CONSTEXPR20 bool operator>(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
大于比较运算符
MSTL_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
unique_ptr< T > dynamic_pointer_cast(const unique_ptr< U > &ptr)=delete
禁止的dynamic_pointer_cast
MSTL_NODISCARD MSTL_CONSTEXPR20 bool operator<(const unique_ptr< T, D > &lhs, const unique_ptr< U, E > &rhs)
小于比较运算符
MSTL_CONSTEXPR20 default_delete< U[]> rebind() &&noexcept
重新绑定到其他数组类型的删除器
constexpr default_delete() noexcept=default
默认构造函数
MSTL_CONSTEXPR20 default_delete< U > rebind() &&noexcept
重新绑定到其他类型的删除器
MSTL_CONSTEXPR20 void operator()(const T *ptr) const noexcept
删除操作符
constexpr default_delete() noexcept=default
默认构造函数
static constexpr bool value