Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.83 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <string>
  4.  
  5. class WeakPtr;
  6.  
  7. class ObjectWrapper {
  8. public:
  9.     explicit ObjectWrapper(std::string* ptr = nullptr);
  10.  
  11.     void DeleteObject();
  12.  
  13.     size_t GetRefCount() const;
  14.     size_t GetWeakRefCount() const;
  15.  
  16.     void IncrementRefCount();
  17.     void IncrementWeakRefCount();
  18.  
  19.     bool DecrementRefCount();
  20.     bool DecrementWeakRefCount();
  21.  
  22.     std::string* Get() const;
  23.  
  24.     bool TryFreeAndReportEmpty();
  25.  
  26.     ~ObjectWrapper();
  27.  
  28. private:
  29.     std::string* ptr_;
  30.     size_t ref_count_ = 0;
  31.     size_t weak_ref_count_ = 0;
  32. };
  33.  
  34. class SharedPtr {
  35. public:
  36.     explicit SharedPtr(std::string* ptr = nullptr);
  37.     SharedPtr(const SharedPtr& other);
  38.     SharedPtr(SharedPtr&& other) noexcept;
  39.  
  40.     SharedPtr& operator=(const SharedPtr& rhs);
  41.     SharedPtr& operator=(SharedPtr&& rhs) noexcept;
  42.  
  43.     explicit SharedPtr(const WeakPtr& w_ptr);
  44.  
  45.     std::string* Get() const;
  46.  
  47.     std::string& operator*() const;
  48.  
  49.     std::string* operator->() const;
  50.  
  51.     void Reset(std::string* new_managed_ptr);
  52.  
  53.     ObjectWrapper* GetWrapper() const;
  54.  
  55.     ~SharedPtr();
  56.  
  57. private:
  58.     void ReleaseOwnership();
  59.  
  60.     void UpdateFields(std::string* ptr, ObjectWrapper* wrapper, bool increment_ref_count = true);
  61.  
  62.     std::string* ptr_ = nullptr;
  63.     ObjectWrapper* wrapper_ = nullptr;
  64. };
  65.  
  66. class WeakPtr {
  67. public:
  68.     WeakPtr() = default;
  69.     WeakPtr(const WeakPtr& other);
  70.     WeakPtr(WeakPtr&& other) noexcept;
  71.  
  72.     WeakPtr& operator=(const WeakPtr& other);
  73.     WeakPtr& operator=(WeakPtr&& other) noexcept;
  74.  
  75.     explicit WeakPtr(const SharedPtr& other);
  76.  
  77.     ObjectWrapper* GetWrapper() const;
  78.  
  79.     SharedPtr Lock();
  80.  
  81.     bool IsExpired();
  82.  
  83.     ~WeakPtr() {
  84.         Release();
  85.     };
  86.  
  87. private:
  88.     void Release();
  89.  
  90.     ObjectWrapper* wrapper_ = nullptr;
  91. };
  92.  
  93. SharedPtr::SharedPtr(std::string* ptr) {
  94.     UpdateFields(ptr, new ObjectWrapper(ptr), true);
  95. }
  96.  
  97. SharedPtr::SharedPtr(const SharedPtr& other) {
  98.     UpdateFields(other.ptr_, other.wrapper_, true);
  99. }
  100.  
  101. SharedPtr::SharedPtr(SharedPtr&& other) noexcept {
  102.     UpdateFields(other.ptr_, other.wrapper_, false);
  103.     other.UpdateFields(nullptr, nullptr, false);
  104. }
  105.  
  106. SharedPtr& SharedPtr::operator=(const SharedPtr& rhs) {
  107.     ReleaseOwnership();
  108.     UpdateFields(rhs.ptr_, rhs.wrapper_, true);
  109.     return *this;
  110. }
  111.  
  112. SharedPtr& SharedPtr::operator=(SharedPtr&& rhs) noexcept {
  113.     if (this != &rhs) {
  114.         ReleaseOwnership();
  115.         UpdateFields(rhs.ptr_, rhs.wrapper_, false);
  116.         rhs.UpdateFields(nullptr, nullptr, false);
  117.     }
  118.     return *this;
  119. }
  120.  
  121. SharedPtr::SharedPtr(const WeakPtr& w_ptr) {
  122.     UpdateFields(w_ptr.GetWrapper()->Get(), w_ptr.GetWrapper(), true);
  123. }
  124.  
  125. std::string* SharedPtr::Get() const {
  126.     return ptr_;
  127. }
  128.  
  129. std::string& SharedPtr::operator*() const {
  130.     return *ptr_;
  131. }
  132.  
  133. std::string* SharedPtr::operator->() const {
  134.     return ptr_;
  135. }
  136.  
  137. void SharedPtr::Reset(std::string* new_managed_ptr) {
  138.     ReleaseOwnership();
  139.     UpdateFields(new_managed_ptr, new ObjectWrapper(new_managed_ptr), true);
  140. }
  141.  
  142. SharedPtr::~SharedPtr() {
  143.     ReleaseOwnership();
  144. }
  145.  
  146. void SharedPtr::ReleaseOwnership() {
  147.     if (wrapper_ != nullptr && wrapper_->DecrementRefCount()) {
  148.         delete wrapper_;
  149.     }
  150. }
  151.  
  152. void SharedPtr::UpdateFields(std::string* ptr, ObjectWrapper* wrapper, bool increment_ref_count) {
  153.     ptr_ = ptr;
  154.     wrapper_ = wrapper;
  155.     if (increment_ref_count) {
  156.         wrapper_->IncrementRefCount();
  157.     }
  158. }
  159.  
  160. ObjectWrapper* SharedPtr::GetWrapper() const {
  161.     return wrapper_;
  162. }
  163.  
  164. ObjectWrapper::ObjectWrapper(std::string* ptr) : ptr_{ptr} {
  165. }
  166.  
  167. ObjectWrapper::~ObjectWrapper() {
  168.     if (ref_count_ == 0) {
  169.         DeleteObject();
  170.     }
  171. }
  172.  
  173. void ObjectWrapper::DeleteObject() {
  174.     delete ptr_;
  175.     ptr_ = nullptr;
  176. }
  177.  
  178. size_t ObjectWrapper::GetRefCount() const {
  179.     return ref_count_;
  180. }
  181.  
  182. size_t ObjectWrapper::GetWeakRefCount() const {
  183.     return weak_ref_count_;
  184. }
  185.  
  186. void ObjectWrapper::IncrementRefCount() {
  187.     ++ref_count_;
  188. }
  189.  
  190. void ObjectWrapper::IncrementWeakRefCount() {
  191.     ++weak_ref_count_;
  192. }
  193.  
  194. bool ObjectWrapper::DecrementRefCount() {
  195.     if (ref_count_ > 0) {
  196.         --ref_count_;
  197.     }
  198.     return TryFreeAndReportEmpty();
  199. }
  200.  
  201. bool ObjectWrapper::DecrementWeakRefCount() {
  202.     if (weak_ref_count_ > 0) {
  203.         --weak_ref_count_;
  204.     }
  205.     return TryFreeAndReportEmpty();
  206. }
  207.  
  208. std::string* ObjectWrapper::Get() const {
  209.     return ptr_;
  210. }
  211.  
  212. bool ObjectWrapper::TryFreeAndReportEmpty() {
  213.     if (ref_count_ == 0) {
  214.         DeleteObject();
  215.         return weak_ref_count_ == 0;
  216.     }
  217.     return false;
  218. }
  219.  
  220. WeakPtr::WeakPtr(const WeakPtr& other) {
  221.     wrapper_ = other.wrapper_;
  222.     if (wrapper_ != nullptr) {
  223.         wrapper_->IncrementWeakRefCount();
  224.     }
  225. }
  226.  
  227. WeakPtr::WeakPtr(WeakPtr&& other) noexcept {
  228.     wrapper_ = other.wrapper_;
  229.     other.wrapper_ = nullptr;
  230. }
  231.  
  232. WeakPtr& WeakPtr::operator=(const WeakPtr& other) {
  233.     Release();
  234.     wrapper_ = other.wrapper_;
  235.     if (wrapper_ != nullptr) {
  236.         wrapper_->IncrementWeakRefCount();
  237.     }
  238.     return *this;
  239. }
  240.  
  241. WeakPtr& WeakPtr::operator=(WeakPtr&& other) noexcept {
  242.     if (this != &other) {
  243.         Release();
  244.         wrapper_ = other.wrapper_;
  245.         other.wrapper_ = nullptr;
  246.     }
  247.     return *this;
  248. }
  249.  
  250. ObjectWrapper* WeakPtr::GetWrapper() const {
  251.     return wrapper_;
  252. }
  253.  
  254. SharedPtr WeakPtr::Lock() {
  255.     return (IsExpired()) ? SharedPtr() : SharedPtr(*this);
  256. }
  257.  
  258. bool WeakPtr::IsExpired() {
  259.     return wrapper_ == nullptr || wrapper_->GetRefCount() == 0;
  260. }
  261.  
  262. void WeakPtr::Release() {
  263.     if (wrapper_ != nullptr && wrapper_->DecrementWeakRefCount()) {
  264.         delete wrapper_;
  265.         wrapper_ = nullptr;
  266.     }
  267. }
  268.  
  269. WeakPtr::WeakPtr(const SharedPtr& other) {
  270.     wrapper_ = other.GetWrapper();
  271.     if (wrapper_ != nullptr) {
  272.         wrapper_->IncrementWeakRefCount();
  273.     }
  274. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement