1#ifndef NEFORCE_CORE_MEMORY_SHARED_PTR_HPP__
2#define NEFORCE_CORE_MEMORY_SHARED_PTR_HPP__
18NEFORCE_BEGIN_NAMESPACE__
30class smart_pointer_atomic;
39struct __smart_ptr_counter {
41 atomic<unsigned long> strong_count_;
42 atomic<unsigned long> weak_count_;
48 virtual void delete_object() = 0;
53 virtual void delete_this() = 0;
60 __smart_ptr_counter() noexcept :
64 __smart_ptr_counter(__smart_ptr_counter&&) =
delete;
66 virtual ~__smart_ptr_counter() =
default;
71 void incref_strong() noexcept { strong_count_.fetch_add(1, memory_order_relaxed); }
76 void incref_weak() noexcept { weak_count_.fetch_add(1, memory_order_relaxed); }
82 void decref_strong() noexcept {
83 if (strong_count_.fetch_sub(1, memory_order_acq_rel) == 1) {
93 void decref_weak() noexcept {
94 if (weak_count_.fetch_sub(1, memory_order_acq_rel) == 1) {
105 bool try_incref_strong() noexcept {
106 auto strong = strong_count_.load(memory_order_relaxed);
111 }
while (!strong_count_.compare_exchange_weak(strong, strong + 1, memory_order_release, memory_order_relaxed));
119 NEFORCE_NODISCARD
uint64_t use_count() const noexcept {
return strong_count_.load(memory_order_relaxed); }
125 NEFORCE_NODISCARD
uint64_t weak_count() const noexcept {
return weak_count_.load(memory_order_relaxed); }
135template <
typename T,
typename Deleter>
136struct __smart_ptr_counter_impl final : __smart_ptr_counter {
137 compressed_pair<Deleter, T*> ptr_pair_{default_construct_tag{},
nullptr};
139 static_assert(is_invocable_v<Deleter, T*>,
"Deleter must be invocable by T*");
141 explicit __smart_ptr_counter_impl(T* ptr)
noexcept(is_nothrow_default_constructible_v<Deleter>) :
142 ptr_pair_(default_construct_tag{}, ptr) {}
144 template <
typename Del = Deleter, enable_if_t<is_constructible_v<Deleter, Del>,
int> = 0>
145 explicit __smart_ptr_counter_impl(T* ptr, Del&& deleter)
noexcept(is_nothrow_constructible_v<Deleter, Del>) :
146 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE
forward<Del>(deleter), ptr) {}
148 void delete_object()
override {
149 ptr_pair_.get_base()(ptr_pair_.value);
150 ptr_pair_.value =
nullptr;
153 void delete_this() noexcept
override {
delete this; }
163template <
typename T,
typename Deleter>
164struct __smart_ptr_counter_impl_fused final : __smart_ptr_counter {
165 compressed_pair<Deleter, T*> ptr_pair_{default_construct_tag{},
nullptr};
169 explicit __smart_ptr_counter_impl_fused(T* ptr,
void* mem,
size_t align, Deleter deleter) noexcept :
170 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE
move(deleter), ptr),
174 void delete_object() noexcept
override {
175 ptr_pair_.get_base()(ptr_pair_.value);
176 ptr_pair_.value =
nullptr;
179 void delete_this() noexcept
override {
180#if NEFORCE_STANDARD_17
181 operator delete(mem_, std::align_val_t{align_});
183 operator delete(mem_);
196template <
typename T,
typename Deleter,
typename Alloc>
197struct __smart_ptr_counter_impl_allocated final : __smart_ptr_counter {
198 compressed_pair<Deleter, T*> ptr_pair_{default_construct_tag{},
nullptr};
199 compressed_pair<Alloc, size_t> size_pair_{default_construct_tag{}, 0};
202 explicit __smart_ptr_counter_impl_allocated(T* ptr,
void* mem,
const size_t size, Deleter deleter,
203 Alloc alloc) noexcept :
204 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE
move(deleter), ptr),
205 size_pair_(exact_arg_construct_tag{}, _NEFORCE
move(alloc),
size),
208 void delete_object() noexcept
override {
209 ptr_pair_.get_base()(ptr_pair_.value);
210 ptr_pair_.value =
nullptr;
213 void delete_this() noexcept
override {
214 using alloc_traits = allocator_traits<Alloc>;
215 using byte_allocator =
typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
216 byte_allocator byte_alloc(size_pair_.get_base());
217 allocator_traits<byte_allocator>::deallocate(byte_alloc,
static_cast<byte_t*
>(mem_), size_pair_.value);
226struct enable_shared_from_this;
238void __setup_enable_shared_from_impl(T* ptr, __smart_ptr_counter* owner, true_type )
noexcept {
240 static_cast<enable_shared_from_this<T>*
>(ptr)->owner_ = owner;
245void __setup_enable_shared_from_impl(T* , __smart_ptr_counter* , false_type )
noexcept {}
248void __setup_enable_shared_from(T* ptr, __smart_ptr_counter* owner)
noexcept {
249 inner::__setup_enable_shared_from_impl(ptr, owner, is_base_of<enable_shared_from_this<T>, T>{});
253shared_ptr<T> __make_shared_fused(T* ptr, __smart_ptr_counter* owner)
noexcept {
254 return shared_ptr<T>(ptr, owner);
275 using owner_type = inner::__smart_ptr_counter;
277 template <
typename U,
typename Deleter>
278 using owner_deleter = inner::__smart_ptr_counter_impl<U, Deleter>;
280 template <
typename U>
281 using owner_default = inner::__smart_ptr_counter_impl<U, default_deleter<U>>;
284 owner_type* owner_ =
nullptr;
291 explicit shared_ptr(T* ptr, owner_type* owner) noexcept :
295 template <
typename U>
298 template <
typename U>
301 template <
typename U>
302 friend class inner::smart_pointer_atomic;
304 template <
typename U>
305 friend shared_ptr<U> inner::__make_shared_fused(U*, inner::__smart_ptr_counter*)
noexcept;
321 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
324 owner_(new owner_default<U>(ptr)) {
325 inner::__setup_enable_shared_from(ptr_, owner_);
335 template <
typename U,
typename Deleter, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
338 owner_(new owner_deleter<U, Deleter>(ptr_, _NEFORCE
forward<Deleter>(deleter))) {
339 inner::__setup_enable_shared_from(ptr_, owner_);
348 template <
typename U,
typename Deleter, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
358 owner_(other.owner_) {
359 if (owner_ !=
nullptr) {
360 owner_->incref_strong();
369 shared_ptr&
operator=(
const shared_ptr& other)
noexcept {
373 if (owner_ !=
nullptr) {
374 owner_->decref_strong();
377 owner_ = other.owner_;
378 if (owner_ !=
nullptr) {
379 owner_->incref_strong();
389 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
392 owner_(other.owner_) {
394 owner_->incref_strong();
404 owner_(other.owner_) {
405 other.ptr_ =
nullptr;
406 other.owner_ =
nullptr;
418 if (owner_ !=
nullptr) {
419 owner_->decref_strong();
422 owner_ = other.owner_;
423 other.ptr_ =
nullptr;
424 other.owner_ =
nullptr;
433 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
436 owner_(other.owner_) {
437 other.ptr_ =
nullptr;
438 other.owner_ =
nullptr;
448 template <
typename U>
451 owner_(other.owner_) {
453 owner_->incref_strong();
460 template <
typename U>
463 owner_(other.owner_) {
464 other.ptr_ =
nullptr;
465 other.owner_ =
nullptr;
471 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
472 shared_ptr&
operator=(
const shared_ptr<U>& other)
noexcept {
474 owner_->decref_strong();
477 owner_ = other.owner_;
479 owner_->incref_strong();
487 template <
typename U, enable_if_t<is_convertible_v<U*, T*>,
int> = 0>
490 owner_->decref_strong();
493 owner_ = other.owner_;
494 other.ptr_ =
nullptr;
495 other.owner_ =
nullptr;
509 if (owner_ !=
nullptr) {
510 owner_->decref_strong();
521 template <
typename U>
524 owner_->decref_strong();
529 owner_ =
new owner_default<U>(ptr_);
530 inner::__setup_enable_shared_from<T>(ptr_, owner_);
540 template <
typename U,
typename Deleter>
541 void reset(U* ptr, Deleter deleter) {
543 owner_->decref_strong();
548 owner_ =
new owner_deleter<U, Deleter>(ptr_, _NEFORCE
move(deleter));
549 inner::__setup_enable_shared_from<T>(ptr_, owner_);
556 NEFORCE_NODISCARD
long use_count() const noexcept {
return owner_ !=
nullptr ? owner_->use_count() : 0; }
562 NEFORCE_NODISCARD
bool unique() const noexcept {
return owner_ !=
nullptr ? owner_->use_count() == 1 :
true; }
568 void swap(shared_ptr& other)
noexcept {
572 _NEFORCE
swap(ptr_, other.ptr_);
573 _NEFORCE
swap(owner_, other.owner_);
580 NEFORCE_NODISCARD T*
get() const noexcept {
return ptr_; }
586 NEFORCE_NODISCARD T*
operator->() const noexcept {
return ptr_; }
598 NEFORCE_NODISCARD
explicit operator bool() const noexcept {
return ptr_ !=
nullptr; }
606 template <
typename U>
607 NEFORCE_NODISCARD
bool owner_equal(
const shared_ptr<U>& rhs)
const noexcept {
608 return owner_ == rhs.owner_;
614 template <
typename U>
615 NEFORCE_NODISCARD
bool owner_equal(
const weak_ptr<U>& rhs)
const noexcept {
616 return owner_ == rhs.owner_;
625 template <
typename U>
626 NEFORCE_NODISCARD
bool owner_before(
const shared_ptr<U>& rhs)
const noexcept {
627 return owner_ < rhs.owner_;
633 template <
typename U>
634 NEFORCE_NODISCARD
bool owner_before(
const weak_ptr<U>& rhs)
const noexcept {
635 return owner_ < rhs.owner_;
642template <
typename T,
typename U>
644 return lhs.owner_equal(rhs);
650template <
typename T,
typename U>
652 return !(lhs == rhs);
658template <
typename T,
typename U>
660 return lhs.owner_before(rhs);
666template <
typename T,
typename U>
674template <
typename T,
typename U>
682template <
typename T,
typename U>
695 return lhs.get() ==
nullptr;
706 return rhs.get() ==
nullptr;
717 return lhs.get() !=
nullptr;
728 return rhs.get() !=
nullptr;
737class shared_ptr<T[]> : shared_ptr<T> {
739 using shared_ptr<T>::shared_ptr;
760 mutable inner::__smart_ptr_counter* owner_ =
nullptr;
762 template <
typename U>
763 friend void inner::__setup_enable_shared_from_impl(U* ptr, inner::__smart_ptr_counter* owner,
true_type)
noexcept;
765 template <
typename U>
766 friend void inner::__setup_enable_shared_from(U*, inner::__smart_ptr_counter*)
noexcept;
768 template <
typename U>
769 friend class shared_ptr;
771 template <
typename U>
772 friend class weak_ptr;
788 if (owner_ ==
nullptr) {
791 owner_->incref_strong();
792 return inner::__make_shared_fused(
static_cast<T*
>(
this), owner_);
802 if (owner_ ==
nullptr) {
805 owner_->incref_strong();
806 return inner::__make_shared_fused(
static_cast<const T*
>(
this), owner_);
821 weak_ptr<const T> weak_from_this() const noexcept;
835NEFORCE_INLINE17
constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;
848template <
typename T,
typename... Args>
851 using Counter = inner::__smart_ptr_counter_impl_fused<T,
decltype(deleter)>;
852 constexpr size_t align =
max(
alignof(T),
alignof(Counter));
853 constexpr size_t offset = (
sizeof(Counter) + align - 1) & ~(align - 1);
854 constexpr size_t size = offset +
sizeof(T);
855#if NEFORCE_STANDARD_17
856 void* mem =
operator new(
size, std::align_val_t{align});
857 auto* counter =
static_cast<Counter*
>(mem);
859 void* mem =
operator new(
size + align - 1);
860 size_t aligned_addr = (
reinterpret_cast<size_t>(mem) + (align - 1)) & ~(align - 1);
861 Counter* counter =
reinterpret_cast<Counter*
>(aligned_addr);
863 T*
object =
reinterpret_cast<T*
>(
reinterpret_cast<byte_t*
>(counter) + offset);
867#if NEFORCE_STANDARD_17
868 operator delete(mem, std::align_val_t{align});
870 operator delete(mem);
872 NEFORCE_THROW_EXCEPTION(
memory_exception(
"shared ptr construction failed."));
874 _NEFORCE
construct(
reinterpret_cast<Counter*
>(counter),
object, mem, align, _NEFORCE
move(deleter));
875 inner::__setup_enable_shared_from(
object, counter);
876 return inner::__make_shared_fused(
object, counter);
889 value* tmp =
nullptr;
891 tmp =
new value[len];
894 operator delete[](tmp);
895 NEFORCE_THROW_EXCEPTION(
memory_exception(
"shared ptr construction failed."));
912template <
typename T,
typename Alloc,
typename... Args>
915 auto deleter = [](T* p) { p->~T(); };
916 using ControlBlock = inner::__smart_ptr_counter_impl_allocated<T,
decltype(deleter), Alloc>;
918 const size_t align = _NEFORCE
max(
alignof(ControlBlock),
alignof(T));
919 const size_t offset = (
sizeof(ControlBlock) + align - 1) & ~(align - 1);
920 const size_t total_size = offset +
sizeof(T);
921 const size_t raw_size = total_size + align - 1;
924 using byte_allocator =
typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
925 byte_allocator byte_alloc(alloc);
929 const auto raw_addr =
reinterpret_cast<uintptr_t>(raw_mem);
930 const uintptr_t aligned_addr = (raw_addr + align - 1) & ~
static_cast<uintptr_t>(align - 1);
931 auto* aligned_mem =
reinterpret_cast<byte_t*
>(aligned_addr);
932 T* object_ptr =
reinterpret_cast<T*
>(aligned_mem + offset);
938 NEFORCE_THROW_EXCEPTION(
memory_exception(
"shared ptr ref object construction failed."));
941 ControlBlock* ctrl_block =
nullptr;
943 ctrl_block = _NEFORCE
construct(
reinterpret_cast<ControlBlock*
>(aligned_mem), object_ptr, raw_mem, raw_size,
948 NEFORCE_THROW_EXCEPTION(
memory_exception(
"shared ptr control block construction failed."));
951 inner::__setup_enable_shared_from(object_ptr, ctrl_block);
952 return inner::__make_shared_fused(object_ptr, ctrl_block);
963template <
typename T,
typename U>
975template <
typename T,
typename U>
987template <
typename T,
typename U>
999template <
typename T,
typename U>
1001 T* tmp =
dynamic_cast<T*
>(ptr.
get());
1002 if (tmp !=
nullptr) {
1019template <
typename T>
1021 NEFORCE_CONSTEXPR20
size_t operator()(
const shared_ptr<T>& ptr)
const
1030NEFORCE_BEGIN_INNER__
1032template <
typename T>
1033class smart_pointer_atomic {
1035 using value_type = T;
1038 struct atomic_counter {
1040 using count_type = inner::__smart_ptr_counter;
1045 static constexpr uintptr_t lock_bit{1};
1047 static void dereference(count_type* counter, true_type )
noexcept { counter->decref_strong(); }
1049 static void dereference(count_type* counter, false_type )
noexcept { counter->decref_weak(); }
1052 constexpr atomic_counter() noexcept = default;
1054 explicit atomic_counter(count_type* counter) noexcept :
1055 value_(reinterpret_cast<uintptr_t>(counter)) {
1060 auto value = value_.
load(memory_order_relaxed);
1062 if (
auto* counter =
reinterpret_cast<count_type*
>(value)) {
1063 this->dereference(counter, is_shared_ptr<T>());
1067 atomic_counter(
const atomic_counter&) =
delete;
1068 atomic_counter& operator=(
const atomic_counter&) =
delete;
1070 count_type* lock(memory_order mo)
const noexcept {
1071 if (mo != memory_order_seq_cst) {
1074 auto cur = value_.
load(memory_order_relaxed);
1075 while ((cur & lock_bit) != 0U) {
1076 this_thread::relax();
1077 cur = value_.
load(memory_order_relaxed);
1081 this_thread::relax();
1082 cur = cur & ~lock_bit;
1084 return reinterpret_cast<count_type*
>(cur);
1087 void unlock(memory_order mo)
const noexcept { value_.
fetch_sub(1, mo); }
1089 count_type* swap_unlock(count_type* counter, memory_order mo)
noexcept {
1090 if (mo != memory_order_seq_cst) {
1093 auto addr =
reinterpret_cast<uintptr_t>(counter);
1095 return reinterpret_cast<count_type*
>(addr & ~lock_bit);
1098 void wait_unlock(memory_order mo)
const noexcept {
1099 const auto old_value = value_.
load(memory_order_relaxed);
1100 const auto unlocked = old_value & ~lock_bit;
1101 value_.
fetch_sub(1, memory_order_release);
1102 if (value_.
load(memory_order_acquire) == unlocked) {
1103 value_.
wait(unlocked, mo);
1107 void notify_one() noexcept { value_.
notify_one(); }
1109 void notify_all() noexcept { value_.
notify_all(); }
1112 typename T::element_type* ptr_ =
nullptr;
1113 atomic_counter refcount_;
1115 friend struct atomic<T>;
1118 static typename atomic_counter::count_type* incref(
typename atomic_counter::count_type* counter,
1121 counter->incref_strong();
1126 static typename atomic_counter::count_type* incref(
typename atomic_counter::count_type* counter,
1129 counter->incref_weak();
1135 constexpr smart_pointer_atomic() noexcept = default;
1137 explicit smart_pointer_atomic(value_type value) noexcept :
1139 refcount_(value.owner_) {
1140 value.owner_ =
nullptr;
1141 value.ptr_ =
nullptr;
1144 ~smart_pointer_atomic() =
default;
1146 smart_pointer_atomic(
const smart_pointer_atomic&) =
delete;
1147 void operator=(
const smart_pointer_atomic&) =
delete;
1149 value_type load(memory_order mo)
const noexcept {
1151 if (mo != memory_order_seq_cst) {
1156 auto counter = refcount_.lock(mo);
1158 value.owner_ = this->incref(counter, is_shared_ptr<T>());
1159 refcount_.unlock(memory_order_relaxed);
1163 void swap(value_type& value, memory_order mo)
noexcept {
1164 refcount_.lock(memory_order_acquire);
1165 _NEFORCE
swap(ptr_, value.ptr_);
1166 auto* old_owner = refcount_.swap_unlock(value.owner_, mo);
1167 value.owner_ = old_owner;
1170 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo1,
1171 memory_order mo2)
noexcept {
1173 auto* counter = refcount_.lock(memory_order_acquire);
1174 if (ptr_ == expected.ptr_ && counter == expected.owner_) {
1175 ptr_ = desired.ptr_;
1176 auto* old_owner = refcount_.swap_unlock(desired.owner_, mo1);
1177 desired.owner_ = old_owner;
1179 auto* new_counter = this->incref(counter, is_shared_ptr<T>());
1180 refcount_.unlock(mo2);
1181 expected.ptr_ = ptr_;
1182 expected.owner_ = new_counter;
1188 void wait(value_type mold, memory_order mo)
const noexcept {
1189 auto* counter = refcount_.lock(memory_order_acquire);
1190 if (ptr_ == mold.ptr_ && counter == mold.owner_) {
1191 refcount_.wait_unlock(mo);
1193 refcount_.unlock(memory_order_relaxed);
1197 void notify_one() noexcept { refcount_.notify_one(); }
1199 void notify_all() noexcept { refcount_.notify_all(); }
1217template <
typename T>
1222 static constexpr bool is_always_lock_free =
false;
1225 inner::smart_pointer_atomic<value_type> atomic_;
1244 atomic_(
move(value)) {}
1247 void operator=(
const atomic&) =
delete;
1285 atomic_.swap(desired, mo);
1293 return atomic_.compare_exchange_strong(expected, desired, mo, mo2);
1337NEFORCE_END_NAMESPACE__
add_lvalue_reference_t< T > operator[](size_t idx)
数组下标运算符
void reset(U *ptr)
重置共享指针并管理新对象
T * operator->() const noexcept
指针解引用运算符
shared_ptr & operator=(const shared_ptr &other) noexcept
拷贝赋值运算符
long use_count() const noexcept
获取引用计数
void swap(shared_ptr &other) noexcept
交换两个共享指针
shared_ptr & operator=(const shared_ptr< U > &other) noexcept
类型转换拷贝赋值运算符
shared_ptr & operator=(shared_ptr &&other) noexcept
移动赋值运算符
bool owner_equal(const shared_ptr< U > &rhs) const noexcept
检查所有权是否相等
shared_ptr(shared_ptr &&other) noexcept
移动构造函数
~shared_ptr() noexcept
析构函数
shared_ptr(const shared_ptr &other) noexcept
拷贝构造函数
shared_ptr(U *ptr, Deleter &&deleter)
从原始指针和自定义删除器构造函数
shared_ptr(shared_ptr< U > &&other) noexcept
类型转换移动构造函数
shared_ptr(shared_ptr< U > &&other, T *ptr) noexcept
移动别名构造函数
T * get() const noexcept
获取原始指针
shared_ptr(const shared_ptr< U > &other) noexcept
类型转换拷贝构造函数
bool owner_before(const shared_ptr< U > &rhs) const noexcept
比较所有权顺序
shared_ptr & operator=(shared_ptr< U > &&other) noexcept
类型转换移动赋值运算符
add_lvalue_reference_t< T > operator*() const noexcept
解引用运算符
void reset(U *ptr, Deleter deleter)
带自定义删除器重置共享指针并管理新对象
bool owner_equal(const weak_ptr< U > &rhs) const noexcept
与弱指针检查所有权是否相等
shared_ptr(nullptr_t np=nullptr) noexcept
默认构造函数
shared_ptr(U *ptr)
从原始指针构造函数
periodic_task_state element_type
bool owner_before(const weak_ptr< U > &rhs) const noexcept
与弱指针比较所有权顺序
bool unique() const noexcept
shared_ptr(unique_ptr< U, Deleter > &&unique)
独享智能指针构造函数
shared_ptr(const shared_ptr< U > &other, T *ptr) noexcept
从共享指针和别名指针别名构造函数
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr bool is_base_of_v
is_base_of的便捷变量模板
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
unsigned char byte_t
字节类型,定义为无符号字符
unsigned long uint64_t
64位无符号整数类型
decltype(nullptr) nullptr_t
空指针类型
void unreachable() noexcept
标记不可达代码路径
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
constexpr auto memory_order_acquire
获取内存顺序常量
@ release
释放操作,确保前面的读写不会被重排到后面
typename remove_extent< T >::type remove_extent_t
remove_extent的便捷别名
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类型转换
enable_if_t<!is_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > allocate_shared(Alloc &alloc, Args &&... args)
使用分配器创建共享指针
enable_if_t<!is_unbounded_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > make_shared(Args &&... args)
融合分配创建共享指针
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr bool is_constructible_v
is_constructible的便捷变量模板
constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
bool_constant< false > false_type
表示false的类型
bool_constant< true > true_type
表示true的类型
void swap(unique_ptr< T, Deleter > &lhs, unique_ptr< T, Deleter > &rhs) noexcept
交换两个unique_ptr
static constexpr void construct(Alloc &alloc, T *ptr, Args &&... args) noexcept(noexcept(allocator_traits::__construct_aux(alloc, ptr, _NEFORCE forward< Args >(args)...)))
在已分配内存上构造对象
static constexpr void deallocate(Alloc &alloc, pointer ptr, size_type n)
释放内存
static constexpr void destroy(Alloc &alloc, T *ptr) noexcept(noexcept(allocator_traits::__destroy_aux(alloc, ptr, 0)))
销毁对象
static constexpr pointer allocate(Alloc &alloc, size_type n)
分配内存
value_type exchange(value_type desired, memory_order mo=memory_order_seq_cst) noexcept
交换操作
void operator=(value_type desired) noexcept
赋值操作符
value_type load(memory_order mo=memory_order_seq_cst) const noexcept
原子加载
void operator=(nullptr_t) noexcept
赋空值操作符
void wait(value_type mold, memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
atomic(value_type value) noexcept
从shared_ptr构造
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order mo=memory_order_seq_cst) noexcept
简化比较交换强版本
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order mo=memory_order_seq_cst) noexcept
简化比较交换弱版本
void store(value_type desired, memory_order mo=memory_order_seq_cst) noexcept
原子存储
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order mo, memory_order mo2) noexcept
比较交换强版本
constexpr atomic(nullptr_t=nullptr) noexcept
默认构造函数
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order mo, memory_order mo2) noexcept
比较交换弱版本
void notify_one() noexcept
通知一个等待者
bool is_lock_free() const noexcept
检查是否无锁
void notify_all() noexcept
通知所有等待者
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void notify_one() noexcept
通知一个等待线程
void notify_all() noexcept
通知所有等待线程
value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
shared_ptr< T > shared_from_this()
获取指向自身的共享指针
shared_ptr< const T > shared_from_this() const
获取指向自身的常量共享指针
enable_shared_from_this() noexcept=default
构造函数