1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System.IO;
  7 
  8 namespace System
  9 {
 10     public class UniquePtr<T>
 11     {
 12         private typedef UniquePtr<T> Self;
 13 
 14         public nothrow UniquePtr() : ptr(null)
 15         {
 16         }
 17         public explicit nothrow UniquePtr(T* ptr_) : ptr(ptr_)
 18         {
 19         }
 20         suppress UniquePtr(const Self&);
 21         public nothrow UniquePtr(Self&& that) : ptr(that.Release())
 22         {
 23         }
 24         public nothrow void operator=(T* ptr_)
 25         {
 26             if (ptr != null)
 27             {
 28                 delete ptr;
 29             }
 30             ptr = ptr_;
 31         }
 32         suppress void operator=(const Self&);
 33         public nothrow void operator=(Self&& that)
 34         {
 35             if (ptr != null)
 36             {
 37                 delete ptr;
 38             }
 39             ptr = that.Release();
 40         }
 41         public ~UniquePtr()
 42         {
 43             if (ptr != null)
 44             {
 45                 delete ptr;
 46             }
 47         }
 48         public nothrow void Reset()
 49         {
 50             if (ptr != null)
 51             {
 52                 delete ptr;
 53                 ptr = null;
 54             }
 55         }
 56         public nothrow void Reset(T* ptr_)
 57         {
 58             if (ptr != null)
 59             {
 60                 delete ptr;
 61             }
 62             ptr = ptr_;
 63         }
 64         public inline nothrow T* Release()
 65         {
 66             T* ptr_ = ptr;
 67             ptr = null;
 68             return ptr_;
 69         }
 70         public inline nothrow T* GetPtr()
 71         {
 72             return ptr;
 73         }
 74         public inline nothrow T* Get()
 75         {
 76             return ptr;
 77         }
 78         public inline nothrow bool IsNull() const
 79         {
 80             return ptr == null;
 81         }
 82         public T* operator->()
 83         {
 84             if (ptr == null)
 85             {
 86                 ThrowNullPointerException();
 87             }
 88             return ptr;
 89         }
 90         public inline const T* operator->() const
 91         {
 92             if (ptr == null)
 93             {
 94                 ThrowNullPointerException();
 95             }
 96             return ptr;
 97         }
 98         public inline T& operator*()
 99         {
100             if (ptr == null)
101             {
102                 ThrowNullPointerException();
103             }
104             return *ptr;
105         }
106         public inline const T& operator*() const
107         {
108             if (ptr == null)
109             {
110                 ThrowNullPointerException();
111             }
112             return *ptr;
113         }
114         public nothrow void Swap(Self& that)
115         {
116             Swap(ptrthat.ptr);
117         }
118         private T* ptr;
119     }
120 
121     public inline nothrow bool operator==<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
122     {
123         return left.Get() == right.Get();
124     }
125 
126     public inline nothrow bool operator<<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
127     {
128         return left.Get() < right.Get();
129     }
130 
131     [system_default="true"]
132     public TextWriter& operator<<<T>(TextWriter& writerconst UniquePtr<T>& ptr)
133     {
134         if (ptr.IsNull())
135         {
136             writer << "null";
137         }
138         else
139         {
140             const T& temp = *ptr;
141             writer << temp;
142         }
143         return writer;
144     }
145 }