Advertisement
AntonGorokhov

Untitled

Oct 1st, 2022
930
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.77 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "sw_fwd.h"  // Forward declaration
  4. #include "shared.h"
  5.  
  6. // https://en.cppreference.com/w/cpp/memory/weak_ptr
  7. template <typename T>
  8. class WeakPtr {
  9. public:
  10.     ////////////////////////////////////////////////////////////////////////////////////////////////
  11.     // Constructors
  12.  
  13.     WeakPtr() {
  14.     }
  15.  
  16.     WeakPtr(const WeakPtr& other) {
  17.         if (this != &other) {
  18.             block_ = other.block_;
  19.             ptr_ = other.ptr_;
  20.             if (block_) {
  21.                 ++block_->cnt_weak;
  22.             }
  23.         }
  24.     }
  25.  
  26.     template <class Y>
  27.     WeakPtr(const WeakPtr<Y>& other) {
  28.         block_ = other.block_;
  29.         ptr_ = other.ptr_;
  30.         if (block_) {
  31.             ++block_->cnt_weak;
  32.         }
  33.     }
  34.  
  35.     WeakPtr(WeakPtr&& other) {
  36.         if (this != &other) {
  37.             block_ = other.block_;
  38.             ptr_ = other.ptr_;
  39.             other.block_ = nullptr;
  40.             other.ptr_ = nullptr;
  41.         }
  42.     }
  43.  
  44.     // Demote `SharedPtr`
  45.     // #2 from https://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr
  46.     WeakPtr(const SharedPtr<T>& other) {
  47.         block_ = other.block_;
  48.         ptr_ = other.ptr_;
  49.         if (block_) {
  50.             ++block_->cnt_weak;
  51.         }
  52.     }
  53.  
  54.     WeakPtr& operator=(const SharedPtr<T>& other) {
  55.         Reset();
  56.         block_ = other.block_;
  57.         ptr_ = other.ptr_;
  58.         if (block_) {
  59.             ++block_->cnt_weak;
  60.         }
  61.         return *this;
  62.     }
  63.  
  64.     template <class Y>
  65.     WeakPtr& operator=(const SharedPtr<Y>& other) {
  66.         Reset();
  67.         block_ = other.block_;
  68.         ptr_ = other.ptr_;
  69.         if (block_) {
  70.             ++block_->cnt_weak;
  71.         }
  72.         return *this;
  73.     }
  74.  
  75.     ////////////////////////////////////////////////////////////////////////////////////////////////
  76.     // `operator=`-s
  77.  
  78.     WeakPtr& operator=(const WeakPtr& other) {
  79.         if (this != &other) {
  80.             Reset();
  81.             block_ = other.block_;
  82.             ptr_ = other.ptr_;
  83.             if (block_) {
  84.                 ++block_->cnt_weak;
  85.             }
  86.         }
  87.         return *this;
  88.     }
  89.     WeakPtr& operator=(WeakPtr&& other) {
  90.         if (this != &other) {
  91.             Reset();
  92.             block_ = other.block_;
  93.             ptr_ = other.ptr_;
  94.             other.block_ = nullptr;
  95.             other.ptr_ = nullptr;
  96.         }
  97.         return *this;
  98.     }
  99.  
  100.     ////////////////////////////////////////////////////////////////////////////////////////////////
  101.     // Destructor
  102.  
  103.     ~WeakPtr() {
  104.         Reset();
  105.     }
  106.  
  107.     ////////////////////////////////////////////////////////////////////////////////////////////////
  108.     // Modifiers
  109.  
  110.     void Reset() {
  111.         if (block_) {
  112.             --block_->cnt_weak;
  113.             if (block_->cnt_weak == 0 && block_->cnt == 0) {
  114.                 delete block_;
  115.             }
  116.         }
  117.         block_ = nullptr;
  118.         ptr_ = nullptr;
  119.     }
  120.     void Swap(WeakPtr& other) {
  121.         std::swap(block_, other.block_);
  122.         std::swap(ptr_, other.ptr_);
  123.     }
  124.  
  125.     ////////////////////////////////////////////////////////////////////////////////////////////////
  126.     // Observers
  127.  
  128.     size_t UseCount() const {
  129.         if (!block_) {
  130.             return 0;
  131.         }
  132.         return block_->cnt;
  133.     }
  134.     bool Expired() const {
  135.         if (ptr_ == nullptr) {
  136.             return true;
  137.         }
  138.         if (block_ == nullptr) {
  139.             return true;
  140.         }
  141.         if (block_->cnt == 0) {
  142.             return true;
  143.         }
  144.         return false;
  145.     }
  146.     SharedPtr<T> Lock() const {
  147.         if (block_) {
  148.             return SharedPtr<T>(block_, ptr_, true);
  149.         }
  150.         return SharedPtr<T>(nullptr);
  151.     }
  152.     BlockBase* block_ = nullptr;
  153.     T* ptr_ = nullptr;
  154. };
  155.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement