1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| #pragma once
#include <atomic>
template <typename T> class shared_ptr { private: T* ptr; std::atomic<std::size_t>* ref_count;
void release() { if (ref_count && ref_count->fetch_sub(1, std::memory_order_acq_rel) == 1) { delete ptr; delete ref_count; } }
public: shared_ptr() : ptr(nullptr), ref_count(nullptr) {}
explicit shared_ptr(T* p) : ptr(p), ref_count(p ? new std::atomic<std::size_t>(1) : nullptr) {}
~shared_ptr() { release(); }
shared_ptr(const shared_ptr<T>& other) : ptr(other.ptr), ref_count(other.ref_count) { if (ref_count) { ref_count->fetch_add(1, std::memory_order_relaxed); } }
shared_ptr<T>& operator=(const shared_ptr<T>& other) { if (this != &other) { release(); ptr = other.ptr; ref_count = other.ref_count; if (ref_count) { ref_count->fetch_add(1, std::memory_order_relaxed); } } return *this; }
shared_ptr(shared_ptr<T>&& other) noexcept : ptr(other.ptr), ref_count(other.ref_count) { other.ptr = nullptr; other.ref_count = nullptr; }
shared_ptr<T>& operator=(shared_ptr<T>&& other) noexcept { if (this != &other) { release(); ptr = other.ptr; ref_count = other.ref_count; other.ptr = nullptr; other.ref_count = nullptr; } return *this; }
T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }
std::size_t use_count() const { return ref_count ? ref_count->load(std::memory_order_acquire) : 0; }
T* get() const { return ptr; }
void reset(T* p = nullptr) { release(); ptr = p; ref_count = p ? new std::atomic<std::size_t>(1) : nullptr; } };
|