![]() |
libfilezilla
|
00001 #ifndef LIBFILEZILLA_SHARED_HEADER 00002 #define LIBFILEZILLA_SHARED_HEADER 00003 00004 #include <memory> 00005 00009 namespace fz { 00010 00024 template<typename T, bool Init = false> class shared_optional final 00025 { 00026 public: 00027 shared_optional(); 00028 shared_optional(shared_optional<T, Init> const& v) = default; 00029 shared_optional(shared_optional<T, Init> && v) noexcept = default; 00030 explicit shared_optional(const T& v); 00031 00032 void clear(); 00033 00040 T& get(); 00041 00042 const T& operator*() const; 00043 const T* operator->() const; 00044 00053 bool operator==(shared_optional<T, Init> const& cmp) const; 00054 bool operator==(T const& cmp) const; 00055 bool operator<(shared_optional<T, Init> const& cmp) const; 00056 bool operator<(T const& cmp) const; 00057 00059 bool is_same(shared_optional<T, Init> const& cmp) const; 00060 00061 inline bool operator!=(const shared_optional<T, Init>& cmp) const { return !(*this == cmp); } 00062 inline bool operator!=(T const& cmp) const { return !(*this == cmp); } 00064 00065 shared_optional<T, Init>& operator=(shared_optional<T, Init> const& v) = default; 00066 shared_optional<T, Init>& operator=(shared_optional<T, Init> && v) noexcept = default; 00067 00068 explicit operator bool() const { return static_cast<bool>(data_); } 00069 00070 bool empty() const { return !data_; } 00071 private: 00072 std::shared_ptr<T> data_; 00073 }; 00074 00082 template<typename T> 00083 using shared_value = shared_optional<T, true>; 00084 00085 00086 template<typename T, bool Init> shared_optional<T, Init>::shared_optional() 00087 : data_(Init ? std::make_shared<T>() : 0) 00088 { 00089 } 00090 00091 template<typename T, bool Init> shared_optional<T, Init>::shared_optional(const T& v) 00092 : data_(std::make_shared<T>(v)) 00093 { 00094 } 00095 00096 template<typename T, bool Init> bool shared_optional<T, Init>::operator==(shared_optional<T, Init> const& cmp) const 00097 { 00098 if (data_ == cmp.data_) { 00099 return true; 00100 } 00101 else if (!Init && (!data_ || !cmp.data_)) { 00102 return false; 00103 } 00104 00105 return *data_ == *cmp.data_; 00106 } 00107 00108 template<typename T, bool Init> bool shared_optional<T, Init>::operator==(T const& cmp) const 00109 { 00110 if (!Init && !data_) { 00111 return false; 00112 } 00113 return *data_ == cmp; 00114 } 00115 00116 template<typename T, bool Init> bool shared_optional<T, Init>::is_same(shared_optional<T, Init> const& cmp) const 00117 { 00118 return data_ == cmp.data_; 00119 } 00120 00121 template<typename T, bool Init> T& shared_optional<T, Init>::get() 00122 { 00123 if (!Init && !data_) { 00124 data_ = std::make_shared<T>(); 00125 } 00126 if (!data_.unique()) { 00127 data_ = std::make_shared<T>(*data_); 00128 } 00129 00130 return *data_; 00131 } 00132 00133 template<typename T, bool Init> bool shared_optional<T, Init>::operator<(shared_optional<T, Init> const& cmp) const 00134 { 00135 if (data_ == cmp.data_) 00136 return false; 00137 else if (!Init && !data_) { 00138 return static_cast<bool>(cmp.data_); 00139 } 00140 else if (!Init && !cmp.data_) { 00141 return false; 00142 } 00143 return *data_ < *cmp.data_; 00144 } 00145 00146 template<typename T, bool Init> bool shared_optional<T, Init>::operator<(T const& cmp) const 00147 { 00148 if (!Init && !data_) { 00149 return true; 00150 } 00151 return *data_ < cmp; 00152 } 00153 00154 template<typename T, bool Init> void shared_optional<T, Init>::clear() 00155 { 00156 if (!Init) { 00157 data_.reset(); 00158 } 00159 else if (data_.unique()) { 00160 *data_ = T(); 00161 } 00162 else { 00163 data_ = std::make_shared<T>(); 00164 } 00165 } 00166 00167 template<typename T, bool Init> const T& shared_optional<T, Init>::operator*() const 00168 { 00169 return *data_; 00170 } 00171 00172 template<typename T, bool Init> const T* shared_optional<T, Init>::operator->() const 00173 { 00174 return data_.get(); 00175 } 00176 00177 } 00178 00179 #endif