#include #include #ifndef SHARED_PTR_HPP #define SHARED_PTR_HPP namespace usu { template 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& ptr) : m_references(ptr.m_references), m_rawPtr(ptr.m_rawPtr) { (*m_references)++; } shared_ptr(shared_ptr&& ptr) : m_references(ptr.m_references), m_rawPtr(ptr.m_rawPtr) { ptr.m_references = nullptr; ptr.m_rawPtr = nullptr; } ~shared_ptr() { maybeDeallocate(); }; shared_ptr& operator=(const shared_ptr& rhs) { maybeDeallocate(); m_references = rhs.m_references; (*m_references)++; m_rawPtr = rhs.m_rawPtr; return *this; } shared_ptr& operator=(shared_ptr&& 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 class shared_ptr { 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 shared_ptr make_shared(Args&&... args) { return shared_ptr(new T(std::forward(args)...)); } template shared_ptr make_shared_array() { return shared_ptr(new T[N], N); } } // namespace usu #endif // SHARED_PTR_HPP