summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@nc8430.lan>2009-06-04 16:31:09 +0200
committermanuel <manuel@nc8430.lan>2009-06-04 16:31:09 +0200
commit2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f (patch)
tree881b3ec20c67018ca2d693071960a462adf9cf52
parent6e3bff52c888c22d8a76c6ff741785f0463456e4 (diff)
downloadooprog-2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f.tar.gz
ooprog-2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f.tar.bz2
ooprog-2c0bf4d7935626ef299f1be3f992b1dfe4c0b19f.zip
shared_ptr
-rw-r--r--ue5/array.hpp22
-rw-r--r--ue5/shared_ptr.hpp230
-rw-r--r--ue5/verwendung.cpp5
3 files changed, 213 insertions, 44 deletions
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
22 22
23 void fill(const T& u) 23 void fill(const T& u)
24 { 24 {
25 for(size_type i = 0; i < size(); ++i)
26 m_data[i] = u;
27 /* std::fill_n(begin(), size(), u); */ 25 /* std::fill_n(begin(), size(), u); */
26 for(size_type i = 0; i < N; ++i)
27 m_data[i] = u;
28 } 28 }
29 29
30 /* range check not necessary. N must be the same in other */ 30 /* range check not necessary. N must be the same in other */
31 void swap(array<T,N> & other) 31 void swap(array<T,N> & other)
32 { 32 {
33 for(size_type i = 0; i < size(); ++i) 33 /* std::swap_ranges(begin(), end(), other.begin()); */
34 for(size_type i = 0; i < N; ++i)
34 { 35 {
35 T x(m_data[i]); 36 T x(m_data[i]);
36 m_data[i] = other[i]; 37 m_data[i] = other.m_data[i];
37 other[i] = x; 38 other.m_data[i] = x;
38 } 39 }
39 /* std::swap_ranges(begin(), end(), other.begin()); */
40 } 40 }
41 41
42 iterator begin() 42 iterator begin()
@@ -51,12 +51,12 @@ namespace Ti
51 51
52 iterator end() 52 iterator end()
53 { 53 {
54 return m_data + size(); 54 return m_data + N;
55 } 55 }
56 56
57 const_iterator end() const 57 const_iterator end() const
58 { 58 {
59 return m_data + size(); 59 return m_data + N;
60 } 60 }
61 61
62 size_type size() const 62 size_type size() const
@@ -86,14 +86,14 @@ namespace Ti
86 86
87 reference at(size_type n) 87 reference at(size_type n)
88 { 88 {
89 if (n >= size()) 89 if (n >= N)
90 throw std::out_of_range("array::at"); 90 throw std::out_of_range("array::at");
91 return m_data[n]; 91 return m_data[n];
92 } 92 }
93 93
94 const_reference at(size_type n) const 94 const_reference at(size_type n) const
95 { 95 {
96 if (n >= size()) 96 if (n >= N)
97 throw std::out_of_range("array::at"); 97 throw std::out_of_range("array::at");
98 return m_data[n]; 98 return m_data[n];
99 } 99 }
@@ -107,7 +107,7 @@ namespace Ti
107 T m_data[N]; 107 T m_data[N];
108 }; 108 };
109 109
110 /* std::move makes rvalue from rvalue */ 110 /* std::move returns lvalue as rvalue */
111 template<typename T, std::size_t N> 111 template<typename T, std::size_t N>
112 array<T, N>&& make_array() 112 array<T, N>&& make_array()
113 { 113 {
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 @@
4/* TODO includes */ 4/* TODO includes */
5 5
6#undef SOLVED_1 6#undef SOLVED_1
7//#define SOLVED_1 7#define SOLVED_1
8 8
9namespace Ti { 9/* TODO: remove */
10#define SHPDEBUG if (0)
11#include <iostream>
10 12
13namespace Ti
14{
11 /* TODO helpers */ 15 /* TODO helpers */
12 16
13 template <typename T> 17 template <typename T>
14 class shared_ptr 18 class shared_ptr
15 { 19 {
16 private: 20 private:
17 /* TODO data */ 21 T* m_ptr;
22 unsigned long* m_count;
18 23
19 public: 24 public:
20 shared_ptr(); 25 shared_ptr()
21 T* get() const; 26 : m_ptr(NULL), m_count(NULL)
22 shared_ptr (const shared_ptr<T>& other); 27 {
28 SHPDEBUG std::cerr << this << ": shared_ptr()" << std::endl;
29 }
23 30
31 T* get() const
32 {
33 SHPDEBUG std::cerr << this << ": get()" << std::endl;
34 return m_ptr;
35 }
36
37 shared_ptr(const shared_ptr<T>& other)
38 : m_ptr(other.m_ptr), m_count(other.m_count)
39 {
40 SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr<T>& other)" << std::endl;
41 add_ref();
42 }
43
44 template <typename O>
45 shared_ptr(const shared_ptr<O>& other)
46 : m_ptr(other.m_ptr), m_count(other.m_count)
47 {
48 SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr<O>& other)" << std::endl;
49 add_ref();
50 }
51
52 /* used to construct shared_ptr with a sub-object of O */
24 template <typename O> 53 template <typename O>
25 shared_ptr (const shared_ptr<O>& other); 54 shared_ptr(const shared_ptr<O>& other, T* ptr)
55 : m_ptr(ptr), m_count(other.m_count)
56 {
57 SHPDEBUG std::cerr << this << ": shared_ptr(shared_ptr<O>& other, O* ptr)" << std::endl;
58 add_ref();
59 }
26 60
27 template <typename O> 61 template <typename O>
28 explicit shared_ptr (O* p); 62 explicit shared_ptr(O* p)
29 shared_ptr& operator = (const shared_ptr<T>& other); 63 : m_ptr(p), m_count(new unsigned long(1))
64 {
65 SHPDEBUG std::cerr << this << ": shared_ptr(O* p)" << std::endl;
66 }
67
68 shared_ptr& operator=(const shared_ptr<T>& other)
69 {
70 SHPDEBUG std::cerr << this << ": operator=(shared_ptr<T>& other)" << std::endl;
71#if 1
72 shared_ptr(other).swap(*this);
73 return *this;
74#else
75 if (*this == other)
76 return *this;
77
78 release();
79
80 m_ptr = other.m_ptr;
81 m_count = other.m_count;
82 add_ref();
83 return *this;
84#endif
85 }
30 86
31 template <typename O> 87 template <typename O>
32 shared_ptr& operator = (const shared_ptr<O>& other); 88 shared_ptr& operator=(const shared_ptr<O>& other)
89 {
90 SHPDEBUG std::cerr << this << ": operator=(shared_ptr<O>& other)" << std::endl;
91#if 0
92 shared_ptr(other).swap(*this);
93 return *this;
94#else
95 if (*this == other)
96 return *this;
33 97
34 ~shared_ptr (); 98 release();
35 T& operator * () const;
36 T* operator -> () const;
37 99
38 void swap (shared_ptr<T>& other); 100 m_ptr = other.m_ptr;
101 m_count = other.m_count;
102 add_ref();
103 return *this;
104#endif
105 }
106
107 ~shared_ptr()
108 {
109 SHPDEBUG std::cerr << this << ": ~shared_ptr()" << std::endl;
110 release();
111 }
112
113 T& operator*() const
114 {
115 return *m_ptr;
116 }
117
118 T* operator->() const
119 {
120 return m_ptr;
121 }
39 122
40 inline void reset(); 123 void swap(shared_ptr<T>& other)
124 {
125 /* std::swap(m_ptr, other.m_ptr); */
126 T* ptr(m_ptr);
127 m_ptr = other.m_ptr;
128 other.m_ptr = ptr;
129
130 /* std::swap(m_count, other.m_count); */
131 unsigned long* count(m_count);
132 m_count = other.m_count;
133 other.m_count = count;
134 }
135
136 inline void reset()
137 {
138 shared_ptr().swap(*this);
139 }
41 140
42 private: 141 private:
142 void add_ref()
143 {
144 if (m_count != NULL)
145 ++(*m_count);
146 }
147
148 void release()
149 {
150 if (m_ptr != NULL)
151 {
152 --(*m_count);
153 if (*m_count == 0)
154 {
155 delete m_ptr;
156 delete m_count;
157 }
158 }
159 }
160
161 template<class O> friend class shared_ptr;
162
43 template <typename R, typename... Args> 163 template <typename R, typename... Args>
44 friend shared_ptr<R> make_shared (Args...); 164 friend shared_ptr<R> make_shared(Args...);
45 165
46 template<typename U1, typename U2> 166 template<typename U1, typename U2>
47 friend bool operator == (const shared_ptr<U1>& a, const shared_ptr<U2>& b); 167 friend bool operator==(const shared_ptr<U1>& a, const shared_ptr<U2>& b);
48 168
49 template<typename U1, typename U2> 169 template<typename U1, typename U2>
50 friend bool operator == (const shared_ptr<U1>& a, const U2* b); 170 friend bool operator==(const shared_ptr<U1>& a, const U2* b);
51 171
52 template<typename U1, typename U2> 172 template<typename U1, typename U2>
53 friend bool operator == (const U1* a, const shared_ptr<U2>& b); 173 friend bool operator==(const U1* a, const shared_ptr<U2>& b);
54 174
55 template<typename U1, typename U2> 175 template<typename U1, typename U2>
56 friend bool operator != (const shared_ptr<U1>& a, const U2* b); 176 friend bool operator!=(const shared_ptr<U1>& a, const U2* b);
57 177
58 template<typename U1, typename U2> 178 template<typename U1, typename U2>
59 friend bool operator != (const U1* a, const shared_ptr<U2>& b); 179 friend bool operator!=(const U1* a, const shared_ptr<U2>& b);
60 180
61 template<typename U1, typename U2> 181 template<typename U1, typename U2>
62 friend bool operator != (const shared_ptr<U1>& a, const shared_ptr<U2>& b); 182 friend bool operator!=(const shared_ptr<U1>& a, const shared_ptr<U2>& b);
63 183
64 template <typename R, typename F> 184 template <typename R, typename F>
65 friend shared_ptr<R> shared_dynamic_cast (const shared_ptr<F>& from); 185 friend shared_ptr<R> shared_dynamic_cast(const shared_ptr<F>& from);
66 }; 186 };
67 187
188 template <typename T, typename ... Args>
189 shared_ptr<T> make_shared(Args ... args)
190 {
191 SHPDEBUG std::cerr << "make_shared(args...)" << std::endl;
192 return shared_ptr<T>(new T(args ...));
193 }
194
195 template<typename U1, typename U2>
196 bool operator==(const shared_ptr<U1>& a, const shared_ptr<U2>& b)
197 {
198 return a.get() == b.get();
199 }
200
201 template<typename U1, typename U2>
202 bool operator==(const shared_ptr<U1>& a, const U2* b)
203 {
204 return a.get() == b.get();
205 }
206
207 template<typename U1, typename U2>
208 bool operator==(const U1* a, const shared_ptr<U2>& b)
209 {
210 return a.get() == b.get();
211 }
212
213 template<typename U1, typename U2>
214 bool operator!=(const shared_ptr<U1>& a, const U2* b)
215 {
216 return a.get() != b.get();
217 }
218
219 template<typename U1, typename U2>
220 bool operator!=(const U1* a, const shared_ptr<U2>& b)
221 {
222 return a.get() != b.get();
223 }
68 224
69 template <typename T /* TODO */ > 225 template<typename U1, typename U2>
70 shared_ptr<T> make_shared (/* TODO */); 226 bool operator!=(const shared_ptr<U1>& a, const shared_ptr<U2>& b)
227 {
228 return a.get() != b.get();
229 }
71 230
72 template <typename T, typename F> 231 template <typename T, typename F>
73 shared_ptr<T> shared_dynamic_cast (const shared_ptr<F>& from); 232 shared_ptr<T> shared_dynamic_cast(const shared_ptr<F>& from)
233 {
234 SHPDEBUG std::cerr << "shared_dynamic_cast(...)" << std::endl;
235 T* castptr = dynamic_cast<T *>(from.get());
236 if (castptr != NULL)
237 {
238 return shared_ptr<T>(from, castptr);
239 }
240 else
241 return shared_ptr<T>();
242 }
74 243
75} // end namespace ti 244} // end namespace ti
76 245
77namespace std { 246namespace std
247{
78 using namespace Ti; 248 using namespace Ti;
79 template <typename T> 249 template <typename T>
80 inline void swap (shared_ptr<T>& t1, shared_ptr<T>& t2); 250 inline void swap(shared_ptr<T>& t1, shared_ptr<T>& t2)
251 {
252 t1.swap(t2);
253 }
254
81 /* TODO */ 255 /* TODO */
82} 256}
83 257
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 @@
2#include <cassert> // for assert 2#include <cassert> // for assert
3#include <utility> // for std::move 3#include <utility> // for std::move
4#include <stdexcept> // for std::out_of_range 4#include <stdexcept> // for std::out_of_range
5#include <iostream> //TODO
6 5
7struct Person 6struct Person
8{ 7{
@@ -80,7 +79,6 @@ int main()
80 } catch (...) 79 } catch (...)
81 {} 80 {}
82 81
83
84 { 82 {
85 // derived1 is 0. 83 // derived1 is 0.
86 shared_ptr<Student> derived1; 84 shared_ptr<Student> derived1;
@@ -154,9 +152,6 @@ int main()
154 a1.swap(a2); 152 a1.swap(a2);
155 assert(a1[0] == 4); 153 assert(a1[0] == 4);
156 assert(a2[2] == 3); 154 assert(a2[2] == 3);
157
158 for(array<int,3>::iterator it = a2.begin(); it != a2.end(); ++it)
159 std::cout << (*it) << std::endl;
160#endif 155#endif
161 156
162#ifdef SOLVED_3 157#ifdef SOLVED_3