From d412961ac7fc226850df0b9f74531f3690836387 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 17:25:48 +0300 Subject: [PATCH 1/9] shared pointer solution --- .../SharedPointer/src/control/control.h | 68 +++- .../SharedPointer/src/shared_ptr/shared_ptr.h | 311 +++++++++++++++++- 2 files changed, 360 insertions(+), 19 deletions(-) diff --git a/module-1/homework/SharedPointer/src/control/control.h b/module-1/homework/SharedPointer/src/control/control.h index b2fc359b..5fb6c353 100644 --- a/module-1/homework/SharedPointer/src/control/control.h +++ b/module-1/homework/SharedPointer/src/control/control.h @@ -4,25 +4,81 @@ class SharedCount { public: - // Your code goes here... + std::size_t Get() const { + return counter_.load(); + } + + virtual bool Empty() { + return counter_ > 0; + } + + virtual bool Remove() { + if (counter_ == 0) { + return false; + } + + --counter_; + return true; + } + + void Add() { + ++counter_; + } protected: - // Your code goes here... + std::atomic counter_ = 0; }; class SharedWeakCount : public SharedCount { public: - // Your code goes here... + void AddWeak() { + ++weak_counter_; + } + + bool RemoveWeak() { + if (weak_counter_ == 0) { + return false; + } + + --weak_counter_; + return true; + } + + std::size_t GetWeak() const { + return weak_counter_.load(); + } + + bool Empty() override { + return (counter_ == 0) and (weak_counter_ == 0); + } protected: - // Your code goes here... + std::atomic weak_counter_ = 0; }; template class ControlBlock : public SharedWeakCount { public: - // Your code goes here... + explicit ControlBlock(T* value) : value_(value) { + assert(value_ != nullptr); + Add(); + } + + ControlBlock(ControlBlock&) = delete; + void operator=(ControlBlock&) = delete; + + bool Remove() override { + if (SharedCount::Remove()) { + if (Get() == 0) { + Deleter deleter; + deleter(value_); + value_ = nullptr; + } + return true; + } + return false; + } private: - // Your code goes here... + T* value_; }; \ No newline at end of file diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index 2a60bbcf..d6d9e498 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -1,6 +1,51 @@ #pragma once #include "../control/control.h" +#include + +template +struct GetPureType { + using type = T; +}; + +template +struct GetPureType { + using type = T; +}; + +template +struct GetPureType { + using type = T; +}; + +struct TypeDeleter { + template + void operator()(T* p) { + delete p; + } +}; + +struct ArrayDeleter { + template + void operator()(T* p) { + delete[] p; + } +}; + +template +struct ChooseDeleter { + using deleter = TypeDeleter; +}; + +template +struct ChooseDeleter { + using deleter = ArrayDeleter; +}; + +template +struct ChooseDeleter { + using deleter = ArrayDeleter; +}; // SharedPtr template @@ -9,7 +54,8 @@ class WeakPtr; template class SharedPtr { public: - using element_type = // Your code goes here... + using element_type = typename GetPureType::type; + using deleter_type = typename ChooseDeleter::deleter; constexpr SharedPtr() noexcept = default; ~SharedPtr(); @@ -56,24 +102,171 @@ class SharedPtr { friend class WeakPtr; private: - // Your code goes here... + element_type* value_{nullptr}; + SharedWeakCount* counter_{nullptr}; }; +template +SharedPtr MakeShared(Args&&... args) { + return SharedPtr(new T(std::forward(args)...)); +} -// MakeShared -// Your code goes here... -// MakeShared +template +SharedPtr::~SharedPtr() { + if (counter_) { + counter_->Remove(); + if (counter_->Empty()) { + delete counter_; + } + } +} -// SharedPtr -// Your code goes here... -// SharedPtr +template +template +SharedPtr::SharedPtr(Y* p) : value_{p}, counter_{new ControlBlock(p)} { +} + +template +template +SharedPtr::SharedPtr(Y* p, Deleter) noexcept + : value_{p}, counter_{new ControlBlock(p)} { +} + +template +SharedPtr::SharedPtr(const SharedPtr& other) noexcept + : value_{other.value_}, counter_{other.counter_} { + counter_->Add(); +} + +template +SharedPtr::SharedPtr(SharedPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { + other.value_ = nullptr; + other.counter_ = nullptr; +} + +template +SharedPtr& SharedPtr::operator=(const SharedPtr& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + counter_->Add(); + return *this; +} + +template +template +SharedPtr& SharedPtr::operator=(const SharedPtr& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + counter_->Add(); + return *this; +} + +template +SharedPtr& SharedPtr::operator=(SharedPtr&& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + other.value_ = nullptr; + other.counter_ = nullptr; + return *this; +} + +template +template +SharedPtr& SharedPtr::operator=(SharedPtr&& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + other.value_ = nullptr; + other.counter_ = nullptr; + return *this; +} + +template +void SharedPtr::Reset() noexcept { + if (counter_) { + counter_->Remove(); + value_ = nullptr; + counter_ = nullptr; + } +} + +template +template +void SharedPtr::Reset(Y* p) noexcept { + if (counter_) { + counter_->Remove(); + if (counter_->Empty()) { + delete counter_; + } + } + + value_ = p; + counter_ = new ControlBlock(p); +} + +template +template +void SharedPtr::Reset(Y* p, Deleter) noexcept { + if (counter_) { + counter_->Remove(); + if (counter_->Empty()) { + delete counter_; + } + } + + value_ = p; + counter_ = new ControlBlock(p); +} + +template +void SharedPtr::Swap(SharedPtr& other) noexcept { + std::swap(counter_, other.counter_); + std::swap(value_, other.value_); +} + +template +T* SharedPtr::Get() const noexcept { + return value_; +} + +template +int64_t SharedPtr::UseCount() const noexcept { + if (counter_ == nullptr) { + return 0; + } + return counter_->Get(); +} + +template +T& SharedPtr::operator*() const noexcept { + return *value_; +} + +template +T* SharedPtr::operator->() const noexcept { + return value_; +} + +template +typename SharedPtr::element_type& SharedPtr::operator[](std::ptrdiff_t idx) const { + return value_[idx]; +} + +template +SharedPtr::operator bool() const noexcept { + return counter_ != nullptr; +} // WeakPtr template class WeakPtr { public: - using element_type = // Your code goes here... + using element_type = typename GetPureType::type; + using deleter_type = typename ChooseDeleter::deleter; // Special-member functions constexpr WeakPtr() noexcept = default; @@ -100,9 +293,101 @@ class WeakPtr { friend class SharedPtr; public: - // Your code goes here... + element_type* value_{nullptr}; + SharedWeakCount* counter_{nullptr}; }; -// WeakPtr -// Your code goes here... -// WeakPtr \ No newline at end of file +template +template +WeakPtr::WeakPtr(const SharedPtr& other) : value_{other.value_}, counter_{other.counter_} { + counter_->AddWeak(); +} + +template +WeakPtr::WeakPtr(const WeakPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { + counter_->AddWeak(); +} + +template +WeakPtr::WeakPtr(WeakPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { + other.value_ = nullptr; + other.counter_ = nullptr; +} + +template +template +WeakPtr& WeakPtr::operator=(const SharedPtr& other) { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + counter_->AddWeak(); + return *this; +} + +template +WeakPtr& WeakPtr::operator=(const WeakPtr& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + counter_->AddWeak(); + return *this; +} + +template +WeakPtr& WeakPtr::operator=(WeakPtr&& other) noexcept { + Reset(); + value_ = other.value_; + counter_ = other.counter_; + other.value_ = nullptr; + other.counter_ = nullptr; + return this; +} + +template +WeakPtr::~WeakPtr() { + if (counter_ == nullptr) { + assert(value_ == nullptr); + return; + } + + counter_->RemoveWeak(); + if (counter_->Empty()) { + delete counter_; + } +} + +template +void WeakPtr::Reset() noexcept { + if (counter_) { + counter_->RemoveWeak(); + if (counter_->Empty()) { + delete counter_; + } + } + + value_ = nullptr; + counter_ = nullptr; +} + +template +void WeakPtr::Swap(WeakPtr& other) noexcept { + std::swap(value_, other.value_); + std::swap(counter_, other.counter_); +} + +template +bool WeakPtr::Expired() noexcept { + return counter_ == nullptr || counter_->Get() == 0; +} + +template +SharedPtr WeakPtr::Lock() const noexcept { + SharedPtr shared; + if (counter_ == nullptr || counter_->Get() == 0) { + return shared; + } + + shared.value_ = value_; + shared.counter_ = counter_; + return shared; +} \ No newline at end of file From 3b291738fef40cb6b9f1b60701e72d8993f2cdec Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:17:01 +0300 Subject: [PATCH 2/9] fix format 1.0 --- module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index d6d9e498..16513168 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -1,7 +1,6 @@ #pragma once #include "../control/control.h" -#include template struct GetPureType { @@ -139,7 +138,8 @@ SharedPtr::SharedPtr(const SharedPtr& other) noexcept } template -SharedPtr::SharedPtr(SharedPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { +SharedPtr::SharedPtr(SharedPtr&& other) noexcept + : value_{other.value_}, counter_{other.counter_} { other.value_ = nullptr; other.counter_ = nullptr; } From d3307b8b11b5df7ca6ad55bc25d238e5ba601aff Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:19:39 +0300 Subject: [PATCH 3/9] fix format 1.1 --- module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index 16513168..d8eafd35 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -138,7 +138,7 @@ SharedPtr::SharedPtr(const SharedPtr& other) noexcept } template -SharedPtr::SharedPtr(SharedPtr&& other) noexcept +SharedPtr::SharedPtr(SharedPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { other.value_ = nullptr; other.counter_ = nullptr; @@ -304,7 +304,8 @@ WeakPtr::WeakPtr(const SharedPtr& other) : value_{other.value_}, counter_{ } template -WeakPtr::WeakPtr(const WeakPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { +WeakPtr::WeakPtr(const WeakPtr& other) noexcept + : value_{other.value_}, counter_{other.counter_} { counter_->AddWeak(); } From d9f01374aa9e5ac52f5df7776a60aeb2f49ed090 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:24:34 +0300 Subject: [PATCH 4/9] fix format 1.2 --- module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index d8eafd35..500d4083 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -133,7 +133,8 @@ SharedPtr::SharedPtr(Y* p, Deleter) noexcept template SharedPtr::SharedPtr(const SharedPtr& other) noexcept - : value_{other.value_}, counter_{other.counter_} { + : value_{other.value_}, + counter_{other.counter_} { counter_->Add(); } @@ -305,7 +306,8 @@ WeakPtr::WeakPtr(const SharedPtr& other) : value_{other.value_}, counter_{ template WeakPtr::WeakPtr(const WeakPtr& other) noexcept - : value_{other.value_}, counter_{other.counter_} { + : value_{other.value_}, + counter_{other.counter_} { counter_->AddWeak(); } From 3ca13eb448c13bdf981f95197d5db39cb10f613f Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:27:06 +0300 Subject: [PATCH 5/9] fix format 1.3 --- .../homework/SharedPointer/src/shared_ptr/shared_ptr.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index 500d4083..7434058e 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -132,9 +132,7 @@ SharedPtr::SharedPtr(Y* p, Deleter) noexcept } template -SharedPtr::SharedPtr(const SharedPtr& other) noexcept - : value_{other.value_}, - counter_{other.counter_} { +SharedPtr::SharedPtr(const SharedPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { counter_->Add(); } @@ -305,9 +303,7 @@ WeakPtr::WeakPtr(const SharedPtr& other) : value_{other.value_}, counter_{ } template -WeakPtr::WeakPtr(const WeakPtr& other) noexcept - : value_{other.value_}, - counter_{other.counter_} { +WeakPtr::WeakPtr(const WeakPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { counter_->AddWeak(); } From f7d85b04401950e4bc752ffe2401c028957520f3 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:31:20 +0300 Subject: [PATCH 6/9] fix format 1.4 --- module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index 7434058e..f1c710df 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -137,8 +137,7 @@ SharedPtr::SharedPtr(const SharedPtr& other) noexcept : value_{other.value_}, } template -SharedPtr::SharedPtr(SharedPtr&& other) noexcept - : value_{other.value_}, counter_{other.counter_} { +SharedPtr::SharedPtr(SharedPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { other.value_ = nullptr; other.counter_ = nullptr; } From c0e88cd48dfac7a01f247cda7844c510850a80c8 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 18:34:53 +0300 Subject: [PATCH 7/9] fix format 1.5 --- .../homework/SharedPointer/src/shared_ptr/shared_ptr.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h index f1c710df..5cb1eea2 100644 --- a/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h +++ b/module-1/homework/SharedPointer/src/shared_ptr/shared_ptr.h @@ -132,12 +132,14 @@ SharedPtr::SharedPtr(Y* p, Deleter) noexcept } template -SharedPtr::SharedPtr(const SharedPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { +SharedPtr::SharedPtr(const SharedPtr& other) noexcept + : value_{other.value_}, counter_{other.counter_} { counter_->Add(); } template -SharedPtr::SharedPtr(SharedPtr&& other) noexcept : value_{other.value_}, counter_{other.counter_} { +SharedPtr::SharedPtr(SharedPtr&& other) noexcept + : value_{other.value_}, counter_{other.counter_} { other.value_ = nullptr; other.counter_ = nullptr; } @@ -302,7 +304,8 @@ WeakPtr::WeakPtr(const SharedPtr& other) : value_{other.value_}, counter_{ } template -WeakPtr::WeakPtr(const WeakPtr& other) noexcept : value_{other.value_}, counter_{other.counter_} { +WeakPtr::WeakPtr(const WeakPtr& other) noexcept + : value_{other.value_}, counter_{other.counter_} { counter_->AddWeak(); } From fe5ebbe2ab4271e9ff86fa98a30b142d8ca10e52 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 19:49:49 +0300 Subject: [PATCH 8/9] fix style --- module-1/homework/SharedPointer/src/control/control.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module-1/homework/SharedPointer/src/control/control.h b/module-1/homework/SharedPointer/src/control/control.h index 5fb6c353..0c98457c 100644 --- a/module-1/homework/SharedPointer/src/control/control.h +++ b/module-1/homework/SharedPointer/src/control/control.h @@ -4,7 +4,7 @@ class SharedCount { public: - std::size_t Get() const { + size_t Get() const { return counter_.load(); } @@ -26,7 +26,7 @@ class SharedCount { } protected: - std::atomic counter_ = 0; + std::atomic counter_ {0}; }; class SharedWeakCount : public SharedCount { @@ -44,7 +44,7 @@ class SharedWeakCount : public SharedCount { return true; } - std::size_t GetWeak() const { + size_t GetWeak() const { return weak_counter_.load(); } @@ -53,13 +53,13 @@ class SharedWeakCount : public SharedCount { } protected: - std::atomic weak_counter_ = 0; + std::atomic weak_counter_{0}; }; template class ControlBlock : public SharedWeakCount { public: - explicit ControlBlock(T* value) : value_(value) { + explicit ControlBlock(T* value) : value_{value} { assert(value_ != nullptr); Add(); } From 639369caff35a934791a4b5f129ac7394107afea Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 19:52:32 +0300 Subject: [PATCH 9/9] fix style 1.1 --- module-1/homework/SharedPointer/src/control/control.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module-1/homework/SharedPointer/src/control/control.h b/module-1/homework/SharedPointer/src/control/control.h index 0c98457c..ca32b3ce 100644 --- a/module-1/homework/SharedPointer/src/control/control.h +++ b/module-1/homework/SharedPointer/src/control/control.h @@ -26,7 +26,7 @@ class SharedCount { } protected: - std::atomic counter_ {0}; + std::atomic counter_{0}; }; class SharedWeakCount : public SharedCount {