summaryrefslogtreecommitdiffstats
path: root/ue5/shared_ptr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'ue5/shared_ptr.hpp')
-rw-r--r--ue5/shared_ptr.hpp230
1 files changed, 202 insertions, 28 deletions
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