Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // #pragma once
- #include "sw_fwd.h" // Forward declaration
- #include <cstddef> // std::nullptr_t
- #include <iostream>
- #include <array>
- #include <utility>
- template <typename T>
- class SharedPtr {
- private:
- struct ControlBlockBase {
- size_t strong_counter_, weak_counter_;
- ControlBlockBase() : strong_counter_(1), weak_counter_ (0) {}
- virtual void ObjClear() {}
- virtual void WeakCounterDec() {}
- virtual void StrongCounterDec() {}
- virtual T* Get() const { return nullptr; }
- virtual T* Get() { return nullptr; }
- void WeakCounterInc() {
- ++weak_counter_;
- }
- void StrongCounterInc() {
- ++strong_counter_;
- }
- };
- struct ControlBlockPtr : public ControlBlockBase {
- T* ptr_;
- ControlBlockPtr(std::nullptr_t) : ControlBlockBase(), ptr_(nullptr) {}
- ControlBlockPtr(T* ptr) : ControlBlockBase(), ptr_(ptr) {}
- void WeakCounterDec() override {
- --(this->weak_counter_);
- if (!this->weak_counter_ && !this->strong_counter_) {
- delete this;
- }
- }
- void StrongCounterDec() override {
- --this->strong_counter_;
- if (!this->strong_counter_) {
- ObjClear();
- if (!this->weak_counter_) {
- delete this;
- std::cout << "\nthat's all\n";
- }
- }
- }
- void ObjClear() override {
- if (ptr_) {
- delete ptr_;
- }
- }
- T* Get() const override {
- return ptr_;
- }
- T* Get() override {
- return ptr_;
- }
- };
- T *ptr_;
- ControlBlockBase *cb_;
- public:
- ControlBlockBase* GetControlBlock() const {
- return cb_;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Constructors
- SharedPtr() {
- cb_ = nullptr;
- ptr_ = nullptr;
- }
- SharedPtr(std::nullptr_t) {
- cb_ = nullptr;
- ptr_ = nullptr;
- }
- explicit SharedPtr(T* ptr) : ptr_(ptr) {
- cb_ = new ControlBlockPtr(ptr);
- }
- // Aliasing constructor
- // #8 from https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
- template <typename Y>
- SharedPtr(const SharedPtr<Y>& other, T* ptr = nullptr) {
- cb_ = reinterpret_cast<ControlBlockBase*>(other.GetControlBlock());
- cb_->StrongCounterInc();
- ptr_ = ptr;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // `operator=`-s
- SharedPtr& operator=(const SharedPtr& other) {
- this->~SharedPtr();
- cb_ = other.cb_;
- ptr_ = other.ptr_;
- if (cb_) {
- cb_->StrongCounterInc();
- }
- return *this;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Destructor
- ~SharedPtr() {
- if (cb_) {
- cb_->StrongCounterDec();
- }
- ptr_ = nullptr;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Observers
- T* Get() const {
- return ptr_;
- }
- T& operator*() const {
- return *ptr_;
- }
- T* operator->() const {
- return ptr_;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement