From 45a0b765a4f78ca1d50d928f0360aa437598b104 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Mon, 9 Dec 2024 16:07:33 -0500 Subject: [PATCH] remaining issues are private/protected destructors and the pointer casts --- SharedPtr.hpp | 163 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 121 insertions(+), 42 deletions(-) diff --git a/SharedPtr.hpp b/SharedPtr.hpp index d4bd143..82bb20c 100644 --- a/SharedPtr.hpp +++ b/SharedPtr.hpp @@ -1,3 +1,4 @@ +#include #ifndef _POWELLCS440 #include #include @@ -7,65 +8,143 @@ assert(false); namespace cs440 { -template class SharedPtr { +using counter = std::atomic; +template class SharedPtr; +class Key { + Key() {} + public: - SharedPtr() { todo("incomplete") } + template friend class SharedPtr; + template void increment(SharedPtr const &ptr) { + const_cast &>(*ptr.count)++; + } + template counter *get_counter(SharedPtr const &ptr) { + return const_cast *>(ptr.count); + } + template U *get_ptr(SharedPtr const &ptr) { + return const_cast(ptr.ptr); + } + template void nullify(SharedPtr &&ptr) { + ptr.ptr = nullptr; + ptr.count = nullptr; + } +}; +template class SharedPtr { + T *ptr; + std::atomic *count; + +public: + friend class Key; + SharedPtr() : ptr{nullptr}, count{new std::atomic{1}} {} template - explicit SharedPtr(U *){todo("incomplete")} SharedPtr(const SharedPtr &p) { - todo("incomplete") + explicit SharedPtr(U *ptr) + : ptr{ptr}, count{new std::atomic{1}} {} + SharedPtr(const SharedPtr &p) : ptr{p.ptr} { + Key().increment(p); + this->count = Key().get_counter(p); } template - SharedPtr(const SharedPtr &p){ - todo("incomplete")} SharedPtr(SharedPtr &&p) { - todo("asdf") + SharedPtr(const SharedPtr &p) : ptr{Key().get_ptr(p)} { + Key().increment(p); + this->count = Key().get_counter(p); + } + SharedPtr(SharedPtr &&p) + : count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} { + Key().nullify(p); } template - SharedPtr(SharedPtr &&p){todo("asdf")} SharedPtr & - operator=(const SharedPtr &) { - todo("") + SharedPtr(SharedPtr &&p) + : count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} { + Key().nullify(p); + } + SharedPtr &operator=(const SharedPtr &ptr) { + Key().increment(ptr); + this->count = Key().get_counter(ptr); + this->ptr = Key().get_ptr(ptr); + return *this; + } + template SharedPtr &operator=(const SharedPtr &ptr) { + Key().increment(ptr); + this->count = Key().get_counter(ptr); + this->ptr = Key().get_ptr(ptr); + return *this; + } + SharedPtr &operator=(SharedPtr &&p) { + this->count = Key().get_counter(ptr); + this->ptr = Key().get_ptr(ptr); + Key().nullify(p); + } + template SharedPtr &operator=(SharedPtr &&p) { + this->count = Key().get_counter(ptr); + this->ptr = Key().get_ptr(ptr); + Key().nullify(p); + } + ~SharedPtr() { + if (this->count == nullptr) { + if (this->ptr != nullptr) { + delete this->ptr; + } + return; + } + if (--(*this->count) == 0) { + delete this->count; + delete this->ptr; + } + } + void reset() { + if (this->count != nullptr) { + if (--(*this->count) == 0) { + delete this->count; + delete this->ptr; + return; + } + } + this->ptr = nullptr; + this->count = nullptr; + } + template void reset(U *p) { + this->reset(); + this->count = new counter{1}; + this->ptr = p; + } + T *get() const { return this->ptr; } + T &operator*() const { return *this->ptr; } + T *operator->() const { return this->ptr; } + explicit operator bool() const { return this->ptr != nullptr; } + template + template + friend SharedPtr static_pointer_cast(const SharedPtr &sp) { + todo(""); } template - SharedPtr &operator=(const SharedPtr &){ - todo("")} SharedPtr &operator=(SharedPtr &&p) { - todo("") + friend SharedPtr dynamic_pointer_cast(const SharedPtr &sp) { + todo(""); } - template SharedPtr &operator=(SharedPtr &&p) { todo("") } - ~SharedPtr() { todo("") } - void reset() { todo("") } - template - void reset(U *p){todo("")} T *get() const {todo("")} T &operator*() const { - todo("")} T *operator-> () const { - todo("") - } - explicit operator bool() const { todo("") } }; template -bool operator==(const SharedPtr &, const SharedPtr &) { - todo("") +bool operator==(const SharedPtr &lhs, const SharedPtr &rhs) { + return lhs.get() == rhs.get(); } -template bool operator==(const SharedPtr &, std::nullptr_t) { - todo("") +template +bool operator==(const SharedPtr &lhs, std::nullptr_t rhs) { + + return lhs.get() == rhs; } -template bool operator==(std::nullptr_t, const SharedPtr &) { - todo("") +template +bool operator==(std::nullptr_t lhs, const SharedPtr &rhs) { + return lhs == rhs.get(); } template -bool operator!=(const SharedPtr &, const SharedPtr &) { - todo("") +bool operator!=(const SharedPtr &lhs, const SharedPtr &rhs) { + return !(lhs == rhs); } -template bool operator!=(const SharedPtr &, std::nullptr_t) { - todo("") +template +bool operator!=(const SharedPtr &lhs, std::nullptr_t rhs) { + return !(lhs == rhs); } -template bool operator!=(std::nullptr_t, const SharedPtr &) { - todo("") -} -template -SharedPtr static_pointer_cast(const SharedPtr &sp) { - todo("") -} -template -SharedPtr dynamic_pointer_cast(const SharedPtr &sp) { - todo("") +template +bool operator!=(std::nullptr_t lhs, const SharedPtr &rhs) { + return !(lhs == rhs); } } // namespace cs440 #endif