// // Created by Brady Bodily on 11/19/19. // #ifndef HW8_SHARED_PTR_HPP #define HW8_SHARED_PTR_HPP #include #include namespace usu { template class shared_ptr { protected: int* count; T* pointer; public: shared_ptr(); shared_ptr(T* input_ptr); shared_ptr(shared_ptr&& r); shared_ptr(const shared_ptr& r); T operator*(); T* operator->(); shared_ptr& operator=(shared_ptr&& r); shared_ptr& operator=(const shared_ptr& r); T* get() { return pointer; }; unsigned int use_count() { return *count; }; ~shared_ptr(); }; /// /// Default Constructor /// /// \tparam T template shared_ptr::shared_ptr() { pointer = new T(); count = new int(1); } /// overloaded constructor /// /// \tparam T /// \param input_ptr template shared_ptr::shared_ptr(T* input_ptr) : pointer(input_ptr) { count = new int(1); } /// Move Constructor /// /// \tparam T /// \param r template shared_ptr::shared_ptr(shared_ptr&& r) { this->count = r.count; this->pointer = r.pointer; r.pointer = nullptr; r.count = new int(0); } /// Move Assignment operator /// /// \tparam T /// \param r /// \return template shared_ptr& shared_ptr::operator=(shared_ptr&& r) { if (this != &r) { std::swap(this->pointer, r.pointer); std::swap(this->count, r.count); } return *this; } /// Copy Constructor /// /// \tparam T /// \param r template shared_ptr::shared_ptr(const shared_ptr& r) : pointer(r.pointer), count(r.count) { *count += 1; } /// Assignment operator /// /// \tparam T /// \param r /// \return template shared_ptr& shared_ptr::operator=(const shared_ptr& r) { this->count = r.count; this->pointer = r.pointer; *count += 1; return *this; } /// Pointer operator /// /// \tparam T /// \return template T* shared_ptr::operator->() { return pointer; } /// Dereference pointer /// /// \tparam T /// \return template T shared_ptr::operator*() { return *pointer; } /// Destructor /// /// \tparam T template shared_ptr::~shared_ptr() { *count -= 1; } template shared_ptr make_shared(Args&&... args) { return shared_ptr(new T(std::forward(args)...)); } /////////Second Class ////////////////////// template class shared_ptr { protected: unsigned int elemnt_count; int* count; T* pointer; public: shared_ptr(); shared_ptr(T* raw_ptr, unsigned int elements); shared_ptr(const shared_ptr& r); shared_ptr(shared_ptr&& r); shared_ptr& operator=(const shared_ptr& r); shared_ptr& operator=(shared_ptr&& r); T& operator[](unsigned int x); ~shared_ptr(); unsigned int use_count() { return *count; }; unsigned int size() { return elemnt_count; }; }; /// Default Constructor /// /// \tparam T template shared_ptr::shared_ptr() : elemnt_count(0) { pointer = new T[0]; count = new int(1); } /// Overloaded Constructor /// /// \tparam T /// \param input_ptr /// \param elementCount template shared_ptr::shared_ptr(T* input_ptr, unsigned int elementCount) : pointer(input_ptr), elemnt_count(elementCount) { count = new int(1); } /// Copy Constructor /// /// \tparam T /// \param r template shared_ptr::shared_ptr(const shared_ptr& r) : pointer(r.pointer), count(r.count), elemnt_count(r.elemnt_count) { *count += 1; } /// Move Constructor /// /// \tparam T /// \param r template shared_ptr::shared_ptr(shared_ptr&& r) { this->pointer = r.pointer; r.pointer = nullptr; this->count = r.count; r.count = new int(0); this->elemnt_count = r.elemnt_count; r.elemnt_count = 0; } ///Move Assignment Operator /// /// \tparam T /// \param r /// \return template shared_ptr& shared_ptr::operator=(const shared_ptr& r) { this->pointer = r.pointer; this->count = r.count; this->elemnt_count = r.elemnt_count; *count += 1; return *this; } /// Index opperator /// /// \tparam T /// \param x /// \return template T& shared_ptr::operator[](unsigned int x) { return this->pointer[x]; } ///Destructor /// /// \tparam T template shared_ptr::~shared_ptr() { *count -= 1; if (!*count && pointer != nullptr) { delete[] pointer; } } /// Move Assignment operator /// /// \tparam T /// \param r /// \return template shared_ptr& shared_ptr::operator=(shared_ptr&& r) { if (this != &r) { std::swap(this->pointer, r.pointer); std::swap(this->count, r.count); std::swap(this->elemnt_count, r.elemnt_count); } return *this; } /// /// /// \tparam T /// \tparam T2 /// \return template shared_ptr make_shared_array() { return shared_ptr(new T[T2], T2); } } // namespace usu #endif // HW8_SHARED_PTR_HPP