Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <string>
- class WeakPtr;
- class ObjectWrapper {
- public:
- explicit ObjectWrapper(std::string* ptr = nullptr);
- void DeleteObject();
- size_t GetRefCount() const;
- size_t GetWeakRefCount() const;
- void IncrementRefCount();
- void IncrementWeakRefCount();
- bool DecrementRefCount();
- bool DecrementWeakRefCount();
- std::string* Get() const;
- bool TryFreeAndReportEmpty();
- ~ObjectWrapper();
- private:
- std::string* ptr_;
- size_t ref_count_ = 0;
- size_t weak_ref_count_ = 0;
- };
- class SharedPtr {
- public:
- explicit SharedPtr(std::string* ptr = nullptr);
- SharedPtr(const SharedPtr& other);
- SharedPtr(SharedPtr&& other) noexcept;
- SharedPtr& operator=(const SharedPtr& rhs);
- SharedPtr& operator=(SharedPtr&& rhs) noexcept;
- explicit SharedPtr(const WeakPtr& w_ptr);
- std::string* Get() const;
- std::string& operator*() const;
- std::string* operator->() const;
- void Reset(std::string* new_managed_ptr);
- ObjectWrapper* GetWrapper() const;
- ~SharedPtr();
- private:
- void ReleaseOwnership();
- void UpdateFields(std::string* ptr, ObjectWrapper* wrapper, bool increment_ref_count = true);
- std::string* ptr_ = nullptr;
- ObjectWrapper* wrapper_ = nullptr;
- };
- class WeakPtr {
- public:
- WeakPtr() = default;
- WeakPtr(const WeakPtr& other);
- WeakPtr(WeakPtr&& other) noexcept;
- WeakPtr& operator=(const WeakPtr& other);
- WeakPtr& operator=(WeakPtr&& other) noexcept;
- explicit WeakPtr(const SharedPtr& other);
- ObjectWrapper* GetWrapper() const;
- SharedPtr Lock();
- bool IsExpired();
- ~WeakPtr() {
- Release();
- };
- private:
- void Release();
- ObjectWrapper* wrapper_ = nullptr;
- };
- SharedPtr::SharedPtr(std::string* ptr) {
- UpdateFields(ptr, new ObjectWrapper(ptr), true);
- }
- SharedPtr::SharedPtr(const SharedPtr& other) {
- UpdateFields(other.ptr_, other.wrapper_, true);
- }
- SharedPtr::SharedPtr(SharedPtr&& other) noexcept {
- UpdateFields(other.ptr_, other.wrapper_, false);
- other.UpdateFields(nullptr, nullptr, false);
- }
- SharedPtr& SharedPtr::operator=(const SharedPtr& rhs) {
- ReleaseOwnership();
- UpdateFields(rhs.ptr_, rhs.wrapper_, true);
- return *this;
- }
- SharedPtr& SharedPtr::operator=(SharedPtr&& rhs) noexcept {
- if (this != &rhs) {
- ReleaseOwnership();
- UpdateFields(rhs.ptr_, rhs.wrapper_, false);
- rhs.UpdateFields(nullptr, nullptr, false);
- }
- return *this;
- }
- SharedPtr::SharedPtr(const WeakPtr& w_ptr) {
- UpdateFields(w_ptr.GetWrapper()->Get(), w_ptr.GetWrapper(), true);
- }
- std::string* SharedPtr::Get() const {
- return ptr_;
- }
- std::string& SharedPtr::operator*() const {
- return *ptr_;
- }
- std::string* SharedPtr::operator->() const {
- return ptr_;
- }
- void SharedPtr::Reset(std::string* new_managed_ptr) {
- ReleaseOwnership();
- UpdateFields(new_managed_ptr, new ObjectWrapper(new_managed_ptr), true);
- }
- SharedPtr::~SharedPtr() {
- ReleaseOwnership();
- }
- void SharedPtr::ReleaseOwnership() {
- if (wrapper_ != nullptr && wrapper_->DecrementRefCount()) {
- delete wrapper_;
- }
- }
- void SharedPtr::UpdateFields(std::string* ptr, ObjectWrapper* wrapper, bool increment_ref_count) {
- ptr_ = ptr;
- wrapper_ = wrapper;
- if (increment_ref_count) {
- wrapper_->IncrementRefCount();
- }
- }
- ObjectWrapper* SharedPtr::GetWrapper() const {
- return wrapper_;
- }
- ObjectWrapper::ObjectWrapper(std::string* ptr) : ptr_{ptr} {
- }
- ObjectWrapper::~ObjectWrapper() {
- if (ref_count_ == 0) {
- DeleteObject();
- }
- }
- void ObjectWrapper::DeleteObject() {
- delete ptr_;
- ptr_ = nullptr;
- }
- size_t ObjectWrapper::GetRefCount() const {
- return ref_count_;
- }
- size_t ObjectWrapper::GetWeakRefCount() const {
- return weak_ref_count_;
- }
- void ObjectWrapper::IncrementRefCount() {
- ++ref_count_;
- }
- void ObjectWrapper::IncrementWeakRefCount() {
- ++weak_ref_count_;
- }
- bool ObjectWrapper::DecrementRefCount() {
- if (ref_count_ > 0) {
- --ref_count_;
- }
- return TryFreeAndReportEmpty();
- }
- bool ObjectWrapper::DecrementWeakRefCount() {
- if (weak_ref_count_ > 0) {
- --weak_ref_count_;
- }
- return TryFreeAndReportEmpty();
- }
- std::string* ObjectWrapper::Get() const {
- return ptr_;
- }
- bool ObjectWrapper::TryFreeAndReportEmpty() {
- if (ref_count_ == 0) {
- DeleteObject();
- return weak_ref_count_ == 0;
- }
- return false;
- }
- WeakPtr::WeakPtr(const WeakPtr& other) {
- wrapper_ = other.wrapper_;
- if (wrapper_ != nullptr) {
- wrapper_->IncrementWeakRefCount();
- }
- }
- WeakPtr::WeakPtr(WeakPtr&& other) noexcept {
- wrapper_ = other.wrapper_;
- other.wrapper_ = nullptr;
- }
- WeakPtr& WeakPtr::operator=(const WeakPtr& other) {
- Release();
- wrapper_ = other.wrapper_;
- if (wrapper_ != nullptr) {
- wrapper_->IncrementWeakRefCount();
- }
- return *this;
- }
- WeakPtr& WeakPtr::operator=(WeakPtr&& other) noexcept {
- if (this != &other) {
- Release();
- wrapper_ = other.wrapper_;
- other.wrapper_ = nullptr;
- }
- return *this;
- }
- ObjectWrapper* WeakPtr::GetWrapper() const {
- return wrapper_;
- }
- SharedPtr WeakPtr::Lock() {
- return (IsExpired()) ? SharedPtr() : SharedPtr(*this);
- }
- bool WeakPtr::IsExpired() {
- return wrapper_ == nullptr || wrapper_->GetRefCount() == 0;
- }
- void WeakPtr::Release() {
- if (wrapper_ != nullptr && wrapper_->DecrementWeakRefCount()) {
- delete wrapper_;
- wrapper_ = nullptr;
- }
- }
- WeakPtr::WeakPtr(const SharedPtr& other) {
- wrapper_ = other.GetWrapper();
- if (wrapper_ != nullptr) {
- wrapper_->IncrementWeakRefCount();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement