libfilezilla
shared.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_SHARED_HEADER
2 #define LIBFILEZILLA_SHARED_HEADER
3 
4 #include <memory>
5 
9 namespace fz {
10 
24 template<typename T, bool Init = false> class shared_optional final
25 {
26 public:
28  shared_optional(shared_optional<T, Init> const& v) = default;
29  shared_optional(shared_optional<T, Init> && v) noexcept = default;
30  explicit shared_optional(const T& v);
31 
32  void clear();
33 
40  T& get();
41 
42  const T& operator*() const;
43  const T* operator->() const;
44 
53  bool operator==(shared_optional<T, Init> const& cmp) const;
54  bool operator==(T const& cmp) const;
55  bool operator<(shared_optional<T, Init> const& cmp) const;
56  bool operator<(T const& cmp) const;
57 
59  bool is_same(shared_optional<T, Init> const& cmp) const;
60 
61  inline bool operator!=(const shared_optional<T, Init>& cmp) const { return !(*this == cmp); }
62  inline bool operator!=(T const& cmp) const { return !(*this == cmp); }
64 
65  shared_optional<T, Init>& operator=(shared_optional<T, Init> const& v) = default;
66  shared_optional<T, Init>& operator=(shared_optional<T, Init> && v) noexcept = default;
67 
68  explicit operator bool() const { return static_cast<bool>(data_); }
69 
70  bool empty() const { return !data_; }
71 private:
72  std::shared_ptr<T> data_;
73 };
74 
82 template<typename T>
84 
85 
86 template<typename T, bool Init> shared_optional<T, Init>::shared_optional()
87  : data_(Init ? std::make_shared<T>() : nullptr)
88 {
89 }
90 
91 template<typename T, bool Init> shared_optional<T, Init>::shared_optional(const T& v)
92  : data_(std::make_shared<T>(v))
93 {
94 }
95 
96 template<typename T, bool Init> bool shared_optional<T, Init>::operator==(shared_optional<T, Init> const& cmp) const
97 {
98  if (data_ == cmp.data_) {
99  return true;
100  }
101  else if (!Init && (!data_ || !cmp.data_)) {
102  return false;
103  }
104 
105  return *data_ == *cmp.data_;
106 }
107 
108 template<typename T, bool Init> bool shared_optional<T, Init>::operator==(T const& cmp) const
109 {
110  if (!Init && !data_) {
111  return false;
112  }
113  return *data_ == cmp;
114 }
115 
116 template<typename T, bool Init> bool shared_optional<T, Init>::is_same(shared_optional<T, Init> const& cmp) const
117 {
118  return data_ == cmp.data_;
119 }
120 
121 template<typename T, bool Init> T& shared_optional<T, Init>::get()
122 {
123  if (!Init && !data_) {
124  data_ = std::make_shared<T>();
125  }
126  if (!data_.unique()) {
127  data_ = std::make_shared<T>(*data_);
128  }
129 
130  return *data_;
131 }
132 
133 template<typename T, bool Init> bool shared_optional<T, Init>::operator<(shared_optional<T, Init> const& cmp) const
134 {
135  if (data_ == cmp.data_)
136  return false;
137  else if (!Init && !data_) {
138  return static_cast<bool>(cmp.data_);
139  }
140  else if (!Init && !cmp.data_) {
141  return false;
142  }
143  return *data_ < *cmp.data_;
144 }
145 
146 template<typename T, bool Init> bool shared_optional<T, Init>::operator<(T const& cmp) const
147 {
148  if (!Init && !data_) {
149  return true;
150  }
151  return *data_ < cmp;
152 }
153 
154 template<typename T, bool Init> void shared_optional<T, Init>::clear()
155 {
156  if (!Init) {
157  data_.reset();
158  }
159  else if (data_.unique()) {
160  *data_ = T();
161  }
162  else {
163  data_ = std::make_shared<T>();
164  }
165 }
166 
167 template<typename T, bool Init> const T& shared_optional<T, Init>::operator*() const
168 {
169  return *data_;
170 }
171 
172 template<typename T, bool Init> const T* shared_optional<T, Init>::operator->() const
173 {
174  return data_.get();
175 }
176 
177 }
178 
179 #endif
shared_optional is like std::shared_ptr but with relational operators acting like C++17&#39;s std::option...
Definition: shared.hpp:24
bool is_same(shared_optional< T, Init > const &cmp) const
Only compares the pointers.
Definition: shared.hpp:116
The namespace used by libfilezilla.
Definition: apply.hpp:16