summaryrefslogtreecommitdiff
path: root/Homework/cs3460/smart_pointers/shared_ptr.hpp
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
commit6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch)
treeed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs3460/smart_pointers/shared_ptr.hpp
downloadmisc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.tar.gz
misc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.zip
Diffstat (limited to 'Homework/cs3460/smart_pointers/shared_ptr.hpp')
-rw-r--r--Homework/cs3460/smart_pointers/shared_ptr.hpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/Homework/cs3460/smart_pointers/shared_ptr.hpp b/Homework/cs3460/smart_pointers/shared_ptr.hpp
new file mode 100644
index 0000000..f1b5939
--- /dev/null
+++ b/Homework/cs3460/smart_pointers/shared_ptr.hpp
@@ -0,0 +1,141 @@
+#include <cstdint>
+#include <stdexcept>
+
+#ifndef SHARED_PTR_HPP
+ #define SHARED_PTR_HPP
+
+namespace usu
+{
+ template <typename T>
+ class shared_ptr
+ {
+ public:
+ shared_ptr() :
+ m_references(new std::uint32_t(0)), m_rawPtr(nullptr)
+ {
+ }
+
+ shared_ptr(T* rawPtr) :
+ m_references(new std::uint32_t(1)), m_rawPtr(rawPtr)
+ {
+ }
+
+ shared_ptr(const shared_ptr<T>& ptr) :
+ m_references(ptr.m_references), m_rawPtr(ptr.m_rawPtr)
+ {
+ (*m_references)++;
+ }
+
+ shared_ptr(shared_ptr<T>&& ptr) :
+ m_references(ptr.m_references), m_rawPtr(ptr.m_rawPtr)
+ {
+ ptr.m_references = nullptr;
+ ptr.m_rawPtr = nullptr;
+ }
+
+ ~shared_ptr()
+ {
+ maybeDeallocate();
+ };
+
+ shared_ptr<T>& operator=(const shared_ptr<T>& rhs)
+ {
+ maybeDeallocate();
+ m_references = rhs.m_references;
+ (*m_references)++;
+ m_rawPtr = rhs.m_rawPtr;
+ return *this;
+ }
+
+ shared_ptr<T>& operator=(shared_ptr<T>&& rhs)
+ {
+ std::swap(m_references, rhs.m_references);
+ std::swap(m_rawPtr, rhs.m_rawPtr);
+ return *this;
+ }
+
+ T operator*() { return *m_rawPtr; }
+ T* operator->() { return m_rawPtr; }
+ T* get() { return m_rawPtr; }
+
+ std::uint32_t use_count() { return *m_references; }
+
+ private:
+ std::uint32_t* m_references;
+ T* m_rawPtr;
+
+ void maybeDeallocate()
+ {
+ if (m_references != nullptr)
+ {
+ (*m_references)--;
+ if (*m_references == 0)
+ {
+ delete m_references;
+ if (m_rawPtr != nullptr)
+ delete m_rawPtr;
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ class shared_ptr<T[]>
+ {
+ public:
+ shared_ptr() :
+ m_references(new std::uint32_t(0)), m_rawPtr(nullptr), m_len(0)
+ {
+ }
+
+ shared_ptr(T* rawPtr, std::size_t len) :
+ m_references(new std::uint32_t(1)), m_rawPtr(rawPtr), m_len(len)
+ {
+ }
+
+ ~shared_ptr()
+ {
+ if (m_references != nullptr)
+ {
+ (*m_references)--;
+ if (*m_references == 0)
+ {
+ delete m_references;
+
+ if (m_rawPtr != nullptr)
+ delete[] m_rawPtr;
+ }
+ }
+ };
+
+ std::size_t size() { return m_len; }
+
+ T& operator[](std::uint32_t index)
+ {
+ if (index >= m_len)
+ throw std::invalid_argument("Index is out of range");
+ return m_rawPtr[index];
+ }
+
+ private:
+ std::uint32_t* m_references;
+ T* m_rawPtr;
+
+ std::size_t m_len;
+ };
+
+ template <typename T, typename... Args>
+ shared_ptr<T> make_shared(Args&&... args)
+ {
+ return shared_ptr<T>(new T(std::forward<Args>(args)...));
+ }
+
+ template <typename T, unsigned int N>
+ shared_ptr<T[]> make_shared_array()
+ {
+ return shared_ptr<T[]>(new T[N], N);
+ }
+
+} // namespace usu
+
+#endif // SHARED_PTR_HPP