| 9 | // std::weak_ptr compatible implementation |
| 10 | template<typename T> |
| 11 | class weak_ptr { |
| 12 | private: |
| 13 | T* mPtr; |
| 14 | detail::ControlBlockBase* mControlBlock; |
| 15 | |
| 16 | public: |
| 17 | using element_type = T; |
| 18 | |
| 19 | // Default constructor |
| 20 | weak_ptr() FL_NOEXCEPT : mPtr(nullptr), mControlBlock(nullptr) {} |
| 21 | |
| 22 | // Copy constructor |
| 23 | weak_ptr(const weak_ptr& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) { |
| 24 | if (mControlBlock) { |
| 25 | ++mControlBlock->weak_count; |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | // Converting copy constructor |
| 30 | template<typename Y> |
| 31 | weak_ptr(const weak_ptr<Y>& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) { |
| 32 | if (mControlBlock) { |
| 33 | ++mControlBlock->weak_count; |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | // Constructor from shared_ptr |
| 38 | template<typename Y> |
| 39 | weak_ptr(const shared_ptr<Y>& shared) FL_NOEXCEPT : mPtr(shared.mPtr), mControlBlock(shared.mControlBlock) { |
| 40 | if (mControlBlock) { |
| 41 | ++mControlBlock->weak_count; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | // Move constructor |
| 46 | weak_ptr(weak_ptr&& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) { |
| 47 | other.mPtr = nullptr; |
| 48 | other.mControlBlock = nullptr; |
| 49 | } |
| 50 | |
| 51 | // Converting move constructor |
| 52 | template<typename Y> |
| 53 | weak_ptr(weak_ptr<Y>&& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) { |
| 54 | other.mPtr = nullptr; |
| 55 | other.mControlBlock = nullptr; |
| 56 | } |
| 57 | |
| 58 | // Destructor |
| 59 | ~weak_ptr() FL_NOEXCEPT { |
| 60 | release(); |
| 61 | } |
| 62 | |
| 63 | // Assignment operators |
| 64 | weak_ptr& operator=(const weak_ptr& other) FL_NOEXCEPT { |
| 65 | if (this != &other) { |
| 66 | release(); |
| 67 | mPtr = other.mPtr; |
| 68 | mControlBlock = other.mControlBlock; |