#include #ifndef _POWELLCS440 #include #include #define todo(msg) \ std::cerr << msg << std::endl; \ assert(false); namespace cs440 { using counter = std::atomic; template class SharedPtr { counter count; (???) underlying; public: // typename U meaning a type which inherits from T SharedPtr(); template explicit SharedPtr(U *); SharedPtr(const SharedPtr &p); template SharedPtr(const SharedPtr &p); SharedPtr(SharedPtr &&p); template SharedPtr(SharedPtr &&p); // needs to handle self assignment SharedPtr &operator=(const SharedPtr &); template SharedPtr &operator=(const SharedPtr &); SharedPtr &operator=(SharedPtr &&p); template SharedPtr &operator=(SharedPtr &&p); ~SharedPtr(); void reset() { this->count = 0; this->underlying = nullptr; } template void reset(U *p); T *get() const; T &operator*() const { return *this->get(); } T *operator->() const { return this->get(); } explicit operator bool() const; template friend bool operator==(const SharedPtr &, const SharedPtr &); friend bool operator==(const SharedPtr &, std::nullptr_t); friend bool operator==(std::nullptr_t, const SharedPtr &); template friend bool operator!=(const SharedPtr &, const SharedPtr &); friend bool operator!=(const SharedPtr &, std::nullptr_t); friend bool operator!=(std::nullptr_t, const SharedPtr &); template friend SharedPtr static_pointer_cast(const SharedPtr &sp); template friend SharedPtr dynamic_pointer_cast(const SharedPtr &sp); }; } // namespace cs440 #endif