From 2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 4 Jun 2009 16:31:09 +0200 Subject: shared_ptr --- ue5/shared_ptr.hpp | 230 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 202 insertions(+), 28 deletions(-) (limited to 'ue5/shared_ptr.hpp') diff --git a/ue5/shared_ptr.hpp b/ue5/shared_ptr.hpp index 4492fff..00a4dc7 100644 --- a/ue5/shared_ptr.hpp +++ b/ue5/shared_ptr.hpp @@ -4,80 +4,254 @@ /* TODO includes */ #undef SOLVED_1 -//#define SOLVED_1 +#define SOLVED_1 -namespace Ti { +/* TODO: remove */ +#define SHPDEBUG if (0) +#include +namespace Ti +{ /* TODO helpers */ template class shared_ptr { private: - /* TODO data */ + T* m_ptr; + unsigned long* m_count; public: - shared_ptr(); - T* get() const; - shared_ptr (const shared_ptr& other); + shared_ptr() + : m_ptr(NULL), m_count(NULL) + { + SHPDEBUG std::cerr << this << ": shared_ptr()" << std::endl; + } + T* get() const + { + SHPDEBUG std::cerr << this << ": get()" << std::endl; + return m_ptr; + } + + shared_ptr(const shared_ptr& other) + : m_ptr(other.m_ptr), m_count(other.m_count) + { + SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr& other)" << std::endl; + add_ref(); + } + + template + shared_ptr(const shared_ptr& other) + : m_ptr(other.m_ptr), m_count(other.m_count) + { + SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr& other)" << std::endl; + add_ref(); + } + + /* used to construct shared_ptr with a sub-object of O */ template - shared_ptr (const shared_ptr& other); + shared_ptr(const shared_ptr& other, T* ptr) + : m_ptr(ptr), m_count(other.m_count) + { + SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr& other, O* ptr)" << std::endl; + add_ref(); + } template - explicit shared_ptr (O* p); - shared_ptr& operator = (const shared_ptr& other); + explicit shared_ptr(O* p) + : m_ptr(p), m_count(new unsigned long(1)) + { + SHPDEBUG std::cerr << this << ": shared_ptr(O* p)" << std::endl; + } + + shared_ptr& operator=(const shared_ptr& other) + { + SHPDEBUG std::cerr << this << ": operator=(shared_ptr& other)" << std::endl; +#if 1 + shared_ptr(other).swap(*this); + return *this; +#else + if (*this == other) + return *this; + + release(); + + m_ptr = other.m_ptr; + m_count = other.m_count; + add_ref(); + return *this; +#endif + } template - shared_ptr& operator = (const shared_ptr& other); + shared_ptr& operator=(const shared_ptr& other) + { + SHPDEBUG std::cerr << this << ": operator=(shared_ptr& other)" << std::endl; +#if 0 + shared_ptr(other).swap(*this); + return *this; +#else + if (*this == other) + return *this; - ~shared_ptr (); - T& operator * () const; - T* operator -> () const; + release(); - void swap (shared_ptr& other); + m_ptr = other.m_ptr; + m_count = other.m_count; + add_ref(); + return *this; +#endif + } + + ~shared_ptr() + { + SHPDEBUG std::cerr << this << ": ~shared_ptr()" << std::endl; + release(); + } + + T& operator*() const + { + return *m_ptr; + } + + T* operator->() const + { + return m_ptr; + } - inline void reset(); + void swap(shared_ptr& other) + { + /* std::swap(m_ptr, other.m_ptr); */ + T* ptr(m_ptr); + m_ptr = other.m_ptr; + other.m_ptr = ptr; + + /* std::swap(m_count, other.m_count); */ + unsigned long* count(m_count); + m_count = other.m_count; + other.m_count = 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...); + friend shared_ptr make_shared(Args...); template - friend bool operator == (const shared_ptr& a, const shared_ptr& b); + friend bool operator==(const shared_ptr& a, const shared_ptr& b); template - friend bool operator == (const shared_ptr& a, const U2* b); + friend bool operator==(const shared_ptr& a, const U2* b); template - friend bool operator == (const U1* a, const shared_ptr& b); + friend bool operator==(const U1* a, const shared_ptr& b); template - friend bool operator != (const shared_ptr& a, const U2* b); + friend bool operator!=(const shared_ptr& a, const U2* b); template - friend bool operator != (const U1* a, const shared_ptr& b); + friend bool operator!=(const U1* a, const shared_ptr& b); template - friend bool operator != (const shared_ptr& a, const shared_ptr& b); + friend bool operator!=(const shared_ptr& a, const shared_ptr& b); template - friend shared_ptr shared_dynamic_cast (const shared_ptr& from); + friend shared_ptr shared_dynamic_cast(const shared_ptr& from); }; + template + shared_ptr make_shared(Args ... args) + { + SHPDEBUG std::cerr << "make_shared(args...)" << std::endl; + 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 - shared_ptr make_shared (/* TODO */); + 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); + shared_ptr shared_dynamic_cast(const shared_ptr& from) + { + SHPDEBUG std::cerr << "shared_dynamic_cast(...)" << std::endl; + T* castptr = dynamic_cast(from.get()); + if (castptr != NULL) + { + return shared_ptr(from, castptr); + } + else + return shared_ptr(); + } } // end namespace ti -namespace std { +namespace std +{ using namespace Ti; template - inline void swap (shared_ptr& t1, shared_ptr& t2); + inline void swap(shared_ptr& t1, shared_ptr& t2) + { + t1.swap(t2); + } + /* TODO */ } -- cgit v1.2.3