diff options
| author | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-07-02 11:55:17 -0700 |
|---|---|---|
| committer | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-07-02 11:55:17 -0700 |
| commit | 6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch) | |
| tree | ed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs3460/smart_pointers/shared_ptr.hpp | |
| download | misc-undergrad-main.tar.gz misc-undergrad-main.zip | |
Diffstat (limited to 'Homework/cs3460/smart_pointers/shared_ptr.hpp')
| -rw-r--r-- | Homework/cs3460/smart_pointers/shared_ptr.hpp | 141 |
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 |
