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:
27  shared_optional() noexcept(!Init || std::is_nothrow_constructible_v<T>);
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() noexcept(!Init || std::is_nothrow_constructible_v<T>)
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_.use_count() > 1) {
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  }
138  else if (!Init && !data_) {
139  return static_cast<bool>(cmp.data_);
140  }
141  else if (!Init && !cmp.data_) {
142  return false;
143  }
144  return *data_ < *cmp.data_;
145 }
146 
147 template<typename T, bool Init> bool shared_optional<T, Init>::operator<(T const& cmp) const
148 {
149  if (!Init && !data_) {
150  return true;
151  }
152  return *data_ < cmp;
153 }
154 
155 template<typename T, bool Init> void shared_optional<T, Init>::clear()
156 {
157  if (!Init) {
158  data_.reset();
159  }
160  else if (data_.use_count() <= 1) {
161  *data_ = T();
162  }
163  else {
164  data_ = std::make_shared<T>();
165  }
166 }
167 
168 template<typename T, bool Init> const T& shared_optional<T, Init>::operator*() const
169 {
170  return *data_;
171 }
172 
173 template<typename T, bool Init> const T* shared_optional<T, Init>::operator->() const
174 {
175  return data_.get();
176 }
177 
178 }
179 
180 #endif
shared_optional is like std::shared_ptr but with relational operators acting like C++17's std::option...
Definition: shared.hpp:25
bool is_same(shared_optional< T, Init > const &cmp) const
Only compares the pointers.
Definition: shared.hpp:116
T & get()
Gets a reference to the stored object.
Definition: shared.hpp:121
The namespace used by libfilezilla.
Definition: apply.hpp:17
bool operator==(symmetric_key const &lhs, symmetric_key const &rhs)
Side-channel safe comparison.