1 // =================================
  2 // Copyright (c) 2024 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 UniquePtr() : ptr(null)
 15         {
 16         }
 17         public explicit UniquePtr(T* ptr_) : ptr(ptr_)
 18         {
 19         }
 20         suppress UniquePtr(const Self&);
 21         public UniquePtr(Self&& that) : ptr(that.Release())
 22         {
 23         }
 24         public 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 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 void Reset()
 49         {
 50             if (ptr != null)
 51             {
 52                 delete ptr;
 53                 ptr = null;
 54             }
 55         }
 56         public void Reset(T* ptr_)
 57         {
 58             if (ptr != null)
 59             {
 60                 delete ptr;
 61             }
 62             ptr = ptr_;
 63         }
 64         public inline T* Release()
 65         {
 66             T* ptr_ = ptr;
 67             ptr = null;
 68             return ptr_;
 69         }
 70         public inline T* GetPtr()
 71         {
 72             return ptr;
 73         }
 74         public inline T* Get()
 75         {
 76             return ptr;
 77         }
 78         public inline bool IsNull() const
 79         {
 80             return ptr == null;
 81         }
 82         public T* operator->()
 83         {
 84             #assert(ptr != null);
 85             return ptr;
 86         }
 87         public inline const T* operator->() const
 88         {
 89             #assert(ptr != null);
 90             return ptr;
 91         }
 92         public inline T& operator*()
 93         {
 94             #assert(ptr != null);
 95             return *ptr;
 96         }
 97         public inline const T& operator*() const
 98         {
 99             #assert(ptr != null);
100             return *ptr;
101         }
102         public void Swap(Self& that)
103         {
104             Swap(ptrthat.ptr);
105         }
106         private T* ptr;
107     }
108 
109     public inline bool operator==<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
110     {
111         return left.Get() == right.Get();
112     }
113 
114     public inline bool operator==<T>(const UniquePtr<T>& leftNullPtrType)
115     {
116         return left.Get() == null;
117     }
118 
119     public inline bool operator<<T>(const UniquePtr<T>& leftconst UniquePtr<T>& right)
120     {
121         return left.Get() < right.Get();
122     }
123 
124     [system_default]
125     public TextWriter& operator<<<T>(TextWriter& writerconst UniquePtr<T>& ptr)
126     {
127         if (writer.Error()) return writer;
128         if (ptr.IsNull())
129         {
130             writer << "null";
131         }
132         else
133         {
134             const T& temp = *ptr;
135             writer << temp;
136         }
137         return writer;
138     }