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