#ifndef SHARED_PTR_H #define SHARED_PTR_H #include #undef SOLVED_1 #define SOLVED_1 namespace Ti { template class shared_ptr { private: T* m_ptr; unsigned long* m_count; public: shared_ptr() : m_ptr(NULL), m_count(NULL) {} T* get() const { return m_ptr; } shared_ptr(const shared_ptr& other) : m_ptr(other.m_ptr), m_count(other.m_count) { add_ref(); } template shared_ptr(const shared_ptr& other) : m_ptr(other.m_ptr), m_count(other.m_count) { add_ref(); } /* used to construct shared_ptr with a sub-object of O */ template shared_ptr(const shared_ptr& other, T* ptr) : m_ptr(ptr), m_count(other.m_count) { add_ref(); } template explicit shared_ptr(O* p) : m_ptr(p), m_count(new unsigned long(1)) {} shared_ptr& operator=(const shared_ptr& other) { if (*this == other) return *this; release(); m_ptr = other.m_ptr; m_count = other.m_count; add_ref(); return *this; } template shared_ptr& operator=(const shared_ptr& other) { if (*this == other) return *this; release(); m_ptr = other.m_ptr; m_count = other.m_count; add_ref(); return *this; } ~shared_ptr() { release(); } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } void swap(shared_ptr& other) { std::swap(m_ptr, other.m_ptr); std::swap(m_count, other.m_count); } inline void reset() { shared_ptr().swap(*this); } private: void add_ref() { if (m_count != NULL) ++(*m_count); } void release() { if (m_ptr != NULL) { --(*m_count); if (*m_count == 0) { delete m_ptr; delete m_count; } } } template friend class shared_ptr; template friend shared_ptr make_shared(Args...); template friend bool operator==(const shared_ptr& a, const shared_ptr& b); template friend bool operator==(const shared_ptr& a, const U2* b); template friend bool operator==(const U1* a, const shared_ptr& b); template friend bool operator!=(const shared_ptr& a, const U2* b); template friend bool operator!=(const U1* a, const shared_ptr& b); template friend bool operator!=(const shared_ptr& a, const shared_ptr& b); template friend shared_ptr shared_dynamic_cast(const shared_ptr& from); }; template shared_ptr make_shared(Args ... args) { return shared_ptr(new T(args ...)); } template bool operator==(const shared_ptr& a, const shared_ptr& b) { return a.get() == b.get(); } template bool operator==(const shared_ptr& a, const U2* b) { return a.get() == b.get(); } template bool operator==(const U1* a, const shared_ptr& b) { return a.get() == b.get(); } template bool operator!=(const shared_ptr& a, const U2* b) { return a.get() != b.get(); } template bool operator!=(const U1* a, const shared_ptr& b) { return a.get() != b.get(); } template bool operator!=(const shared_ptr& a, const shared_ptr& b) { return a.get() != b.get(); } template shared_ptr shared_dynamic_cast(const shared_ptr& from) { T* castptr = dynamic_cast(from.get()); if (castptr != NULL) return shared_ptr(from, castptr); else return shared_ptr(); } } // end namespace ti namespace std { using namespace Ti; template inline void swap(shared_ptr& t1, shared_ptr& t2) { t1.swap(t2); } } #endif /* vim: set et sw=2 ts=2: */