![]() |
libfilezilla
|
00001 #ifndef LIBFILEZILLA_OPTIONAL_HEADER 00002 #define LIBFILEZILLA_OPTIONAL_HEADER 00003 00004 00009 namespace fz { 00010 00018 template<typename T> 00019 class sparse_optional final 00020 { 00021 public: 00022 sparse_optional(); 00023 explicit sparse_optional(T const& v); 00024 00026 explicit sparse_optional(T * v); 00027 00028 sparse_optional(sparse_optional<T> const& v); 00029 sparse_optional(sparse_optional<T> && v) noexcept; 00030 ~sparse_optional(); 00031 00032 void clear(); 00033 00034 explicit operator bool() const { return v_ != 0; }; 00035 00036 T& operator*() { return *v_; } 00037 T const& operator*() const { return *v_; } 00038 00039 T* operator->() { return v_; } 00040 T const* operator->() const { return v_; } 00041 00042 bool operator==(sparse_optional<T> const& cmp) const; 00043 inline bool operator!=(sparse_optional<T> const& cmp) const { return !(*this == cmp); } 00044 bool operator<(sparse_optional<T> const& cmp) const; 00045 00046 sparse_optional<T>& operator=(sparse_optional<T> const& v); 00047 sparse_optional<T>& operator=(sparse_optional<T> && v) noexcept; 00048 private: 00049 T* v_; 00050 }; 00051 00052 00053 template<typename T> 00054 sparse_optional<T>::sparse_optional() 00055 : v_() 00056 { 00057 } 00058 00059 template<typename T> 00060 sparse_optional<T>::sparse_optional(T const& v) 00061 : v_(new T(v)) 00062 { 00063 } 00064 00065 template<typename T> 00066 sparse_optional<T>::sparse_optional(T * v) 00067 : v_(v) 00068 { 00069 } 00070 00071 template<typename T> 00072 sparse_optional<T>::sparse_optional(sparse_optional<T> const& v) 00073 { 00074 if (v) { 00075 v_ = new T(*v); 00076 } 00077 else { 00078 v_ = 0; 00079 } 00080 } 00081 00082 template<typename T> 00083 sparse_optional<T>::sparse_optional(sparse_optional<T> && v) noexcept 00084 { 00085 v_ = v.v_; 00086 v.v_ = 0; 00087 } 00088 00089 template<typename T> 00090 sparse_optional<T>::~sparse_optional() 00091 { 00092 delete v_; 00093 } 00094 00095 template<typename T> 00096 void sparse_optional<T>::clear() 00097 { 00098 delete v_; 00099 v_ = 0; 00100 } 00101 00102 template<typename T> 00103 sparse_optional<T>& sparse_optional<T>::operator=(sparse_optional<T> const& v) 00104 { 00105 if (this != &v) { 00106 delete v_; 00107 if (v.v_) { 00108 v_ = new T(*v.v_); 00109 } 00110 else { 00111 v_ = 0; 00112 } 00113 } 00114 00115 return *this; 00116 } 00117 00118 template<typename T> 00119 sparse_optional<T>& sparse_optional<T>::operator=(sparse_optional<T> && v) noexcept 00120 { 00121 if (this != &v) { 00122 delete v_; 00123 v_ = v.v_; 00124 v.v_ = 0; 00125 } 00126 00127 return *this; 00128 } 00129 00130 template<typename T> 00131 bool sparse_optional<T>::operator==(sparse_optional<T> const& cmp) const 00132 { 00133 if (!v_ && !cmp.v_) { 00134 return true; 00135 } 00136 00137 if (!v_ || !cmp.v_) { 00138 return false; 00139 } 00140 00141 return *v_ == *cmp.v_; 00142 } 00143 00144 template<typename T> 00145 bool sparse_optional<T>::operator<(sparse_optional<T> const& cmp) const 00146 { 00147 if (!v_ || !cmp.v_) { 00148 return cmp.v_ != 0; 00149 } 00150 00151 return *v_ < *cmp.v_; 00152 } 00153 00154 } 00155 00156 #endif