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