source: Revenant/marslib/include/mars_ptr.h@ 7ef8ec4

port/mars-tycoon
Last change on this file since 7ef8ec4 was 80a6a52, checked in by Jonathan Neufeld <support@…>, 3 years ago

Get to a compile state for terrain procedural generation

  • Property mode set to 100755
File size: 6.5 KB
Line 
1#ifndef __TOTIPTR_H__
2#define __TOTIPTR_H__
3
4#include <stdlib.h>
5
6#include <string>
7
8namespace mars
9{
10 // TODO: Synchronize?
11 template <class T> class ptr
12 {
13 private:
14 int * ref;
15 T * p;
16
17 public:
18 typedef T Type;
19
20 inline ptr ()
21 {
22 this->ref = new int;
23 *this->ref = 1;
24 this->p = NULL;
25 }
26 inline ptr (T * fly)
27 {
28 this->ref = new int;
29 *this->ref = 1;
30 this->p = fly;
31 }
32 inline ptr (const ptr<T> & copy)
33 {
34 this->ref = copy.ref;
35 ++(*this->ref);
36 this->p = copy.p;
37 }
38 inline ptr & operator = (const ptr<T> & copy)
39 {
40 if (!--(*this->ref))
41 {
42 delete this->ref;
43 delete this->p;
44 }
45 this->ref = copy.ref;
46 ++(*this->ref);
47 this->p = copy.p;
48 return *this;
49 }
50 inline ptr & operator = (T * const p)
51 {
52 if (!--(*this->ref))
53 {
54 delete this->ref;
55 delete this->p;
56 }
57 this->ref = new int;
58 *this->ref = 1;
59 this->p = p;
60 return *this;
61 }
62 inline T * operator -> () { return this->p; }
63 inline T & operator * () { return *this->p; }
64 inline const T * operator -> () const { return this->p; }
65 inline const T & operator * () const { return *this->p; }
66 inline bool operator == (const T * p) const { return this->p == p; }
67 inline bool operator == (const ptr< T > & other) const { return p == other.p; }
68 inline bool operator != (const T * p) const { return this->p != p; }
69 inline bool operator < (const ptr< T > & other) const { return this->p < other.p; }
70
71 inline T * pointer () { return p; }
72 inline const T * pointer () const { return p; }
73
74 inline ~ptr ()
75 {
76 if (!--(*this->ref))
77 {
78 delete this->ref;
79 delete this->p;
80 }
81 }
82 };
83
84 template< typename Subclass, typename Baseclass >
85 Subclass * ptr_dynamic_cast (ptr< Baseclass > & p, Baseclass * = NULL)
86 { return dynamic_cast< Subclass * > (p.pointer()); }
87
88 template< typename Subclass, typename Baseclass >
89 const Subclass * ptr_dynamic_cast (const ptr< Baseclass > & p, Baseclass * = NULL)
90 { return dynamic_cast< const Subclass * > (p.pointer()); }
91
92 template< typename Otherclass, typename Inputclass >
93 Otherclass * ptr_static_cast (ptr< Inputclass > & p, Otherclass * = NULL)
94 { return static_cast< Otherclass * > (p.pointer()); }
95
96 template< typename Otherclass, typename Inputclass >
97 const Otherclass * ptr_static_cast (const ptr< Inputclass > & p, Otherclass * = NULL)
98 { return static_cast< const Otherclass * > (p.pointer()); }
99
100 template <typename T>
101 class WeakReference
102 {
103 public:
104 class StateEx : public std::exception {};
105
106 enum State { Weak = 0, Bound = 1 };
107
108 private:
109 union
110 {
111 mars::ptr< T > * ppT;
112 mars::ptr< std::string > * ppName;
113 } _ptr;
114 State _state;
115
116 public:
117 WeakReference (const WeakReference & copy)
118 : _state(copy._state)
119 {
120 if ((copy._state == Weak && copy._ptr.ppName != NULL) || (copy._state == Bound && copy._ptr.ppT != NULL))
121 if (copy._state == Weak)
122 _ptr.ppName = new mars::ptr <std::string> (*copy._ptr.ppName);
123 else if (copy._state == Bound)
124 _ptr.ppT = new mars::ptr <T> (*copy._ptr.ppT);
125 else
126 {
127 _ptr.ppName = NULL;
128 _ptr.ppT = NULL;
129 }
130 else
131 {
132 _ptr.ppName = NULL;
133 _ptr.ppT = NULL;
134 }
135 }
136
137 WeakReference ()
138 : _state(Weak)
139 {
140 _ptr.ppName = NULL;
141 _ptr.ppT = NULL;
142 }
143
144 WeakReference (const std::string & name)
145 : _state(Weak)
146 { _ptr.ppName = new mars::ptr< std::string > (new std::string (name)); }
147
148 WeakReference (const mars::ptr< std::string > & pName)
149 : _state(Weak)
150 { _ptr.ppName = new mars::ptr< std::string > (pName); }
151
152 WeakReference (const mars::ptr< T > & ptr)
153 : _state(Bound)
154 { _ptr.ppT = new mars::ptr< T > (ptr); }
155
156 inline const mars::ptr< T > & operator * () const
157 {
158 if (_state == Bound)
159 return *_ptr.ppT;
160 else
161 throw StateEx();
162 }
163 inline const mars::ptr< T > & operator -> () const
164 {
165 if (_state == Bound)
166 return *_ptr.ppT;
167 else
168 throw StateEx();
169 }
170 inline mars::ptr< T > & operator * ()
171 {
172 if (_state == Bound)
173 return *_ptr.ppT;
174 else
175 throw StateEx();
176 }
177 inline mars::ptr< T > & operator -> ()
178 {
179 if (_state == Bound)
180 return *_ptr.ppT;
181 else
182 throw StateEx();
183 }
184 inline bool operator == (const WeakReference< T > & other) const
185 {
186 if (_state != other._state)
187 {
188 if (_state == Weak)
189 return other == **_ptr.ppName;
190 else
191 return **_ptr.ppT == **other._ptr.ppName;
192 } else
193 {
194 switch (_state)
195 {
196 case Weak:
197 return **_ptr.ppName == **other._ptr.ppName;
198 case Bound:
199 return **_ptr.ppT == **other._ptr.ppT;
200 }
201 }
202
203 throw StateEx();
204 }
205 inline WeakReference<T> & operator = (const std::string & name)
206 {
207 if (_state == Bound)
208 throw StateEx();
209 else
210 {
211 if (_ptr.ppName == NULL)
212 _ptr.ppName = new mars::ptr< std::string > (new std::string (name));
213 else
214 **_ptr.ppName = name;
215 }
216 return *this;
217 }
218 inline WeakReference<T> & operator = (const WeakReference<T> & copy)
219 {
220 _state = copy._state;
221
222 if ((copy._state == Weak && copy._ptr.ppName != NULL) || (copy._state == Bound && copy._ptr.ppT != NULL))
223 if (copy._state == Weak)
224 _ptr.ppName = new mars::ptr <std::string> (*copy._ptr.ppName);
225 else if (copy._state == Bound)
226 _ptr.ppT = new mars::ptr <T> (*copy._ptr.ppT);
227 else
228 {
229 _ptr.ppName = NULL;
230 _ptr.ppT = NULL;
231 }
232 else
233 {
234 _ptr.ppName = NULL;
235 _ptr.ppT = NULL;
236 }
237
238 return *this;
239 }
240
241 inline State getState () const { return _state; }
242 inline bool isNull () const { return (_ptr.ppName == NULL && _state == Weak) || (_ptr.ppT == NULL && _state == Bound); }
243 inline void makeNull ()
244 {
245 switch (_state)
246 {
247 case Weak:
248 delete _ptr.ppName;
249 _ptr.ppName = NULL;
250 break;
251 case Bound:
252 delete _ptr.ppT;
253 _ptr.ppT = NULL;
254 break;
255 }
256 }
257 inline const std::string & getName () const
258 {
259 if (_state == Weak && _ptr.ppName != NULL)
260 return **_ptr.ppName;
261 else
262 return static_cast< const std::string & > (**_ptr.ppT); // T must implement an operator for std::string
263 }
264 inline operator const std::string & () const { return getName(); }
265 inline void resolve (const mars::ptr< T > & p)
266 {
267 if (_state == Weak && _ptr.ppName != NULL)
268 {
269 delete _ptr.ppName;
270 _ptr.ppT = new mars::ptr< T > (p);
271 _state = Bound;
272 } else
273 throw StateEx();
274 }
275
276 inline bool operator < (const WeakReference< T > & other) const
277 { return getName() < other.getName(); }
278
279 inline ~WeakReference ()
280 {
281 switch (_state)
282 {
283 case Weak:
284 delete _ptr.ppName;
285 break;
286 case Bound:
287 delete _ptr.ppT;
288 break;
289 }
290 }
291 };
292}
293
294#endif
Note: See TracBrowser for help on using the repository browser.