1
2
3
4
5
6 using System.IO;
7
8 namespace System
9 {
10 public abstract class CounterBase
11 {
12 public CounterBase() : useCount(1), weakCount(1)
13 {
14 }
15 suppress CounterBase(const CounterBase&);
16 suppress void operator=(const CounterBase&);
17 suppress CounterBase(CounterBase&&);
18 suppress void operator=(CounterBase&&);
19 public virtual default ~CounterBase();
20 public abstract void Dispose();
21 public virtual void Destruct()
22 {
23 delete this;
24 }
25 public inline void AddReference()
26 {
27 #assert(useCount != 0 || weakCount == 0);
28 ++useCount;
29 ++weakCount;
30 }
31 public inline void Release()
32 {
33 --useCount;
34 if (useCount != 0)
35 {
36 --weakCount;
37 return;
38 }
39 Dispose();
40 WeakRelease();
41 }
42 public inline void WeakAddReference()
43 {
44 ++weakCount;
45 }
46 public void WeakRelease()
47 {
48 --weakCount;
49 if (weakCount == 0)
50 {
51 Destruct();
52 }
53 }
54 public inline int GetUseCount() const
55 {
56 return useCount;
57 }
58 private int useCount;
59 private int weakCount;
60 }
61
62 public class Counter<T> : CounterBase
63 {
64 private typedef Counter<T> Self;
65
66 public Counter(T* ptr_) : ptr(ptr_)
67 {
68 }
69 suppress Counter(const Self&);
70 suppress void operator=(const Self&);
71 suppress Counter(Self&&);
72 suppress void operator=(Self&&);
73 public override void Dispose()
74 {
75 delete ptr;
76 ptr = null;
77 }
78 private T* ptr;
79 }
80
81 public class SharedCount<T>
82 {
83 private typedef Counter<T>* CounterPtrType;
84 private typedef SharedCount<T> Self;
85
86 public SharedCount() : counter(null)
87 {
88 }
89 public SharedCount(T* ptr_) : counter(new Counter<T>(ptr_))
90 {
91 }
92 public SharedCount(Counter<T>* counter_) : counter(counter_)
93 {
94 if (counter != null)
95 {
96 counter->AddReference();
97 }
98 }
99 public SharedCount(const Self& that) : counter(that.counter)
100 {
101 if (counter != null)
102 {
103 counter->AddReference();
104 }
105 }
106 public SharedCount(Self&& that) : counter(that.counter)
107 {
108 that.counter = null;
109 }
110 public SharedCount(const WeakCount<T>& that) : counter(that.GetCounter())
111 {
112 #assert(counter != null);
113 counter->AddReference();
114 }
115 public void operator=(const Self& that)
116 {
117 CounterPtrType otherCounter = that.counter;
118 if (otherCounter != null)
119 {
120 otherCounter->AddReference();
121 }
122 if (counter != null)
123 {
124 counter->Release();
125 }
126 counter = otherCounter;
127 }
128 public void operator=(Self&& that)
129 {
130 Swap(counter, that.counter);
131 }
132 public ~SharedCount()
133 {
134 if (counter != null)
135 {
136 counter->Release();
137 }
138 }
139 public void Swap(Self& that)
140 {
141 CounterPtrType otherCounter = that.counter;
142 that.counter = counter;
143 counter = otherCounter;
144 }
145 public int GetUseCount() const
146 {
147 if (counter != null)
148 {
149 return counter->GetUseCount();
150 }
151 return 0;
152 }
153 public bool IsUnique() const
154 {
155 return GetUseCount() == 1;
156 }
157 public CounterPtrType GetCounter() const
158 {
159 return counter;
160 }
161 private CounterPtrType counter;
162 }
163
164 public bool operator==<T>(const SharedCount<T>& left, const SharedCount<T>& right)
165 {
166 return left.GetCounter() == right.GetCounter();
167 }
168
169 public bool operator<<T>(const SharedCount<T>& left, const SharedCount<T>& right)
170 {
171 return left.GetCounter() < right.GetCounter();
172 }
173
174 internal SharedCount<U> SharedCountCast<U, T>(const SharedCount<T>& from)
175 {
176 return SharedCount<U>(cast<Counter<U>*>(from.GetCounter()));
177 }
178
179 public class WeakCount<T>
180 {
181 private typedef Counter<T>* CounterPtrType;
182 private typedef WeakCount<T> Self;
183
184 public WeakCount() : counter(null)
185 {
186 }
187 public WeakCount(const Self& that) : counter(that.counter)
188 {
189 if (counter != null)
190 {
191 counter->WeakAddReference();
192 }
193 }
194 public WeakCount(Self&& that) : counter(that.counter)
195 {
196 that.counter = null;
197 }
198 public WeakCount(const SharedCount<T>& that) : counter(that.GetCounter())
199 {
200 if (counter != null)
201 {
202 counter->WeakAddReference();
203 }
204 }
205 public ~WeakCount()
206 {
207 if (counter != null)
208 {
209 counter->WeakRelease();
210 }
211 }
212 public void operator=(const SharedCount<T>& that)
213 {
214 CounterPtrType otherCounter = that.GetCounter();
215 if (otherCounter != null)
216 {
217 otherCounter->WeakAddReference();
218 }
219 if (counter != null)
220 {
221 counter->WeakRelease();
222 }
223 counter = otherCounter;
224 }
225 public void operator=(const Self& that)
226 {
227 CounterPtrType otherCounter = that.counter;
228 if (otherCounter != null)
229 {
230 otherCounter->WeakAddReference();
231 }
232 if (counter != null)
233 {
234 counter->WeakRelease();
235 }
236 counter = otherCounter;
237 }
238 public void operator=(Self&& that)
239 {
240 Swap(counter, that.counter);
241 }
242 public void Swap(Self& that)
243 {
244 CounterPtrType otherCounter = that.counter;
245 that.counter = counter;
246 counter = otherCounter;
247 }
248 public int GetUseCount() const
249 {
250 if (counter != null)
251 {
252 return counter->GetUseCount();
253 }
254 return 0;
255 }
256 public CounterPtrType GetCounter() const
257 {
258 return counter;
259 }
260 private CounterPtrType counter;
261 }
262
263 public bool operator==<T>(const WeakCount<T>& left, const WeakCount<T>& right)
264 {
265 return left.GetCounter() == right.GetCounter();
266 }
267
268 public bool operator<<T>(const WeakCount<T>& left, const WeakCount<T>& right)
269 {
270 return left.GetCounter() < right.GetCounter();
271 }
272
273 public class SharedPtr<T>
274 {
275 private typedef SharedPtr<T> Self;
276 private typedef SharedCount<T> CountType;
277
278 public SharedPtr() : ptr(null), count()
279 {
280 }
281 public explicit SharedPtr(T* ptr_) : ptr(ptr_), count(ptr)
282 {
283 EnableSharedFromThis(ptr_, ptr_, count);
284 }
285 public SharedPtr(T* ptr_, const CountType& count_) : ptr(ptr_), count(count_)
286 {
287 }
288 public SharedPtr(const Self& that) : ptr(that.ptr), count(that.count)
289 {
290 }
291 public SharedPtr(Self&& that) : ptr(that.ptr), count(Rvalue(that.count))
292 {
293 that.ptr = null;
294 }
295 public SharedPtr(const WeakPtr<T>& that) : ptr(), count(that.GetCount())
296 {
297 ptr = that.GetPtrForSharedPtr();
298 }
299 public void Reset()
300 {
301 Self().Swap(*this);
302 }
303 public void Reset(T* ptr_)
304 {
305 Self(ptr_).Swap(*this);
306 }
307 public void operator=(const Self& that)
308 {
309 ptr = that.ptr;
310 count = that.count;
311 }
312 public void operator=(Self&& that)
313 {
314 Swap(ptr, that.ptr);
315 Swap(count, that.count);
316 }
317 public inline T* operator->() const
318 {
319 #assert(ptr != null);
320 return ptr;
321 }
322 public inline T& operator*() const
323 {
324 #assert(ptr != null);
325 return *ptr;
326 }
327 public inline T* GetPtr() const
328 {
329 return ptr;
330 }
331 public inline T* Get() const
332 {
333 return ptr;
334 }
335 public inline const CountType& GetCount() const
336 {
337 return count;
338 }
339 public inline bool IsNull() const
340 {
341 return ptr == null;
342 }
343 public void Swap(Self& that)
344 {
345 Swap(ptr, that.ptr);
346 count.Swap(that.count);
347 }
348 public bool IsUnique() const
349 {
350 return count.IsUnique();
351 }
352 public int GetUseCount() const
353 {
354 return count.GetUseCount();
355 }
356 private T* ptr;
357 private CountType count;
358 }
359
360 public bool operator==<T>(const SharedPtr<T>& left, const SharedPtr<T>& right)
361 {
362 return left.Get() == right.Get();
363 }
364
365 public bool operator<<T>(const SharedPtr<T>& left, const SharedPtr<T>& right)
366 {
367 #assert(left.Get() != null && right.Get() != null || left.Get() == null && right.Get() == null);
368 return left.Get() < right.Get();
369 }
370
371 public SharedPtr<U> PtrCast<U, T>(const SharedPtr<T>& from)
372 {
373 return SharedPtr<U>(cast<U*>(from.Get()), SharedCountCast<U>(from.GetCount()));
374 }
375
376 public class WeakPtr<T>
377 {
378 private typedef WeakPtr<T> Self;
379 private typedef WeakCount<T> CountType;
380
381 public WeakPtr() : ptr(null), count()
382 {
383 }
384 public WeakPtr(const SharedPtr<T>& that) : ptr(that.Get()), count(that.GetCount())
385 {
386 }
387 public WeakPtr(const Self& that) : ptr(), count(that.count)
388 {
389 ptr = that.Lock().Ptr();
390 }
391 public default ~WeakPtr();
392 public void operator=(const Self& that)
393 {
394 ptr = that.Lock().Get();
395 count = that.count;
396 }
397 public void operator=(const SharedPtr<T>& that)
398 {
399 ptr = that.Get();
400 count = that.GetCount();
401 }
402 public int GetUseCount() const
403 {
404 return count.GetUseCount();
405 }
406 public bool IsExpired() const
407 {
408 return count.GetUseCount() == 0;
409 }
410 public SharedPtr<T> Lock() const
411 {
412 if (IsExpired())
413 {
414 return SharedPtr<T>();
415 }
416 return SharedPtr<T>(*this);
417 }
418 public void Reset()
419 {
420 Self().Swap(*this);
421 }
422 public void Swap(Self& that)
423 {
424 Swap(ptr, that.ptr);
425 count.Swap(that.count);
426 }
427
428
429
430
431
432 public inline T* GetPtrForSharedPtr() const
433 {
434 return ptr;
435 }
436 public inline const CountType& GetCount() const
437 {
438 return count;
439 }
440 public void Assign(T* ptr_, const SharedCount<T>& count_)
441 {
442 ptr = ptr_;
443 count = count_;
444 }
445 private T* ptr;
446 private CountType count;
447 }
448
449 public class ShareableFromThis<T>
450 {
451 public SharedPtr<T> GetSharedFromThis() const
452 {
453 SharedPtr<T> p(weakThis);
454 #assert(p.Get() == this);
455 return p;
456 }
457 public WeakPtr<T>& GetWeakThis()
458 {
459 return weakThis;
460 }
461 private WeakPtr<T> weakThis;
462 }
463
464 public inline void EnableSharedFromThis<T>(void*, void*, const SharedCount<T>&)
465 {
466 }
467
468 public void EnableSharedFromThis<T, U>(ShareableFromThis<T>* left, U* right, const SharedCount<U>& count)
469 {
470 if (left != null)
471 {
472 left->GetWeakThis().Assign(cast<T*>(right), SharedCountCast<T>(count));
473 }
474 }
475
476 [system_default]
477 public TextWriter& operator<<<T>(TextWriter& writer, const SharedPtr<T>& ptr)
478 {
479 if (writer.Error()) return writer;
480 if (ptr.IsNull())
481 {
482 writer << "null";
483 }
484 else
485 {
486 const T& temp = *ptr;
487 writer << temp;
488 }
489 return writer;
490 }