1 // =================================
  2 // Copyright (c) 2022 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* Get()
 71         {
 72             return ptr;
 73         }
 74         public inline nothrow bool IsNull() const
 75         {
 76             return ptr == null;
 77         }
 78         public inline nothrow T* operator->()
 79         {
 80             if (ptr == null)
 81             {
 82                 ThrowNullPointerException();
 83             }
 84             return ptr;
 85         }
 86         public inline nothrow const T* operator->() const
 87         {
 88             if (ptr == null)
 89             {
 90                 ThrowNullPointerException();
 91             }
 92             return ptr;
 93         }
 94         public inline nothrow T& operator*()
 95         {
 96             if (ptr == null)
 97             {
 98                 ThrowNullPointerException();
 99             }
100             return *ptr;
101         }
102         public inline nothrow const T& operator*() const
103         {
104             if (ptr == null)
105             {
106                 ThrowNullPointerException();
107             }
108             return *ptr;
109         }
110         public nothrow void Swap(Self& that)
111         {
112             Swap(ptrthat.ptr);
113         }
114         private T* ptr;
115     }
116 
117     public inline nothrow bool operator==<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
118     {
119         return left.Get() == right.Get();
120     }
121 
122     public inline nothrow bool operator<<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
123     {
124         return left.Get() < right.Get();
125     }
126 
127     [system_default="true"]
128     public TextWriter& operator<<<T>(TextWriter& writerconst UniquePtr<T>& ptr)
129     {
130         if (ptr.IsNull())
131         {
132             writer << "null";
133         }
134         else
135         {
136             const T& temp = *ptr;
137             writer << temp;
138         }
139         return writer;
140     }
141 }