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 explicit __smart_ptr_counter_impl(T* ptr, Deleter&& deleter) noexcept(is_nothrow_move_constructible_v<Deleter>) :
145 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE move(deleter), ptr) {}
146
147 void delete_object() override {
148 ptr_pair_.get_base()(ptr_pair_.value);
149 ptr_pair_.value = nullptr;
150 }
151
152 void delete_this() noexcept override { delete this; }
153};
154
162template <typename T, typename Deleter>
163struct __smart_ptr_counter_impl_fused final : __smart_ptr_counter {
164 compressed_pair<Deleter, T*> ptr_pair_{default_construct_tag{}, nullptr};
165 size_t align_;
166 void* mem_;
167
168 explicit __smart_ptr_counter_impl_fused(T* ptr, void* mem, size_t align, Deleter deleter) noexcept :
169 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE move(deleter), ptr),
170 align_(align),
171 mem_(mem) {}
172
173 void delete_object() noexcept override {
174 ptr_pair_.get_base()(ptr_pair_.value);
175 ptr_pair_.value = nullptr;
176 }
177
178 void delete_this() noexcept override {
179#if NEFORCE_STANDARD_17
180 operator delete(mem_, std::align_val_t{align_});
181#else
182 operator delete(mem_);
183#endif
184 }
185};
186
195template <typename T, typename Deleter, typename Alloc>
196struct __smart_ptr_counter_impl_allocated final : __smart_ptr_counter {
197 compressed_pair<Deleter, T*> ptr_pair_{default_construct_tag{}, nullptr};
198 compressed_pair<Alloc, size_t> size_pair_{default_construct_tag{}, 0};
199 void* mem_;
200
201 explicit __smart_ptr_counter_impl_allocated(T* ptr, void* mem, const size_t size, Deleter deleter,
202 Alloc alloc) noexcept :
203 ptr_pair_(exact_arg_construct_tag{}, _NEFORCE move(deleter), ptr),
204 size_pair_(exact_arg_construct_tag{}, _NEFORCE move(alloc), size),
205 mem_(mem) {}
206
207 void delete_object() noexcept override {
208 ptr_pair_.get_base()(ptr_pair_.value);
209 ptr_pair_.value = nullptr;
210 }
211
212 void delete_this() noexcept override {
213 using alloc_traits = allocator_traits<Alloc>;
214 using byte_allocator = typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
215 byte_allocator byte_alloc(size_pair_.get_base());
216 allocator_traits<byte_allocator>::deallocate(byte_alloc, static_cast<byte_t*>(mem_), size_pair_.value);
217 }
218};
219
220NEFORCE_END_INNER__
222
223
224template <typename T>
225struct enable_shared_from;
226
227template <typename T>
228class shared_ptr;
229
230template <typename T>
231class weak_ptr;
232
234NEFORCE_BEGIN_INNER__
235
236template <typename T>
237void __setup_enable_shared_from_impl(T* ptr, __smart_ptr_counter* owner, true_type) noexcept {
238 if (ptr) {
239 static_cast<enable_shared_from<T>*>(ptr)->owner_ = owner;
240 }
241}
242
243template <typename T>
244void __setup_enable_shared_from_impl(T*, __smart_ptr_counter*, false_type) noexcept {}
245
246template <typename T>
247void __setup_enable_shared_from(T* ptr, __smart_ptr_counter* owner) noexcept {
248 inner::__setup_enable_shared_from_impl(ptr, owner, is_base_of<enable_shared_from<T>, T>{});
249}
250
251template <typename T>
252shared_ptr<T> __make_shared_fused(T* ptr, __smart_ptr_counter* owner) noexcept {
253 return shared_ptr<T>(ptr, owner);
254}
255
256NEFORCE_END_INNER__
258
259
268template <typename T>
269class shared_ptr {
270public:
271 using element_type = T;
272
273private:
274 using owner_type = inner::__smart_ptr_counter;
275
276 template <typename U, typename Deleter>
277 using owner_deleter = inner::__smart_ptr_counter_impl<U, Deleter>;
278
279 template <typename U>
280 using owner_default = inner::__smart_ptr_counter_impl<U, default_delete<U>>;
281
282 element_type* ptr_ = nullptr;
283 owner_type* owner_ = nullptr;
284
290 explicit shared_ptr(T* ptr, owner_type* owner) noexcept :
291 ptr_(ptr),
292 owner_(owner) {}
293
294 template <typename U>
295 friend class shared_ptr;
296
297 template <typename U>
298 friend class weak_ptr;
299
300 template <typename U>
301 friend class inner::smart_pointer_atomic;
302
303 template <typename U>
304 friend shared_ptr<U> inner::__make_shared_fused(U*, inner::__smart_ptr_counter*) noexcept;
305
306public:
313 shared_ptr(nullptr_t np = nullptr) noexcept {}
314
320 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
321 shared_ptr(U* ptr) :
322 ptr_(ptr),
323 owner_(new owner_default<U>(ptr_)) {
324 inner::__setup_enable_shared_from(ptr_, owner_);
325 }
326
334 template <typename U, typename Deleter, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
335 explicit shared_ptr(U* ptr, Deleter&& deleter) :
336 ptr_(ptr),
337 owner_(new owner_deleter<U, Deleter>(ptr_, _NEFORCE forward<Deleter>(deleter))) {
338 inner::__setup_enable_shared_from(ptr_, owner_);
339 }
340
347 template <typename U, typename Deleter, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
349 shared_ptr(unique.release(), unique.get_deleter()) {}
350
355 shared_ptr(const shared_ptr& other) noexcept :
356 ptr_(other.ptr_),
357 owner_(other.owner_) {
358 if (owner_) {
359 owner_->incref_strong();
360 }
361 }
362
368 shared_ptr& operator=(const shared_ptr& other) noexcept {
369 if (_NEFORCE addressof(other) == this) {
370 return *this;
371 }
372 if (owner_) {
373 owner_->decref_strong();
374 }
375 ptr_ = other.ptr_;
376 owner_ = other.owner_;
377 if (owner_) {
378 owner_->incref_strong();
379 }
380 return *this;
381 }
382
388 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
389 shared_ptr(const shared_ptr<U>& other) noexcept :
390 ptr_(other.ptr_),
391 owner_(other.owner_) {
392 if (owner_) {
393 owner_->incref_strong();
394 }
395 }
396
401 shared_ptr(shared_ptr&& other) noexcept :
402 ptr_(other.ptr_),
403 owner_(other.owner_) {
404 other.ptr_ = nullptr;
405 other.owner_ = nullptr;
406 }
407
413 shared_ptr& operator=(shared_ptr&& other) noexcept {
414 if (_NEFORCE addressof(other) == this) {
415 return *this;
416 }
417 if (owner_) {
418 owner_->decref_strong();
419 }
420 ptr_ = other.ptr_;
421 owner_ = other.owner_;
422 other.ptr_ = nullptr;
423 other.owner_ = nullptr;
424 return *this;
425 }
426
432 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
433 explicit shared_ptr(shared_ptr<U>&& other) noexcept :
434 ptr_(other.ptr_),
435 owner_(other.owner_) {
436 other.ptr_ = nullptr;
437 other.owner_ = nullptr;
438 }
439
447 template <typename U>
448 shared_ptr(const shared_ptr<U>& other, T* ptr) noexcept :
449 ptr_(ptr),
450 owner_(other.owner_) {
451 if (owner_) {
452 owner_->incref_strong();
453 }
454 }
455
459 template <typename U>
460 shared_ptr(shared_ptr<U>&& other, T* ptr) noexcept :
461 ptr_(ptr),
462 owner_(other.owner_) {
463 other.ptr_ = nullptr;
464 other.owner_ = nullptr;
465 }
466
470 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
471 shared_ptr& operator=(const shared_ptr<U>& other) noexcept {
472 if (owner_) {
473 owner_->decref_strong();
474 }
475 ptr_ = other.ptr_;
476 owner_ = other.owner_;
477 if (owner_) {
478 owner_->incref_strong();
479 }
480 return *this;
481 }
482
486 template <typename U, enable_if_t<is_convertible_v<U*, T*>, int> = 0>
487 shared_ptr& operator=(shared_ptr<U>&& other) noexcept {
488 if (owner_) {
489 owner_->decref_strong();
490 }
491 ptr_ = other.ptr_;
492 owner_ = other.owner_;
493 other.ptr_ = nullptr;
494 other.owner_ = nullptr;
495 return *this;
496 }
497
502 ~shared_ptr() noexcept { reset(); }
503
507 void reset() noexcept {
508 if (owner_) {
509 owner_->decref_strong();
510 }
511 owner_ = nullptr;
512 ptr_ = nullptr;
513 }
514
520 template <typename U>
521 void reset(U* ptr) {
522 if (owner_) {
523 owner_->decref_strong();
524 }
525 ptr_ = nullptr;
526 owner_ = nullptr;
527 ptr_ = ptr;
528 owner_ = new owner_default<U>(ptr_);
529 inner::__setup_enable_shared_from<T>(ptr_, owner_);
530 }
531
539 template <typename U, typename Deleter>
540 void reset(U* ptr, Deleter deleter) {
541 if (owner_) {
542 owner_->decref_strong();
543 }
544 ptr_ = nullptr;
545 owner_ = nullptr;
546 ptr_ = ptr;
547 owner_ = new owner_deleter<U, Deleter>(ptr_, _NEFORCE move(deleter));
548 inner::__setup_enable_shared_from<T>(ptr_, owner_);
549 }
550
555 NEFORCE_NODISCARD long use_count() const noexcept { return owner_ ? owner_->use_count() : 0; }
556
561 NEFORCE_NODISCARD bool unique() const noexcept { return owner_ ? owner_->use_count() == 1 : true; }
562
567 void swap(shared_ptr& other) noexcept {
568 if (_NEFORCE addressof(other) == this) {
569 return;
570 }
571 _NEFORCE swap(ptr_, other.ptr_);
572 _NEFORCE swap(owner_, other.owner_);
573 }
574
579 NEFORCE_NODISCARD T* get() const noexcept { return ptr_; }
580
585 NEFORCE_NODISCARD T* operator->() const noexcept { return ptr_; }
586
591 NEFORCE_NODISCARD add_lvalue_reference_t<T> operator*() const noexcept { return *ptr_; }
592
597 NEFORCE_NODISCARD explicit operator bool() const noexcept { return ptr_ != nullptr; }
598
605 template <typename U>
606 NEFORCE_NODISCARD bool owner_equal(const shared_ptr<U>& rhs) const noexcept {
607 return owner_ == rhs.owner_;
608 }
609
613 template <typename U>
614 NEFORCE_NODISCARD bool owner_equal(const weak_ptr<U>& rhs) const noexcept {
615 return owner_ == rhs.owner_;
616 }
617
624 template <typename U>
625 NEFORCE_NODISCARD bool owner_before(const shared_ptr<U>& rhs) const noexcept {
626 return owner_ < rhs.owner_;
627 }
628
632 template <typename U>
633 NEFORCE_NODISCARD bool owner_before(const weak_ptr<U>& rhs) const noexcept {
634 return owner_ < rhs.owner_;
635 }
636};
637
641template <typename T, typename U>
642NEFORCE_NODISCARD bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
643 return lhs.owner_equal(rhs);
644}
645
649template <typename T, typename U>
650NEFORCE_NODISCARD bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
651 return !(lhs == rhs);
652}
653
657template <typename T, typename U>
658NEFORCE_NODISCARD bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
659 return lhs.owner_before(rhs);
660}
661
665template <typename T, typename U>
666NEFORCE_NODISCARD bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
667 return rhs < lhs;
668}
669
673template <typename T, typename U>
674NEFORCE_NODISCARD bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
675 return !(lhs > rhs);
676}
677
681template <typename T, typename U>
682NEFORCE_NODISCARD bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept {
683 return !(lhs < rhs);
684}
685
686
691template <typename T>
692class shared_ptr<T[]> : shared_ptr<T> {
693public:
694 using shared_ptr<T>::shared_ptr;
695
701 add_lvalue_reference_t<T> operator[](size_t idx) { return this->get()[idx]; }
702};
703
704
712template <typename T>
714private:
715 mutable inner::__smart_ptr_counter* owner_ = nullptr;
716
717 template <typename U>
718 friend void inner::__setup_enable_shared_from_impl(U* ptr, inner::__smart_ptr_counter* owner, true_type) noexcept;
719
720 template <typename U>
721 friend void inner::__setup_enable_shared_from(U*, inner::__smart_ptr_counter*) noexcept;
722
723 template <typename U>
724 friend class shared_ptr;
725
726 template <typename U>
727 friend class weak_ptr;
728
729protected:
733 enable_shared_from() noexcept {}
734
740 shared_ptr<T> shared_from_this() {
741 static_assert(is_base_of_v<enable_shared_from, T>, "shared from T requires derived class");
742 if (!owner_) {
743 NEFORCE_THROW_EXCEPTION(memory_exception("smart pointer share failed."));
744 }
745 owner_->incref_strong();
746 return inner::__make_shared_fused(static_cast<T*>(this), owner_);
747 }
748
754 shared_ptr<const T> shared_from_this() const {
755 static_assert(is_base_of_v<enable_shared_from, T>, "shared from T requires derived class");
756 if (!owner_) {
757 NEFORCE_THROW_EXCEPTION(memory_exception("smart pointer share failed."));
758 }
759 owner_->incref_strong();
760 return inner::__make_shared_fused(static_cast<const T*>(this), owner_);
761 }
762};
763
764
768template <typename T>
770
771template <typename T>
772struct is_shared_ptr<shared_ptr<T>> : true_type {};
773
774template <typename T>
775NEFORCE_INLINE17 constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;
776
777
788template <typename T, typename... Args>
790 auto const deleter = [](T* ptr) noexcept(is_nothrow_destructible_v<T>) { ptr->~T(); };
791 using Counter = inner::__smart_ptr_counter_impl_fused<T, decltype(deleter)>;
792 constexpr size_t align = max(alignof(T), alignof(Counter));
793 constexpr size_t offset = (sizeof(Counter) + align - 1) & ~(align - 1);
794 constexpr size_t size = offset + sizeof(T);
795#if NEFORCE_STANDARD_17
796 void* mem = operator new(size, std::align_val_t{align});
797 auto* counter = static_cast<Counter*>(mem);
798#else
799 void* mem = operator new(size + align - 1);
800 size_t aligned_addr = (reinterpret_cast<size_t>(mem) + (align - 1)) & ~(align - 1);
801 Counter* counter = reinterpret_cast<Counter*>(aligned_addr);
802#endif
803 T* object = reinterpret_cast<T*>(reinterpret_cast<byte_t*>(counter) + offset);
804 try {
805 _NEFORCE construct(object, _NEFORCE forward<Args>(args)...);
806 } catch (...) {
807#if NEFORCE_STANDARD_17
808 operator delete(mem, std::align_val_t{align});
809#else
810 operator delete(mem);
811#endif
812 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr construction failed."));
813 }
814 _NEFORCE construct(reinterpret_cast<Counter*>(counter), object, mem, align, _NEFORCE move(deleter));
815 inner::__setup_enable_shared_from(object, counter);
816 return inner::__make_shared_fused(object, counter);
817}
818
826template <typename T>
828 using value = remove_extent_t<T>;
829 value* tmp = nullptr;
830 try {
831 tmp = new value[len];
832 return shared_ptr<T[]>(tmp, default_delete<value[]>{});
833 } catch (...) {
834 operator delete[](tmp);
835 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr construction failed."));
836 }
837 unreachable();
838}
839
852template <typename T, typename Alloc, typename... Args>
854 Args&&... args) {
855 auto deleter = [](T* p) { p->~T(); };
856 using ControlBlock = inner::__smart_ptr_counter_impl_allocated<T, decltype(deleter), Alloc>;
857
858 const size_t align = _NEFORCE max(alignof(ControlBlock), alignof(T));
859 const size_t offset = (sizeof(ControlBlock) + align - 1) & ~(align - 1);
860 const size_t total_size = offset + sizeof(T);
861 const size_t raw_size = total_size + align - 1;
862
863 using alloc_traits = allocator_traits<remove_cv_t<Alloc>>;
864 using byte_allocator = typename alloc_traits::template alloc_rebind_t<Alloc, byte_t>;
865 byte_allocator byte_alloc(alloc);
866
867 byte_t* raw_mem = allocator_traits<byte_allocator>::allocate(byte_alloc, raw_size);
868
869 const uintptr_t raw_addr = reinterpret_cast<uintptr_t>(raw_mem);
870 const uintptr_t aligned_addr = (raw_addr + align - 1) & ~static_cast<uintptr_t>(align - 1);
871 auto aligned_mem = reinterpret_cast<byte_t*>(aligned_addr);
872 T* object_ptr = reinterpret_cast<T*>(aligned_mem + offset);
873
874 try {
875 allocator_traits<Alloc>::construct(alloc, object_ptr, _NEFORCE forward<Args>(args)...);
876 } catch (...) {
877 allocator_traits<byte_allocator>::deallocate(byte_alloc, raw_mem, raw_size);
878 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr ref object construction failed."));
879 }
880
881 ControlBlock* ctrl_block = nullptr;
882 try {
883 ctrl_block = _NEFORCE construct(reinterpret_cast<ControlBlock*>(aligned_mem), object_ptr, raw_mem, raw_size,
884 deleter, alloc);
885 } catch (...) {
886 allocator_traits<Alloc>::destroy(alloc, object_ptr);
887 allocator_traits<byte_allocator>::deallocate(byte_alloc, raw_mem, raw_size);
888 NEFORCE_THROW_EXCEPTION(memory_exception("shared ptr control block construction failed."));
889 }
890
891 inner::__setup_enable_shared_from(object_ptr, ctrl_block);
892 return inner::__make_shared_fused(object_ptr, ctrl_block);
893}
894
895
903template <typename T, typename U>
905 return shared_ptr<T>(ptr, static_cast<T*>(ptr.get()));
906}
907
915template <typename T, typename U>
917 return shared_ptr<T>(ptr, const_cast<T*>(ptr.get()));
918}
919
927template <typename T, typename U>
929 return shared_ptr<T>(ptr, reinterpret_cast<T*>(ptr.get()));
930}
931
939template <typename T, typename U>
941 T* tmp = dynamic_cast<T*>(ptr.get());
942 if (tmp != nullptr) {
943 return shared_ptr<T>(ptr, tmp);
944 }
945 return nullptr;
946}
947 // SharedPointer
949
954
959template <typename T>
960struct hash<shared_ptr<T>> {
961 NEFORCE_CONSTEXPR20 size_t operator()(const shared_ptr<T>& ptr) const
962 noexcept(noexcept(_NEFORCE declval<_NEFORCE hash<T*>>()(_NEFORCE declval<T*>()))) {
963 return hash<T*>()(ptr.get());
964 }
965};
966 // HashPrimary
968
970NEFORCE_BEGIN_INNER__
971
972template <typename T>
973class smart_pointer_atomic {
974public:
975 using value_type = T;
976
977private:
978 struct atomic_counter {
979 public:
980 using count_type = inner::__smart_ptr_counter;
981
982 private:
983 mutable atomic_base<uintptr_t> value_{0};
984
985 static constexpr uintptr_t lock_bit{1};
986
987 static void dereference(count_type* counter, true_type) noexcept { counter->decref_strong(); }
988
989 static void dereference(count_type* counter, false_type) noexcept { counter->decref_weak(); }
990
991 public:
992 constexpr atomic_counter() noexcept = default;
993
994 explicit atomic_counter(count_type* counter) noexcept :
995 value_(reinterpret_cast<uintptr_t>(counter)) {
996 counter = nullptr;
997 }
998
999 ~atomic_counter() {
1000 auto value = value_.load(memory_order_relaxed);
1001 NEFORCE_CONSTEXPR_ASSERT(!(value & lock_bit));
1002 if (auto counter = reinterpret_cast<count_type*>(value)) {
1003 this->dereference(counter, is_shared_ptr<T>());
1004 }
1005 }
1006
1007 atomic_counter(const atomic_counter&) = delete;
1008 atomic_counter& operator=(const atomic_counter&) = delete;
1009
1010 count_type* lock(memory_order mo) const noexcept {
1011 if (mo != memory_order_seq_cst) {
1013 }
1014 auto cur = value_.load(memory_order_relaxed);
1015 while (cur & lock_bit) {
1016 this_thread::relax();
1017 cur = value_.load(memory_order_relaxed);
1018 }
1019
1020 while (!value_.compare_exchange_strong(cur, cur | lock_bit, mo, memory_order_relaxed)) {
1021 this_thread::relax();
1022 cur = cur & ~lock_bit;
1023 }
1024 return reinterpret_cast<count_type*>(cur);
1025 }
1026
1027 void unlock(memory_order mo) const noexcept { value_.fetch_sub(1, mo); }
1028
1029 count_type* swap_unlock(count_type* counter, memory_order mo) noexcept {
1030 if (mo != memory_order_seq_cst) {
1032 }
1033 auto addr = reinterpret_cast<uintptr_t>(counter);
1034 addr = value_.exchange(addr, mo);
1035 return reinterpret_cast<count_type*>(addr & ~lock_bit);
1036 }
1037
1038 void wait_unlock(memory_order mo) const noexcept {
1039 const auto old_value = value_.load(memory_order_relaxed);
1040 const auto unlocked = old_value & ~lock_bit;
1042 if (value_.load(memory_order_acquire) == unlocked) {
1043 value_.wait(unlocked, mo);
1044 }
1045 }
1046
1047 void notify_one() noexcept { value_.notify_one(); }
1048
1049 void notify_all() noexcept { value_.notify_all(); }
1050 };
1051
1052 typename T::element_type* ptr_ = nullptr;
1053 atomic_counter refcount_;
1054
1055 friend struct atomic<T>;
1056
1057private:
1058 static typename atomic_counter::count_type* incref(typename atomic_counter::count_type* counter, true_type) {
1059 if (counter) {
1060 counter->incref_strong();
1061 }
1062 return counter;
1063 }
1064
1065 static typename atomic_counter::count_type* incref(typename atomic_counter::count_type* counter, false_type) {
1066 if (counter) {
1067 counter->incref_weak();
1068 }
1069 return counter;
1070 }
1071
1072public:
1073 constexpr smart_pointer_atomic() noexcept = default;
1074
1075 explicit smart_pointer_atomic(value_type value) noexcept :
1076 ptr_(value.ptr_),
1077 refcount_(value.owner_) {
1078 value.owner_ = nullptr;
1079 value.ptr_ = nullptr;
1080 }
1081
1082 ~smart_pointer_atomic() = default;
1083
1084 smart_pointer_atomic(const smart_pointer_atomic&) = delete;
1085 void operator=(const smart_pointer_atomic&) = delete;
1086
1087 value_type load(memory_order mo) const noexcept {
1089 if (mo != memory_order_seq_cst) {
1091 }
1092
1093 value_type value;
1094 auto counter = refcount_.lock(mo);
1095 value.ptr_ = ptr_;
1096 value.owner_ = this->incref(counter, is_shared_ptr<T>());
1097 refcount_.unlock(memory_order_relaxed);
1098 return value;
1099 }
1100
1101 void swap(value_type& value, memory_order mo) noexcept {
1102 refcount_.lock(memory_order_acquire);
1103 _NEFORCE swap(ptr_, value.ptr_);
1104 auto* old_owner = refcount_.swap_unlock(value.owner_, mo);
1105 value.owner_ = old_owner;
1106 }
1107
1108 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo1,
1109 memory_order mo2) noexcept {
1110 bool result = true;
1111 auto* counter = refcount_.lock(memory_order_acquire);
1112 if (ptr_ == expected.ptr_ && counter == expected.owner_) {
1113 ptr_ = desired.ptr_;
1114 auto* old_owner = refcount_.swap_unlock(desired.owner_, mo1);
1115 desired.owner_ = old_owner;
1116 } else {
1117 auto* new_counter = this->incref(counter, is_shared_ptr<T>());
1118 refcount_.unlock(mo2);
1119 expected.ptr_ = ptr_;
1120 expected.owner_ = new_counter;
1121 result = false;
1122 }
1123 return result;
1124 }
1125
1126 void wait(value_type mold, memory_order mo) const noexcept {
1127 auto* counter = refcount_.lock(memory_order_acquire);
1128 if (ptr_ == mold.ptr_ && counter == mold.owner_) {
1129 refcount_.wait_unlock(mo);
1130 } else {
1131 refcount_.unlock(memory_order_relaxed);
1132 }
1133 }
1134
1135 void notify_one() noexcept { refcount_.notify_one(); }
1136
1137 void notify_all() noexcept { refcount_.notify_all(); }
1138};
1139
1140NEFORCE_END_INNER__
1142
1148
1155template <typename T>
1156struct atomic<shared_ptr<T>> {
1157public:
1158 using value_type = shared_ptr<T>;
1159
1160 static constexpr bool is_always_lock_free = false;
1161
1162private:
1163 inner::smart_pointer_atomic<value_type> atomic_;
1164
1165public:
1170 bool is_lock_free() const noexcept { return false; }
1171
1175 constexpr atomic(nullptr_t = nullptr) noexcept {}
1176
1181 atomic(value_type value) noexcept :
1182 atomic_(move(value)) {}
1183
1184 atomic(const atomic&) = delete;
1185 void operator=(const atomic&) = delete;
1186
1192 value_type load(memory_order mo = memory_order_seq_cst) const noexcept { return atomic_.load(mo); }
1193
1197 operator value_type() const noexcept { return atomic_.load(memory_order_seq_cst); }
1198
1204 void store(value_type desired, memory_order mo = memory_order_seq_cst) noexcept { atomic_.swap(desired, mo); }
1205
1209 void operator=(value_type desired) noexcept { atomic_.swap(desired, memory_order_seq_cst); }
1210
1214 void operator=(nullptr_t) noexcept { store(nullptr); }
1215
1222 value_type exchange(value_type desired, memory_order mo = memory_order_seq_cst) noexcept {
1223 atomic_.swap(desired, mo);
1224 return desired;
1225 }
1226
1230 bool compare_exchange_strong(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
1231 return atomic_.compare_exchange_strong(expected, desired, mo, mo2);
1232 }
1233
1237 bool compare_exchange_strong(value_type& expected, value_type desired,
1238 memory_order mo = memory_order_seq_cst) noexcept {
1239 return compare_exchange_strong(expected, move(desired), mo, cmpexch_failure_order(mo));
1240 }
1241
1245 bool compare_exchange_weak(value_type& expected, value_type desired, memory_order mo, memory_order mo2) noexcept {
1246 return compare_exchange_strong(expected, move(desired), mo, mo2);
1247 }
1248
1252 bool compare_exchange_weak(value_type& expected, value_type desired,
1253 memory_order mo = memory_order_seq_cst) noexcept {
1254 return compare_exchange_strong(expected, move(desired), mo);
1255 }
1256
1260 void wait(value_type mold, memory_order mo = memory_order_seq_cst) const noexcept { atomic_.wait(move(mold), mo); }
1261
1265 void notify_one() noexcept { atomic_.notify_one(); }
1266
1270 void notify_all() noexcept { atomic_.notify_all(); }
1271};
1272 // AtomicOperations
1274
1275NEFORCE_END_NAMESPACE__
1276#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
类型转换移动赋值运算符
shared_ptr(shared_ptr< U > &&other) noexcept
类型转换移动构造函数
NEFORCE_NODISCARD bool owner_before(const shared_ptr< U > &rhs) const noexcept
比较所有权顺序
NEFORCE_NODISCARD long use_count() const noexcept
获取引用计数
NEFORCE_NODISCARD T * operator->() const noexcept
指针解引用运算符
shared_ptr(unique_ptr< U, Deleter > &&unique)
独享智能指针构造函数
NEFORCE_NODISCARD bool owner_before(const weak_ptr< U > &rhs) const noexcept
与弱指针比较所有权顺序
void reset(U *ptr)
重置共享指针并管理新对象
shared_ptr(const shared_ptr &other) noexcept
拷贝构造函数
NEFORCE_NODISCARD add_lvalue_reference_t< T > operator*() const noexcept
解引用运算符
NEFORCE_NODISCARD bool owner_equal(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
默认构造函数
NEFORCE_NODISCARD bool owner_equal(const shared_ptr< U > &rhs) const noexcept
检查所有权是否相等
shared_ptr(U *ptr, Deleter &&deleter)
从原始指针和自定义删除器构造函数
~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
移动别名构造函数
NEFORCE_NODISCARD bool unique() const noexcept
NEFORCE_NODISCARD T * get() const 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的便捷别名
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 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 NEFORCE_ALWAYS_INLINE_INLINE void unreachable() noexcept
标记不可达代码路径
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
@ wait
等待操作
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_INLINE17 constexpr bool is_invocable_v
is_invocable的便捷变量模板
NEFORCE_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
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的便捷别名
shared_ptr< T > const_pointer_cast(const shared_ptr< U > &ptr)
CV类型转换
NEFORCE_NODISCARD bool operator==(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
相等比较运算符
NEFORCE_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)
动态类型转换
NEFORCE_NODISCARD bool operator>(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
大于比较运算符
NEFORCE_NODISCARD 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)
融合分配创建共享指针
enable_if_t<!is_array_v< T > &&is_constructible_v< T, Args... >, shared_ptr< T > > allocate_shared(Alloc &alloc, Args &&... args)
使用分配器创建共享指针
NEFORCE_NODISCARD bool operator<=(const shared_ptr< T > &lhs, const shared_ptr< U > &rhs) noexcept
小于等于比较运算符
shared_ptr< T > static_pointer_cast(const shared_ptr< U > &ptr)
静态类型转换
NEFORCE_NODISCARD 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重载
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
NEFORCE_INLINE17 constexpr bool is_nothrow_default_constructible_v
is_nothrow_default_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_constructible_v
is_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
分配器特性模板
static NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer allocate(Alloc &alloc, size_type n)
分配内存
static NEFORCE_CONSTEXPR20 void deallocate(Alloc &alloc, pointer ptr, size_type n)
释放内存
static NEFORCE_CONSTEXPR20 void destroy(Alloc &alloc, T *ptr) noexcept(noexcept(allocator_traits::__destroy_aux(alloc, ptr, 0)))
销毁对象
static NEFORCE_CONSTEXPR20 void construct(Alloc &alloc, T *ptr, Args &&... args) noexcept(noexcept(allocator_traits::__construct_aux(alloc, ptr, _NEFORCE forward< Args >(args)...)))
在已分配内存上构造对象
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
简化比较交换弱版本
原子类型基础模板类
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
NEFORCE_ALWAYS_INLINE void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
NEFORCE_ALWAYS_INLINE value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
NEFORCE_ALWAYS_INLINE value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
NEFORCE_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const 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
获取指向自身的常量共享指针
enable_shared_from() noexcept
构造函数
shared_ptr< T > shared_from_this()
获取指向自身的共享指针
哈希函数的主模板
判断Base是否是Derived的基类
类型特征:是否为shared_ptr
内存操作异常
独占智能指针