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     }