Advertisement
Ilya_konstantinov

shared_aliasing

Oct 10th, 2024
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.49 KB | Source Code | 0 0
  1. // #pragma once
  2.  
  3. #include "sw_fwd.h"  // Forward declaration
  4.  
  5. #include <cstddef>  // std::nullptr_t
  6. #include <iostream>
  7. #include <array>
  8. #include <utility>
  9.  
  10. template <typename T>
  11. class SharedPtr {
  12. private:
  13.  
  14.     struct ControlBlockBase {
  15.         size_t strong_counter_, weak_counter_;
  16.         ControlBlockBase() : strong_counter_(1), weak_counter_ (0) {}
  17.         virtual void ObjClear() {}
  18.         virtual void WeakCounterDec() {}
  19.         virtual void StrongCounterDec() {}
  20.         virtual T* Get() const { return nullptr; }
  21.         virtual T* Get() { return nullptr; }
  22.  
  23.         void WeakCounterInc() {
  24.             ++weak_counter_;
  25.         }
  26.        
  27.         void StrongCounterInc() {
  28.             ++strong_counter_;
  29.         }
  30.  
  31.  
  32.     };
  33.    
  34.     struct ControlBlockPtr : public ControlBlockBase {
  35.         T* ptr_;
  36.  
  37.         ControlBlockPtr(std::nullptr_t) : ControlBlockBase(), ptr_(nullptr) {}
  38.         ControlBlockPtr(T* ptr) : ControlBlockBase(), ptr_(ptr) {}
  39.  
  40.         void WeakCounterDec() override {
  41.             --(this->weak_counter_);
  42.             if (!this->weak_counter_ && !this->strong_counter_) {
  43.                 delete this;
  44.             }
  45.         }
  46.  
  47.         void StrongCounterDec() override {
  48.             --this->strong_counter_;
  49.             if (!this->strong_counter_) {
  50.                 ObjClear();
  51.                 if (!this->weak_counter_) {
  52.                     delete this;
  53.                     std::cout << "\nthat's all\n";
  54.                 }
  55.             }
  56.         }
  57.  
  58.         void ObjClear() override {
  59.             if (ptr_) {
  60.                 delete ptr_;
  61.             }
  62.         }
  63.  
  64.         T* Get() const override {
  65.             return ptr_;
  66.         }
  67.  
  68.         T* Get() override {
  69.             return ptr_;
  70.         }
  71.  
  72.     };
  73.  
  74.     T *ptr_;
  75.     ControlBlockBase *cb_;
  76.  
  77. public:
  78.     ControlBlockBase* GetControlBlock() const {
  79.         return cb_;
  80.     }
  81.  
  82.     ////////////////////////////////////////////////////////////////////////////////////////////////
  83.     // Constructors
  84.  
  85.     SharedPtr() {
  86.         cb_ = nullptr;
  87.         ptr_ = nullptr;
  88.     }
  89.    
  90.     SharedPtr(std::nullptr_t) {
  91.         cb_ = nullptr;
  92.         ptr_ = nullptr;
  93.     }
  94.  
  95.     explicit SharedPtr(T* ptr) : ptr_(ptr) {
  96.         cb_ = new ControlBlockPtr(ptr);
  97.     }
  98.  
  99.     // Aliasing constructor
  100.     // #8 from https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
  101.     template <typename Y>
  102.     SharedPtr(const SharedPtr<Y>& other, T* ptr = nullptr) {
  103.         cb_ = reinterpret_cast<ControlBlockBase*>(other.GetControlBlock());
  104.         cb_->StrongCounterInc();
  105.         ptr_ = ptr;
  106.     }
  107.     ////////////////////////////////////////////////////////////////////////////////////////////////
  108.     // `operator=`-s
  109.  
  110.     SharedPtr& operator=(const SharedPtr& other) {
  111.         this->~SharedPtr();
  112.         cb_ = other.cb_;
  113.         ptr_ = other.ptr_;
  114.         if (cb_) {
  115.             cb_->StrongCounterInc();
  116.         }
  117.         return *this;
  118.     }
  119.     ////////////////////////////////////////////////////////////////////////////////////////////////
  120.     // Destructor
  121.  
  122.     ~SharedPtr() {
  123.         if (cb_) {
  124.             cb_->StrongCounterDec();
  125.         }
  126.         ptr_ = nullptr;
  127.     }
  128.  
  129.     ////////////////////////////////////////////////////////////////////////////////////////////////
  130.     // Observers
  131.  
  132.     T* Get() const {
  133.         return ptr_;
  134.     }
  135.  
  136.     T& operator*() const {
  137.         return *ptr_;
  138.     }
  139.  
  140.     T* operator->() const {
  141.         return ptr_;
  142.     }
  143. };
  144.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement