NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
shared_ptr.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_MEMORY_SHARED_PTR_HPP__
2#define NEFORCE_CORE_MEMORY_SHARED_PTR_HPP__
3
11
12#include <new>
18NEFORCE_BEGIN_NAMESPACE__
19
25
27NEFORCE_BEGIN_INNER__
28
29template <typename T>
30class smart_pointer_atomic;
31
32
39struct __smart_ptr_counter {
40public:
41 atomic<unsigned long> strong_count_;
42 atomic<unsigned long> weak_count_;
43
44protected:
48 virtual void delete_object() = 0;
49
53 virtual void delete_this() = 0;
54
55public:
60 __smart_ptr_counter() noexcept :
61 strong_count_(1),
62 weak_count_(1) {}
63
64 __smart_ptr_counter(__smart_ptr_counter&&) = delete;
65
66 virtual ~__smart_ptr_counter() = default;
67
71 void incref_strong() noexcept { strong_count_.fetch_add(1, memory_order_relaxed); }
72
76 void incref_weak() noexcept { weak_count_.fetch_add(1, memory_order_relaxed); }
77
82 void decref_strong() noexcept {
83 if (strong_count_.fetch_sub(1, memory_order_acq_rel) == 1) {
84 delete_object();
85 decref_weak();
86 }
87 }
88
93 void decref_weak() noexcept {
94 if (weak_count_.fetch_sub(1, memory_order_acq_rel) == 1) {
95 delete_this();
96 }
97 }
98
105 bool try_incref_strong() noexcept {
106 auto strong = strong_count_.load(memory_order_relaxed);
107 do {
108 if (strong == 0) {
109 return false;
110 }
111 } while (!strong_count_.compare_exchange_weak(strong, strong + 1, memory_order_release, memory_order_relaxed));
112 return true;
113 }
114
119 NEFORCE_NODISCARD uint64_t use_count() const noexcept { return strong_count_.load(memory_order_relaxed); }
120
125 NEFORCE_NODISCARD uint64_t weak_count() const noexcept { return weak_count_.load(memory_order_relaxed); }
126};
127
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};
138
139 static_assert(is_invocable_v<Deleter, T*>, "Deleter must be invocable by T*");
140
141 explicit __smart_ptr_counter_impl(T* ptr) noexcept(is_nothrow_default_constructible_v<Deleter>) :
142 ptr_pair_(default_construct_tag{}, ptr) {}
143
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) {}
147
148 void delete_object() override {
149 ptr_pair_.get_base()(ptr_pair_.value);
150 ptr_pair_.value = nullptr;
151 }
152
153 void delete_this() noexcept override { delete this; }
154};
155
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};
166 size_t align_;
167 void* mem_;
168
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),
171 align_(align),
172 mem_(mem) {}
173
174 void delete_object() noexcept override {
175 ptr_pair_.get_base()(ptr_pair_.value);
176 ptr_pair_.value = nullptr;
177 }
178
179 void delete_this() noexcept override {
180#if NEFORCE_STANDARD_17
181 operator delete(mem_, std::align_val_t{align_});
182#else
183 operator delete(mem_);
184#endif
185 }
186};
187
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};
200 void* mem_;
201
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),
206 mem_(mem) {}
207
208 void delete_object() noexcept override {
209 ptr_pair_.get_base()(ptr_pair_.value);
210 ptr_pair_.value = nullptr;
211 }
212
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);
218 }
219};
220
221NEFORCE_END_INNER__
223
224
225template <typename T>
227
228template <typename T>
229class shared_ptr;
230
231template <typename T>
232class weak_ptr;
233
235NEFORCE_BEGIN_INNER__
236
237template <typename T>
238void __setup_enable_shared_from_impl(T* ptr, __smart_ptr_counter* owner, true_type /*unused*/) noexcept {
239 if (ptr) {
240 static_cast<enable_shared_from_this<T>*>(ptr)->owner_ = owner;
241 }
242}
243
244template <typename T>
245void __setup_enable_shared_from_impl(T* /*unused*/, __smart_ptr_counter* /*unused*/, false_type /*unused*/) noexcept {}
246
247template <typename T>
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>{});
250}
251
252template <typename T>
253shared_ptr<T> __make_shared_fused(T* ptr, __smart_ptr_counter* owner) noexcept {
254 return shared_ptr<T>(ptr, owner);
255}
256
257NEFORCE_END_INNER__
259
260
269template <typename T>
270class shared_ptr {
271public:
272 using element_type = T;
273
274private:
275 using owner_type = inner::__smart_ptr_counter;
276
277 template <typename U, typename Deleter>
278 using owner_deleter = inner::__smart_ptr_counter_impl<U, Deleter>;
279
280 template <typename U>
281 using owner_default = inner::__smart_ptr_counter_impl<U, default_deleter<U>>;
282
283 element_type* ptr_ = nullptr;
284 owner_type* owner_ = nullptr;
285
291 explicit shared_ptr(T* ptr, owner_type* owner) noexcept :
292 ptr_(ptr),
293 owner_(owner) {}
294
295 template <typename U>
296 friend class shared_ptr;
297
298 template <typename U>
299 friend class weak_ptr;
300
301 template <typename U>
302 friend class inner::smart_pointer_atomic;
303
304 template <typename U>
305 friend shared_ptr<U> inner::__make_shared_fused(U*, inner::__smart_ptr_counter*) noexcept;
306
307public:
314 shared_ptr(nullptr_t np = nullptr) noexcept {}
315
321 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
322 shared_ptr(U* ptr) :
323 ptr_(ptr),
324 owner_(new owner_default<U>(ptr)) {
325 inner::__setup_enable_shared_from(ptr_, owner_);
326 }
327
335 template <typename U, typename Deleter, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
336 explicit shared_ptr(U* ptr, Deleter&& deleter) :
337 ptr_(ptr),
338 owner_(new owner_deleter<U, Deleter>(ptr_, _NEFORCE forward<Deleter>(deleter))) {
339 inner::__setup_enable_shared_from(ptr_, owner_);
340 }
341
348 template <typename U, typename Deleter, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
350 shared_ptr(unique.release(), unique.get_deleter()) {}
351
356 shared_ptr(const shared_ptr& other) noexcept :
357 ptr_(other.ptr_),
358 owner_(other.owner_) {
359 if (owner_ != nullptr) {
360 owner_->incref_strong();
361 }
362 }
363
369 shared_ptr& operator=(const shared_ptr& other) noexcept {
370 if (_NEFORCE addressof(other) == this) {
371 return *this;
372 }
373 if (owner_ != nullptr) {
374 owner_->decref_strong();
375 }
376 ptr_ = other.ptr_;
377 owner_ = other.owner_;
378 if (owner_ != nullptr) {
379 owner_->incref_strong();
380 }
381 return *this;
382 }
383
389 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
390 shared_ptr(const shared_ptr<U>& other) noexcept :
391 ptr_(other.ptr_),
392 owner_(other.owner_) {
393 if (owner_) {
394 owner_->incref_strong();
395 }
396 }
397
402 shared_ptr(shared_ptr&& other) noexcept :
403 ptr_(other.ptr_),
404 owner_(other.owner_) {
405 other.ptr_ = nullptr;
406 other.owner_ = nullptr;
407 }
408
414 shared_ptr& operator=(shared_ptr&& other) noexcept {
415 if (_NEFORCE addressof(other) == this) {
416 return *this;
417 }
418 if (owner_ != nullptr) {
419 owner_->decref_strong();
420 }
421 ptr_ = other.ptr_;
422 owner_ = other.owner_;
423 other.ptr_ = nullptr;
424 other.owner_ = nullptr;
425 return *this;
426 }
427
433 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
434 explicit shared_ptr(shared_ptr<U>&& other) noexcept :
435 ptr_(other.ptr_),
436 owner_(other.owner_) {
437 other.ptr_ = nullptr;
438 other.owner_ = nullptr;
439 }
440
448 template <typename U>
449 shared_ptr(const shared_ptr<U>& other, T* ptr) noexcept :
450 ptr_(ptr),
451 owner_(other.owner_) {
452 if (owner_) {
453 owner_->incref_strong();
454 }
455 }
456
460 template <typename U>
461 shared_ptr(shared_ptr<U>&& other, T* ptr) noexcept :
462 ptr_(ptr),
463 owner_(other.owner_) {
464 other.ptr_ = nullptr;
465 other.owner_ = nullptr;
466 }
467
471 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
472 shared_ptr& operator=(const shared_ptr<U>& other) noexcept {
473 if (owner_) {
474 owner_->decref_strong();
475 }
476 ptr_ = other.ptr_;
477 owner_ = other.owner_;
478 if (owner_) {
479 owner_->incref_strong();
480 }
481 return *this;
482 }
483
487 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
488 shared_ptr& operator=(shared_ptr<U>&& other) noexcept {
489 if (owner_) {
490 owner_->decref_strong();
491 }
492 ptr_ = other.ptr_;
493 owner_ = other.owner_;
494 other.ptr_ = nullptr;
495 other.owner_ = nullptr;
496 return *this;
497 }
498
503 ~shared_ptr() noexcept { reset(); }
504
508 void reset() noexcept {
509 if (owner_ != nullptr) {
510 owner_->decref_strong();
511 }
512 owner_ = nullptr;
513 ptr_ = nullptr;
514 }
515
521 template <typename U>
522 void reset(U* ptr) {
523 if (owner_) {
524 owner_->decref_strong();
525 }
526 ptr_ = nullptr;
527 owner_ = nullptr;
528 ptr_ = ptr;
529 owner_ = new owner_default<U>(ptr_);
530 inner::__setup_enable_shared_from<T>(ptr_, owner_);
531 }
532
540 template <typename U, typename Deleter>
541 void reset(U* ptr, Deleter deleter) {
542 if (owner_) {
543 owner_->decref_strong();
544 }
545 ptr_ = nullptr;
546 owner_ = nullptr;
547 ptr_ = ptr;
548 owner_ = new owner_deleter<U, Deleter>(ptr_, _NEFORCE move(deleter));
549 inner::__setup_enable_shared_from<T>(ptr_, owner_);
550 }
551
556 NEFORCE_NODISCARD long use_count() const noexcept { return owner_ != nullptr ? owner_->use_count() : 0; }
557
562 NEFORCE_NODISCARD bool unique() const noexcept { return owner_ != nullptr ? owner_->use_count() == 1 : true; }
563
568 void swap(shared_ptr& other) noexcept {
569 if (_NEFORCE addressof(other) == this) {
570 return;
571 }
572 _NEFORCE swap(ptr_, other.ptr_);
573 _NEFORCE swap(owner_, other.owner_);
574 }
575
580 NEFORCE_NODISCARD T* get() const noexcept { return ptr_; }
581
586 NEFORCE_NODISCARD T* operator->() const noexcept { return ptr_; }
587
592 NEFORCE_NODISCARD add_lvalue_reference_t<T> operator*() const noexcept { return *ptr_; }
593
598 NEFORCE_NODISCARD explicit operator bool() const noexcept { return ptr_ != nullptr; }
599
606 template <typename U>
607 NEFORCE_NODISCARD bool owner_equal(const shared_ptr<U>& rhs) const noexcept {
608 return owner_ == rhs.owner_;
609 }
610
614 template <typename U>
615 NEFORCE_NODISCARD bool owner_equal(const weak_ptr<U>& rhs) const noexcept {
616 return owner_ == rhs.owner_;
617 }
618
625 template <typename U>
626 NEFORCE_NODISCARD bool owner_before(const shared_ptr<U>& rhs) const noexcept {
627 return owner_ < rhs.owner_;
628 }
629
633 template <typename U>
634 NEFORCE_NODISCARD bool owner_before(const weak_ptr<U>& rhs) const noexcept {
635 return owner_ < rhs.owner_;
636 }
637};
638
642template <typename T, typename U>
643NEFORCE_NODISCARD bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
644 return lhs.owner_equal(rhs);
645}
646
650template <typename T, typename U>
651NEFORCE_NODISCARD bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
652 return !(lhs == rhs);
653}
654
658template <typename T, typename U>
659NEFORCE_NODISCARD bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
660 return lhs.owner_before(rhs);
661}
662
666template <typename T, typename U>
667NEFORCE_NODISCARD bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
668 return rhs < lhs;
669}
670
674template <typename T, typename U>
675NEFORCE_NODISCARD bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
676 return !(lhs > rhs);
677}
678
682template <typename T, typename U>
683NEFORCE_NODISCARD bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
684 return !(lhs < rhs);
685}
686
693template <typename T>
694NEFORCE_NODISCARD bool operator==(const shared_ptr<T>& lhs, nullptr_t np) noexcept {
695 return lhs.get() == nullptr;
696}
697
704template <typename T>
705NEFORCE_NODISCARD bool operator==(nullptr_t np, const shared_ptr<T>& rhs) noexcept {
706 return rhs.get() == nullptr;
707}
708
715template <typename T>
716NEFORCE_NODISCARD bool operator!=(const shared_ptr<T>& lhs, nullptr_t np) noexcept {
717 return lhs.get() != nullptr;
718}
719
726template <typename T>
727NEFORCE_NODISCARD bool operator!=(nullptr_t np, const shared_ptr<T>& rhs) noexcept {
728 return rhs.get() != nullptr;
729}
730
731
736template <typename T>
737class shared_ptr<T[]> : shared_ptr<T> {
738public:
739 using shared_ptr<T>::shared_ptr;
740
746 add_lvalue_reference_t<T> operator[](size_t idx) { return this->get()[idx]; }
747};
748
749
757template <typename T>
759private:
760 mutable inner::__smart_ptr_counter* owner_ = nullptr;
761
762 template <typename U>
763 friend void inner::__setup_enable_shared_from_impl(U* ptr, inner::__smart_ptr_counter* owner, true_type) noexcept;
764
765 template <typename U>
766 friend void inner::__setup_enable_shared_from(U*, inner::__smart_ptr_counter*) noexcept;
767
768 template <typename U>
769 friend class shared_ptr;
770
771 template <typename U>
772 friend class weak_ptr;
773
774protected:
778 enable_shared_from_this() noexcept = default;
779
780public:
786 shared_ptr<T> shared_from_this() {
787 static_assert(is_base_of_v<enable_shared_from_this, T>, "shared from T requires derived class");
788 if (owner_ == nullptr) {
789 NEFORCE_THROW_EXCEPTION(memory_exception("smart pointer share failed."));
790 }
791 owner_->incref_strong();
792 return inner::__make_shared_fused(static_cast<T*>(this), owner_);
793 }
794
800 shared_ptr<const T> shared_from_this() const {
801 static_assert(is_base_of_v<enable_shared_from_this, T>, "shared from T requires derived class");
802 if (owner_ == nullptr) {
803 NEFORCE_THROW_EXCEPTION(memory_exception("smart pointer share failed."));
804 }
805 owner_->incref_strong();
806 return inner::__make_shared_fused(static_cast<const T*>(this), owner_);
807 }
808};
809
810
814template <typename T>
816
817template <typename T>
818struct is_shared_ptr<shared_ptr<T>> : true_type {};
819
820template <typename T>
821NEFORCE_INLINE17 constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;
822
823
834template <typename T, typename... Args>
836 auto const deleter = [](T* ptr) noexcept(is_nothrow_destructible_v<T>) { ptr->~T(); };
837 using Counter = inner::__smart_ptr_counter_impl_fused<T, decltype(deleter)>;
838 constexpr size_t align = max(alignof(T), alignof(Counter));
839 constexpr size_t offset = (sizeof(Counter) + align - 1) & ~(align - 1);
840 constexpr size_t size = offset + sizeof(T);
841#if NEFORCE_STANDARD_17
842 void* mem = operator new(size, std::align_val_t{align});
843 auto* counter = static_cast<Counter*>(mem);
844#else
845 void* mem = operator new(size + align - 1);
846 size_t aligned_addr = (reinterpret_cast<size_t>(mem) + (align - 1)) & ~(align - 1);
847 Counter* counter = reinterpret_cast<Counter*>(aligned_addr);
848#endif
849 T* object = reinterpret_cast<T*>(reinterpret_cast<byte_t*>(counter) + offset);
850 try {
851 _NEFORCE construct(object, _NEFORCE forward<Args>(args)...);
852 } catch (...) {
853#if NEFORCE_STANDARD_17
854 operator delete(mem, std::align_val_t{align});
855#else
856 operator delete(mem);
857#endif
858 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr construction failed."));
859 }
860 _NEFORCE construct(reinterpret_cast<Counter*>(counter), object, mem, align, _NEFORCE move(deleter));
861 inner::__setup_enable_shared_from(object, counter);
862 return inner::__make_shared_fused(object, counter);
863}
864
872template <typename T>
874 using value = remove_extent_t<T>;
875 value* tmp = nullptr;
876 try {
877 tmp = new value[len];
878 return shared_ptr<value[]>(tmp, default_deleter<value[]>{});
879 } catch (...) {
880 operator delete[](tmp);
881 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr construction failed."));
882 }
883 unreachable();
884}
885
898template <typename T, typename Alloc, typename... Args>
900 Args&&... args) {
901 auto deleter = [](T* p) { p->~T(); };
902 using ControlBlock = inner::__smart_ptr_counter_impl_allocated<T, decltype(deleter), Alloc>;
903
904 const size_t align = _NEFORCE max(alignof(ControlBlock), alignof(T));
905 const size_t offset = (sizeof(ControlBlock) + align - 1) & ~(align - 1);
906 const size_t total_size = offset + sizeof(T);
907 const size_t raw_size = total_size + align - 1;
908
909 using alloc_traits = allocator_traits<remove_cv_t<Alloc>>;
910 using byte_allocator = typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
911 byte_allocator byte_alloc(alloc);
912
913 byte_t* raw_mem = allocator_traits<byte_allocator>::allocate(byte_alloc, raw_size);
914
915 const auto raw_addr = reinterpret_cast<uintptr_t>(raw_mem);
916 const uintptr_t aligned_addr = (raw_addr + align - 1) & ~static_cast<uintptr_t>(align - 1);
917 auto* aligned_mem = reinterpret_cast<byte_t*>(aligned_addr);
918 T* object_ptr = reinterpret_cast<T*>(aligned_mem + offset);
919
920 try {
921 allocator_traits<Alloc>::construct(alloc, object_ptr, _NEFORCE forward<Args>(args)...);
922 } catch (...) {
923 allocator_traits<byte_allocator>::deallocate(byte_alloc, raw_mem, raw_size);
924 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr ref object construction failed."));
925 }
926
927 ControlBlock* ctrl_block = nullptr;
928 try {
929 ctrl_block = _NEFORCE construct(reinterpret_cast<ControlBlock*>(aligned_mem), object_ptr, raw_mem, raw_size,
930 deleter, alloc);
931 } catch (...) {
932 allocator_traits<Alloc>::destroy(alloc, object_ptr);
933 allocator_traits<byte_allocator>::deallocate(byte_alloc, raw_mem, raw_size);
934 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr control block construction failed."));
935 }
936
937 inner::__setup_enable_shared_from(object_ptr, ctrl_block);
938 return inner::__make_shared_fused(object_ptr, ctrl_block);
939}
940
941
949template <typename T, typename U>
951 return shared_ptr<T>(ptr, static_cast<T*>(ptr.get()));
952}
953
961template <typename T, typename U>
963 return shared_ptr<T>(ptr, const_cast<T*>(ptr.get()));
964}
965
973template <typename T, typename U>
975 return shared_ptr<T>(ptr, reinterpret_cast<T*>(ptr.get()));
976}
977
985template <typename T, typename U>
987 T* tmp = dynamic_cast<T*>(ptr.get());
988 if (tmp != nullptr) {
989 return shared_ptr<T>(ptr, tmp);
990 }
991 return nullptr;
992}
993 // SharedPointer
995
1000
1005template <typename T>
1006struct hash<shared_ptr<T>> {
1007 NEFORCE_CONSTEXPR20 size_t operator()(const shared_ptr<T>& ptr) const
1008 noexcept(noexcept(_NEFORCE declval<_NEFORCE hash<T*>>()(_NEFORCE declval<T*>()))) {
1009 return hash<T*>()(ptr.get());
1010 }
1011};
1012 // HashPrimary
1014
1016NEFORCE_BEGIN_INNER__
1017
1018template <typename T>
1019class smart_pointer_atomic {
1020public:
1021 using value_type = T;
1022
1023private:
1024 struct atomic_counter {
1025 public:
1026 using count_type = inner::__smart_ptr_counter;
1027
1028 private:
1029 mutable atomic_base<uintptr_t> value_{0};
1030
1031 static constexpr uintptr_t lock_bit{1};
1032
1033 static void dereference(count_type* counter, true_type /*unused*/) noexcept { counter->decref_strong(); }
1034
1035 static void dereference(count_type* counter, false_type /*unused*/) noexcept { counter->decref_weak(); }
1036
1037 public:
1038 constexpr atomic_counter() noexcept = default;
1039
1040 explicit atomic_counter(count_type* counter) noexcept :
1041 value_(reinterpret_cast<uintptr_t>(counter)) {
1042 counter = nullptr;
1043 }
1044
1045 ~atomic_counter() {
1046 auto value = value_.load(memory_order_relaxed);
1047 NEFORCE_CONSTEXPR_ASSERT(!(value & lock_bit));
1048 if (auto* counter = reinterpret_cast<count_type*>(value)) {
1049 this->dereference(counter, is_shared_ptr<T>());
1050 }
1051 }
1052
1053 atomic_counter(const atomic_counter&) = delete;
1054 atomic_counter& operator=(const atomic_counter&) = delete;
1055
1056 count_type* lock(memory_order mo) const noexcept {
1057 if (mo != memory_order_seq_cst) {
1059 }
1060 auto cur = value_.load(memory_order_relaxed);
1061 while ((cur & lock_bit) != 0U) {
1062 this_thread::relax();
1063 cur = value_.load(memory_order_relaxed);
1064 }
1065
1066 while (!value_.compare_exchange_strong(cur, cur | lock_bit, mo, memory_order_relaxed)) {
1067 this_thread::relax();
1068 cur = cur & ~lock_bit;
1069 }
1070 return reinterpret_cast<count_type*>(cur);
1071 }
1072
1073 void unlock(memory_order mo) const noexcept { value_.fetch_sub(1, mo); }
1074
1075 count_type* swap_unlock(count_type* counter, memory_order mo) noexcept {
1076 if (mo != memory_order_seq_cst) {
1078 }
1079 auto addr = reinterpret_cast<uintptr_t>(counter);
1080 addr = value_.exchange(addr, mo);
1081 return reinterpret_cast<count_type*>(addr & ~lock_bit);
1082 }
1083
1084 void wait_unlock(memory_order mo) const noexcept {
1085 const auto old_value = value_.load(memory_order_relaxed);
1086 const auto unlocked = old_value & ~lock_bit;
1088 if (value_.load(memory_order_acquire) == unlocked) {
1089 value_.wait(unlocked, mo);
1090 }
1091 }
1092
1093 void notify_one() noexcept { value_.notify_one(); }
1094
1095 void notify_all() noexcept { value_.notify_all(); }
1096 };
1097
1098 typename T::element_type* ptr_ = nullptr;
1099 atomic_counter refcount_;
1100
1101 friend struct atomic<T>;
1102
1103private:
1104 static typename atomic_counter::count_type* incref(typename atomic_counter::count_type* counter,
1105 true_type /*unused*/) {
1106 if (counter) {
1107 counter->incref_strong();
1108 }
1109 return counter;
1110 }
1111
1112 static typename atomic_counter::count_type* incref(typename atomic_counter::count_type* counter,
1113 false_type /*unused*/) {
1114 if (counter) {
1115 counter->incref_weak();
1116 }
1117 return counter;
1118 }
1119
1120public:
1121 constexpr smart_pointer_atomic() noexcept = default;
1122
1123 explicit smart_pointer_atomic(value_type value) noexcept :
1124 ptr_(value.ptr_),
1125 refcount_(value.owner_) {
1126 value.owner_ = nullptr;
1127 value.ptr_ = nullptr;
1128 }
1129
1130 ~smart_pointer_atomic() = default;
1131
1132 smart_pointer_atomic(const smart_pointer_atomic&) = delete;
1133 void operator=(const smart_pointer_atomic&) = delete;
1134
1135 value_type load(memory_order mo) const noexcept {
1137 if (mo != memory_order_seq_cst) {
1139 }
1140
1141 value_type value;
1142 auto counter = refcount_.lock(mo);
1143 value.ptr_ = ptr_;
1144 value.owner_ = this->incref(counter, is_shared_ptr<T>());
1145 refcount_.unlock(memory_order_relaxed);
1146 return value;
1147 }
1148
1149 void swap(value_type& value, memory_order mo) noexcept {
1150 refcount_.lock(memory_order_acquire);
1151 _NEFORCE swap(ptr_, value.ptr_);
1152 auto* old_owner = refcount_.swap_unlock(value.owner_, mo);
1153 value.owner_ = old_owner;
1154 }
1155
1156 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo1,
1157 memory_order mo2) noexcept {
1158 bool result = true;
1159 auto* counter = refcount_.lock(memory_order_acquire);
1160 if (ptr_ == expected.ptr_ && counter == expected.owner_) {
1161 ptr_ = desired.ptr_;
1162 auto* old_owner = refcount_.swap_unlock(desired.owner_, mo1);
1163 desired.owner_ = old_owner;
1164 } else {
1165 auto* new_counter = this->incref(counter, is_shared_ptr<T>());
1166 refcount_.unlock(mo2);
1167 expected.ptr_ = ptr_;
1168 expected.owner_ = new_counter;
1169 result = false;
1170 }
1171 return result;
1172 }
1173
1174 void wait(value_type mold, memory_order mo) const noexcept {
1175 auto* counter = refcount_.lock(memory_order_acquire);
1176 if (ptr_ == mold.ptr_ && counter == mold.owner_) {
1177 refcount_.wait_unlock(mo);
1178 } else {
1179 refcount_.unlock(memory_order_relaxed);
1180 }
1181 }
1182
1183 void notify_one() noexcept { refcount_.notify_one(); }
1184
1185 void notify_all() noexcept { refcount_.notify_all(); }
1186};
1187
1188NEFORCE_END_INNER__
1190
1196
1203template <typename T>
1204struct atomic<shared_ptr<T>> {
1205public:
1206 using value_type = shared_ptr<T>;
1207
1208 static constexpr bool is_always_lock_free = false;
1209
1210private:
1211 inner::smart_pointer_atomic<value_type> atomic_;
1212
1213public:
1218 NEFORCE_NODISCARD bool is_lock_free() const noexcept { return false; }
1219
1223 constexpr atomic(nullptr_t = nullptr) noexcept {}
1224
1229 atomic(value_type value) noexcept :
1230 atomic_(move(value)) {}
1231
1232 atomic(const atomic&) = delete;
1233 void operator=(const atomic&) = delete;
1234
1240 value_type load(memory_order mo = memory_order_seq_cst) const noexcept { return atomic_.load(mo); }
1241
1245 operator value_type() const noexcept { return atomic_.load(memory_order_seq_cst); }
1246
1252 void store(value_type desired, memory_order mo = memory_order_seq_cst) noexcept { atomic_.swap(desired, mo); }
1253
1257 void operator=(value_type desired) noexcept { atomic_.swap(desired, memory_order_seq_cst); }
1258
1262 void operator=(nullptr_t) noexcept { store(nullptr); }
1263
1270 value_type exchange(value_type desired, memory_order mo = memory_order_seq_cst) noexcept {
1271 atomic_.swap(desired, mo);
1272 return desired;
1273 }
1274
1278 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
1279 return atomic_.compare_exchange_strong(expected, desired, mo, mo2);
1280 }
1281
1285 bool compare_exchange_strong(value_type& expected, value_type desired,
1286 memory_order mo = memory_order_seq_cst) noexcept {
1287 return compare_exchange_strong(expected, move(desired), mo, cmpexch_failure_order(mo));
1288 }
1289
1293 bool compare_exchange_weak(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
1294 return compare_exchange_strong(expected, move(desired), mo, mo2);
1295 }
1296
1300 bool compare_exchange_weak(value_type& expected, value_type desired,
1301 memory_order mo = memory_order_seq_cst) noexcept {
1302 return compare_exchange_strong(expected, move(desired), mo);
1303 }
1304
1308 void wait(value_type mold, memory_order mo = memory_order_seq_cst) const noexcept { atomic_.wait(move(mold), mo); }
1309
1313 void notify_one() noexcept { atomic_.notify_one(); }
1314
1318 void notify_all() noexcept { atomic_.notify_all(); }
1319};
1320 // AtomicOperations
1322
1323NEFORCE_END_NAMESPACE__
1324#endif // NEFORCE_CORE_MEMORY_SHARED_PTR_HPP__
分配器特性
原子类型完整实现
add_lvalue_reference_t< T > operator[](size_t idx)
数组下标运算符
共享智能指针类模板
shared_ptr(shared_ptr &&other) noexcept
移动构造函数
shared_ptr & operator=(shared_ptr< U > &&other) noexcept
类型转换移动赋值运算符
T * operator->() const noexcept
指针解引用运算符
shared_ptr(shared_ptr< U > &&other) noexcept
类型转换移动构造函数
bool owner_equal(const shared_ptr< U > &rhs) const noexcept
检查所有权是否相等
T * get() const noexcept
获取原始指针
shared_ptr(unique_ptr< U, Deleter > &&unique)
独享智能指针构造函数
add_lvalue_reference_t< T > operator*() const noexcept
解引用运算符
void reset(U *ptr)
重置共享指针并管理新对象
shared_ptr(const shared_ptr &other) noexcept
拷贝构造函数
bool owner_equal(const weak_ptr< U > &rhs) const noexcept
与弱指针检查所有权是否相等
bool owner_before(const weak_ptr< U > &rhs) const noexcept
与弱指针比较所有权顺序
shared_ptr(const shared_ptr< U > &other) noexcept
类型转换拷贝构造函数
shared_ptr(const shared_ptr< U > &other, T *ptr) noexcept
从共享指针和别名指针别名构造函数
shared_ptr & operator=(const shared_ptr< U > &other) noexcept
类型转换拷贝赋值运算符
shared_ptr(nullptr_t np=nullptr) noexcept
默认构造函数
bool owner_before(const shared_ptr< U > &rhs) const noexcept
比较所有权顺序
shared_ptr(U *ptr, Deleter &&deleter)
从原始指针和自定义删除器构造函数
long use_count() const noexcept
获取引用计数
~shared_ptr() noexcept
析构函数
void reset(U *ptr, Deleter deleter)
带自定义删除器重置共享指针并管理新对象
void reset() noexcept
重置共享指针
shared_ptr(U *ptr)
从原始指针构造函数
void swap(shared_ptr &other) noexcept
交换两个共享指针
shared_ptr(shared_ptr< U > &&other, T *ptr) noexcept
移动别名构造函数
shared_ptr & operator=(shared_ptr &&other) noexcept
移动赋值运算符
shared_ptr & operator=(const shared_ptr &other) noexcept
拷贝赋值运算符
独占智能指针
弱智能指针类模板
比较算法
异常处理框架
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(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 long uint64_t
64位无符号整数类型
decltype(nullptr) nullptr_t
空指针类型
NEFORCE_NORETURN void unreachable() noexcept
标记不可达代码路径
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
@ wait
等待操作
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr bool is_invocable_v
is_invocable的便捷变量模板
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
memory_order
内存顺序
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
@ release
释放操作,确保前面的读写不会被重排到后面
uint64_t uintptr_t
可容纳指针的无符号整数类型
typename remove_extent< T >::type remove_extent_t
remove_extent的便捷别名
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类型转换
bool operator>(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
大于比较运算符
shared_ptr< T > dynamic_pointer_cast(const shared_ptr< U > &ptr)
动态类型转换
bool operator<=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
小于等于比较运算符
bool operator==(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
相等比较运算符
enable_if_t<!is_unbounded_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > make_shared(Args &&... args)
融合分配创建共享指针
bool operator<(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
小于比较运算符(基于所有权顺序)
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)
静态类型转换
bool operator!=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
不等比较运算符
shared_ptr< T > reinterpret_pointer_cast(const shared_ptr< U > &ptr)
重解释类型转换
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr bool is_constructible_v
is_constructible的便捷变量模板
constexpr bool is_nothrow_default_constructible_v
is_nothrow_default_constructible的便捷变量模板
constexpr bool is_nothrow_constructible_v
is_nothrow_constructible的便捷变量模板
constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
分配器特性模板
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 void construct(Alloc &alloc, T *ptr, Args &&... args) noexcept(noexcept(allocator_traits::__construct_aux(alloc, ptr, _NEFORCE forward< Args >(args)...)))
在已分配内存上构造对象
static constexpr pointer allocate(Alloc &alloc, size_type n)
分配内存
constexpr atomic(nullptr_t=nullptr) noexcept
默认构造函数
void wait(value_type mold, memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order mo, memory_order mo2) noexcept
比较交换弱版本
void operator=(value_type desired) noexcept
赋值操作符
bool is_lock_free() const noexcept
检查是否无锁
void notify_all() noexcept
通知所有等待者
value_type exchange(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
比较交换强版本
void store(value_type desired, memory_order mo=memory_order_seq_cst) noexcept
原子存储
atomic(value_type value) noexcept
从shared_ptr构造
value_type load(memory_order mo=memory_order_seq_cst) const noexcept
原子加载
void operator=(nullptr_t) noexcept
赋空值操作符
void notify_one() noexcept
通知一个等待者
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
简化比较交换弱版本
原子类型基础模板类
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 exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
void notify_one() noexcept
通知一个等待线程
void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
通用原子类型模板
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
bool compare_exchange_strong(T &expected, T desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
T value_type
值类型
bool compare_exchange_weak(T &expected, T desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
constexpr compressed_pair & get_base() &noexcept
获取基类引用
默认删除器
启用从this创建共享指针的基类
shared_ptr< const T > shared_from_this() const
获取指向自身的常量共享指针
shared_ptr< T > shared_from_this()
获取指向自身的共享指针
enable_shared_from_this() noexcept=default
构造函数
哈希函数的主模板
判断Base是否是Derived的基类
类型特征:是否为shared_ptr
内存操作异常
独占智能指针