libfilezilla
shared.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines