1#ifndef MSTL_CORE_MEMORY_SHARED_PTR_HPP__
2#define MSTL_CORE_MEMORY_SHARED_PTR_HPP__
34struct __smart_ptr_counter {
43 virtual void delete_object() noexcept = 0;
48 virtual
void delete_this() noexcept {
57 __smart_ptr_counter() noexcept
58 : strong_count_(1), weak_count_(1) {}
60 __smart_ptr_counter(__smart_ptr_counter&&) =
delete;
62 virtual ~__smart_ptr_counter() =
default;
67 void incref_strong() noexcept {
74 void incref_weak() noexcept {
82 void decref_strong() noexcept {
93 void decref_weak() noexcept {
105 bool try_incref_strong() noexcept {
108 if (strong == 0)
return false;
109 }
while (!strong_count_.compare_exchange_weak(
121 MSTL_NODISCARD
uint64_t use_count() const noexcept {
129 MSTL_NODISCARD
uint64_t weak_count() const noexcept {
141template <
typename T,
typename Deleter>
142struct __smart_ptr_counter_impl final : __smart_ptr_counter {
146 explicit __smart_ptr_counter_impl(T* ptr) noexcept
149 explicit __smart_ptr_counter_impl(T* ptr, Deleter&& deleter) noexcept
152 void delete_object() noexcept
override {
165template <
typename T,
typename Deleter>
166struct __smart_ptr_counter_impl_fused final : __smart_ptr_counter {
171 explicit __smart_ptr_counter_impl_fused(T* ptr,
void* mem, Deleter deleter) noexcept
172 : ptr_(ptr), mem_(mem), deleter_(
_MSTL move(deleter)) {}
174 void delete_object() noexcept
override {
179 void delete_this() noexcept
override {
181#if MSTL_STANDARD_17__
182 ,
static_cast<std::align_val_t
>(
183 _MSTL max(
alignof(T),
alignof(__smart_ptr_counter_impl_fused)))
197template <
typename T,
typename Deleter,
typename Alloc>
198struct __smart_ptr_counter_impl_allocated final : __smart_ptr_counter {
205 explicit __smart_ptr_counter_impl_allocated(
206 T* ptr,
void* mem,
const size_t size,
207 Deleter deleter, Alloc alloc) noexcept
208 : ptr_(ptr), mem_(mem), size_(
size),
212 void delete_object() noexcept
override {
217 void delete_this() noexcept
override {
218 using alloc_traits = allocator_traits<Alloc>;
219 using byte_allocator =
typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
220 byte_allocator byte_alloc(allocator_);
243__setup_enable_shared_from(T* ptr, __smart_ptr_counter* owner) {
250__setup_enable_shared_from(T*, __smart_ptr_counter*) {
255MSTL_ALWAYS_INLINE
shared_ptr<T> __make_shared_fused(T* ptr, __smart_ptr_counter* owner)
noexcept {
278 _INNER __smart_ptr_counter* owner_ =
nullptr;
285 explicit shared_ptr(T* ptr,
_INNER __smart_ptr_counter* owner) noexcept
286 : ptr_(ptr), owner_(owner) {}
288 template <
typename U>
291 template <
typename U>
294 template <
typename U>
311 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
314 _INNER __setup_enable_shared_from<T>(ptr_, owner_);
324 template <
typename U,
typename Deleter, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
326 : ptr_(ptr), owner_(new
_INNER __smart_ptr_counter_impl<U, Deleter>(ptr,
_MSTL forward<Deleter>(deleter))) {
327 _INNER __setup_enable_shared_from<T>(ptr_, owner_);
336 template <
typename U,
typename Deleter, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
338 : shared_ptr(ptr.
release(), ptr.get_deleter()) {}
345 : ptr_(x.ptr_), owner_(x.owner_) {
346 if (owner_) owner_->incref_strong();
356 if (owner_) owner_->decref_strong();
359 if (owner_) owner_->incref_strong();
368 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
370 : ptr_(x.ptr_), owner_(x.owner_) {
371 if (owner_) owner_->incref_strong();
379 : ptr_(x.ptr_), owner_(x.owner_) {
391 if (owner_) owner_->decref_strong();
404 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
406 : ptr_(x.ptr_), owner_(x.owner_) {
418 template <
typename U>
420 : ptr_(ptr), owner_(x.owner_) {
421 if (owner_) owner_->incref_strong();
427 template <
typename U>
429 : ptr_(ptr), owner_(x.owner_) {
437 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
439 if (owner_) owner_->decref_strong();
442 if (owner_) owner_->incref_strong();
449 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
451 if (owner_) owner_->decref_strong();
471 if (owner_) owner_->decref_strong();
481 template <
typename U>
483 if (owner_) owner_->decref_strong();
487 owner_ =
new _INNER __smart_ptr_counter_impl<U, default_delete<U>>(ptr);
488 _INNER __setup_enable_shared_from<T>(ptr_, owner_);
498 template <
typename U,
typename Deleter>
499 void reset(U* ptr, Deleter deleter) {
500 if (owner_) owner_->decref_strong();
504 owner_ =
new _INNER __smart_ptr_counter_impl<U, Deleter>(ptr,
_MSTL move(deleter));
505 _INNER __setup_enable_shared_from<T>(ptr_, owner_);
513 return owner_ ? owner_->use_count() : 0;
520 MSTL_NODISCARD
bool unique() const noexcept {
521 return owner_ ? owner_->use_count() == 1 :
true;
528 void swap(shared_ptr& x)
noexcept {
538 MSTL_NODISCARD T*
get() const noexcept {
562 MSTL_NODISCARD
explicit operator bool() const noexcept {
563 return ptr_ !=
nullptr;
572 template <
typename U>
573 MSTL_NODISCARD
bool owner_equal(
const shared_ptr<U>& rhs)
const noexcept {
574 return owner_ == rhs.owner_;
580 template <
typename U>
581 MSTL_NODISCARD
bool owner_equal(
const weak_ptr<U>& rhs)
const noexcept {
582 return owner_ == rhs.owner_;
591 template <
typename U>
592 MSTL_NODISCARD
bool owner_before(
const shared_ptr<U>& rhs)
const noexcept {
593 return owner_ < rhs.owner_;
599 template <
typename U>
600 MSTL_NODISCARD
bool owner_before(
const weak_ptr<U>& rhs)
const noexcept {
601 return owner_ < rhs.owner_;
608template <
typename T,
typename U>
610 return lhs.owner_equal(rhs);
616template <
typename T,
typename U>
618 return !(lhs == rhs);
624template <
typename T,
typename U>
626 return lhs.owner_before(rhs);
632template <
typename T,
typename U>
640template <
typename T,
typename U>
648template <
typename T,
typename U>
659class shared_ptr<T[]> : shared_ptr<T> {
661 using shared_ptr<T>::shared_ptr;
669 return this->
get()[idx];
684 _INNER __smart_ptr_counter* owner_ =
nullptr;
686 template <
typename U>
701 static_assert(is_base_of_v<enable_shared_from_this, T>,
"shared from T requires derived class");
705 owner_->incref_strong();
706 return _INNER __make_shared_fused(
static_cast<T*
>(
this), owner_);
715 static_assert(is_base_of_v<enable_shared_from_this, T>,
"shared from T requires derived class");
719 owner_->incref_strong();
720 return _INNER __make_shared_fused(
static_cast<T const*
>(
this), owner_);
735template <
typename T,
typename... Args>
738 auto const deleter = [](T* ptr)
noexcept { ptr->~T(); };
739 using Counter =
_INNER __smart_ptr_counter_impl_fused<T,
decltype(deleter)>;
740 constexpr size_t align =
_MSTL max(
alignof(T),
alignof(Counter));
741 constexpr size_t offset = (
sizeof(Counter) + align - 1) & ~(align - 1);
742 constexpr size_t size = offset +
sizeof(T);
743#if MSTL_STANDARD_17__
744 void* mem = ::operator
new(
size,
static_cast<std::align_val_t
>(align));
745 Counter* counter =
static_cast<Counter*
>(mem);
747 void* mem = ::operator
new(
size + align - 1);
748 size_t aligned_addr = (
reinterpret_cast<size_t>(mem) + (align - 1)) & ~(align - 1);
749 Counter* counter =
reinterpret_cast<Counter*
>(aligned_addr);
751 T*
object =
reinterpret_cast<T*
>(
reinterpret_cast<byte_t*
>(counter) + offset);
755#if MSTL_STANDARD_17__
756 operator delete(mem,
static_cast<std::align_val_t
>(align));
758 operator delete(mem);
762 new (counter) Counter(
object, mem, deleter);
763 _INNER __setup_enable_shared_from(
object, counter);
764 return _INNER __make_shared_fused(
object, counter);
778 auto* tmp =
new value[len]();
798template <
typename T,
typename Alloc,
typename... Args>
801 auto deleter = [](T* p) { p->~T(); };
802 using ControlBlock =
_INNER __smart_ptr_counter_impl_allocated<T,
decltype(deleter), Alloc>;
804 const size_t align =
_MSTL max(
alignof(ControlBlock),
alignof(T));
805 const size_t offset = (
sizeof(ControlBlock) + align - 1) & ~(align - 1);
806 const size_t total_size = offset +
sizeof(T);
807 const size_t raw_size = total_size + align - 1;
810 using byte_allocator =
typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
811 byte_allocator byte_alloc(alloc);
816 const uintptr_t aligned_addr = (raw_addr + align - 1) & ~
static_cast<uintptr_t>(align - 1);
817 auto aligned_mem =
reinterpret_cast<byte_t*
>(aligned_addr);
818 T* object_ptr =
reinterpret_cast<T*
>(aligned_mem + offset);
824 throw_exception(
memory_exception(
"shared ptr ref object construction failed."));
827 ControlBlock* ctrl_block =
nullptr;
829 ctrl_block = ::new (aligned_mem) ControlBlock(object_ptr, raw_mem, raw_size, deleter, alloc);
833 throw_exception(
memory_exception(
"shared ptr control block construction failed."));
836 _INNER __setup_enable_shared_from(object_ptr, ctrl_block);
837 return _INNER __make_shared_fused(object_ptr, ctrl_block);
848template <
typename T,
typename U>
860template <
typename T,
typename U>
872template <
typename T,
typename U>
884template <
typename T,
typename U>
886 T* tmp =
dynamic_cast<T*
>(ptr.
get());
894 MSTL_CONSTEXPR20
size_t operator ()(
const shared_ptr<T>& ptr)
const
896 return hash<T*>()(ptr.get());
shared_ptr(const shared_ptr< U > &x, T *ptr) noexcept
从共享指针和别名指针别名构造函数
MSTL_NODISCARD bool owner_before(const shared_ptr< U > &rhs) const noexcept
比较所有权顺序
shared_ptr(shared_ptr &&x) noexcept
移动构造函数
void swap(shared_ptr &x) noexcept
交换两个共享指针
MSTL_NODISCARD long use_count() const noexcept
获取引用计数
shared_ptr & operator=(const shared_ptr &x) noexcept
拷贝赋值运算符
shared_ptr(shared_ptr< U > &&x, T *ptr) noexcept
移动别名构造函数
void reset(U *ptr)
重置共享指针并管理新对象
shared_ptr(const shared_ptr< U > &x) noexcept
类型转换拷贝构造函数
shared_ptr(nullptr_t np=nullptr) noexcept
默认构造函数
MSTL_NODISCARD add_lvalue_reference_t< T > operator*() const noexcept
解引用运算符
MSTL_NODISCARD bool owner_equal(const weak_ptr< U > &rhs) const noexcept
与弱指针检查所有权是否相等
periodic_task_state element_type
shared_ptr(U *ptr, Deleter &&deleter)
从原始指针和自定义删除器构造函数
MSTL_NODISCARD T * operator->() const noexcept
指针解引用运算符
~shared_ptr() noexcept
析构函数
void reset(U *ptr, Deleter deleter)
带自定义删除器重置共享指针并管理新对象
shared_ptr(shared_ptr< U > &&x) noexcept
类型转换移动构造函数
MSTL_NODISCARD bool unique() const noexcept
检查是否独占所有权
void reset() noexcept
重置共享指针
MSTL_NODISCARD T * get() const noexcept
获取原始指针
shared_ptr(U *ptr)
从原始指针构造函数
shared_ptr(unique_ptr< U, Deleter > &&ptr)
独享智能指针构造函数
MSTL_NODISCARD bool owner_before(const weak_ptr< U > &rhs) const noexcept
与弱指针比较所有权顺序
MSTL_NODISCARD bool owner_equal(const shared_ptr< U > &rhs) const noexcept
检查所有权是否相等
shared_ptr(const shared_ptr &x) noexcept
拷贝构造函数
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
atomic< unsigned long > atomic_ulong
无符号长整型原子类型
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
unsigned char byte_t
字节类型,定义为无符号字符
unsigned long long uint64_t
64位无符号整数类型
decltype(nullptr) nullptr_t
空指针类型
MSTL_CONSTEXPR20 enable_if_t< is_constructible_v< T, Args... >, void * > construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
MSTL_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
@ 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_extent< T >::type remove_extent_t
remove_extent的便捷别名
MSTL_NODISCARD bool operator<=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
小于等于比较运算符
MSTL_NODISCARD bool operator!=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
不等比较运算符
MSTL_NODISCARD bool operator>(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
大于比较运算符
MSTL_NODISCARD bool operator>=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
大于等于比较运算符
MSTL_NODISCARD bool operator<(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
小于比较运算符(基于所有权顺序)
shared_ptr< T > const_pointer_cast(const shared_ptr< U > &ptr)
CV类型转换
MSTL_NODISCARD bool operator==(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
相等比较运算符
shared_ptr< T > dynamic_pointer_cast(const shared_ptr< U > &ptr)
动态类型转换
enable_if_t<!is_unbounded_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > make_shared(Args &&... args)
融合分配创建共享指针
enable_if_t<!is_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > allocate_shared(Alloc &alloc, Args &&... args)
使用分配器创建共享指针
shared_ptr< T > static_pointer_cast(const shared_ptr< U > &ptr)
静态类型转换
shared_ptr< T > reinterpret_pointer_cast(const shared_ptr< U > &ptr)
重解释类型转换
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
static MSTL_CONSTEXPR20 void destroy(Alloc &alloc, T *ptr) noexcept(noexcept(allocator_traits::__destroy_aux(alloc, ptr, 0)))
销毁对象
static MSTL_NODISCARD MSTL_CONSTEXPR20 pointer allocate(Alloc &alloc, size_type n)
分配内存
static MSTL_CONSTEXPR20 void deallocate(Alloc &alloc, pointer ptr, size_type n)
释放内存
static MSTL_CONSTEXPR20 void construct(Alloc &alloc, T *ptr, Args &&... args) noexcept(noexcept(allocator_traits::__construct_aux(alloc, ptr, _MSTL forward< Args >(args)...)))
在已分配内存上构造对象
MSTL_ALWAYS_INLINE value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
enable_shared_from_this() noexcept
构造函数
shared_ptr< T const > shared_from_this() const
获取指向自身的常量共享指针
shared_ptr< T > shared_from_this()
获取指向自身的共享指针