From 2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 4 Jun 2009 16:31:09 +0200 Subject: shared_ptr --- ue5/array.hpp | 22 ++--- ue5/shared_ptr.hpp | 230 ++++++++++++++++++++++++++++++++++++++++++++++------- ue5/verwendung.cpp | 5 -- 3 files changed, 213 insertions(+), 44 deletions(-) (limited to 'ue5') diff --git a/ue5/array.hpp b/ue5/array.hpp index 9c8a7e6..e9adc55 100644 --- a/ue5/array.hpp +++ b/ue5/array.hpp @@ -22,21 +22,21 @@ namespace Ti void fill(const T& u) { - for(size_type i = 0; i < size(); ++i) - m_data[i] = u; /* std::fill_n(begin(), size(), u); */ + for(size_type i = 0; i < N; ++i) + m_data[i] = u; } /* range check not necessary. N must be the same in other */ void swap(array & other) { - for(size_type i = 0; i < size(); ++i) + /* std::swap_ranges(begin(), end(), other.begin()); */ + for(size_type i = 0; i < N; ++i) { T x(m_data[i]); - m_data[i] = other[i]; - other[i] = x; + m_data[i] = other.m_data[i]; + other.m_data[i] = x; } - /* std::swap_ranges(begin(), end(), other.begin()); */ } iterator begin() @@ -51,12 +51,12 @@ namespace Ti iterator end() { - return m_data + size(); + return m_data + N; } const_iterator end() const { - return m_data + size(); + return m_data + N; } size_type size() const @@ -86,14 +86,14 @@ namespace Ti reference at(size_type n) { - if (n >= size()) + if (n >= N) throw std::out_of_range("array::at"); return m_data[n]; } const_reference at(size_type n) const { - if (n >= size()) + if (n >= N) throw std::out_of_range("array::at"); return m_data[n]; } @@ -107,7 +107,7 @@ namespace Ti T m_data[N]; }; - /* std::move makes rvalue from rvalue */ + /* std::move returns lvalue as rvalue */ template array&& make_array() { 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 */ } diff --git a/ue5/verwendung.cpp b/ue5/verwendung.cpp index 8a20e6c..a0939cd 100644 --- a/ue5/verwendung.cpp +++ b/ue5/verwendung.cpp @@ -2,7 +2,6 @@ #include // for assert #include // for std::move #include // for std::out_of_range -#include //TODO struct Person { @@ -80,7 +79,6 @@ int main() } catch (...) {} - { // derived1 is 0. shared_ptr derived1; @@ -154,9 +152,6 @@ int main() a1.swap(a2); assert(a1[0] == 4); assert(a2[2] == 3); - - for(array::iterator it = a2.begin(); it != a2.end(); ++it) - std::cout << (*it) << std::endl; #endif #ifdef SOLVED_3 -- cgit v1.2.3