libfilezilla
Loading...
Searching...
No Matches
shared.hpp
Go to the documentation of this file.
1#ifndef LIBFILEZILLA_SHARED_HEADER
2#define LIBFILEZILLA_SHARED_HEADER
3
4#include <memory>
5
9namespace fz {
10
24template<typename T, bool Init = false> class shared_optional final
25{
26public:
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
72 long use_count() const { return data_.use_count(); }
73
74private:
75 std::shared_ptr<T> data_;
76};
77
85template<typename T>
87
88
89template<typename T, bool Init> shared_optional<T, Init>::shared_optional() noexcept(!Init || std::is_nothrow_constructible_v<T>)
90 : data_(Init ? std::make_shared<T>() : nullptr)
91{
92}
93
94template<typename T, bool Init> shared_optional<T, Init>::shared_optional(const T& v)
95 : data_(std::make_shared<T>(v))
96{
97}
98
99template<typename T, bool Init> bool shared_optional<T, Init>::operator==(shared_optional<T, Init> const& cmp) const
100{
101 if (data_ == cmp.data_) {
102 return true;
103 }
104 else if (!Init && (!data_ || !cmp.data_)) {
105 return false;
106 }
107
108 return *data_ == *cmp.data_;
109}
110
111template<typename T, bool Init> bool shared_optional<T, Init>::operator==(T const& cmp) const
112{
113 if (!Init && !data_) {
114 return false;
115 }
116 return *data_ == cmp;
117}
118
119template<typename T, bool Init> bool shared_optional<T, Init>::is_same(shared_optional<T, Init> const& cmp) const
120{
121 return data_ == cmp.data_;
122}
123
124template<typename T, bool Init> T& shared_optional<T, Init>::get()
125{
126 if (!Init && !data_) {
127 data_ = std::make_shared<T>();
128 }
129 if (data_.use_count() > 1) {
130 data_ = std::make_shared<T>(*data_);
131 }
132
133 return *data_;
134}
135
136template<typename T, bool Init> bool shared_optional<T, Init>::operator<(shared_optional<T, Init> const& cmp) const
137{
138 if (data_ == cmp.data_) {
139 return false;
140 }
141 else if (!Init && !data_) {
142 return static_cast<bool>(cmp.data_);
143 }
144 else if (!Init && !cmp.data_) {
145 return false;
146 }
147 return *data_ < *cmp.data_;
148}
149
150template<typename T, bool Init> bool shared_optional<T, Init>::operator<(T const& cmp) const
151{
152 if (!Init && !data_) {
153 return true;
154 }
155 return *data_ < cmp;
156}
157
158template<typename T, bool Init> void shared_optional<T, Init>::clear()
159{
160 if (!Init) {
161 data_.reset();
162 }
163 else if (data_.use_count() <= 1) {
164 *data_ = T();
165 }
166 else {
167 data_ = std::make_shared<T>();
168 }
169}
170
171template<typename T, bool Init> const T& shared_optional<T, Init>::operator*() const
172{
173 return *data_;
174}
175
176template<typename T, bool Init> const T* shared_optional<T, Init>::operator->() const
177{
178 return data_.get();
179}
180
181}
182
183#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:119
T & get()
Gets a reference to the stored object.
Definition shared.hpp:124
The namespace used by libfilezilla.
Definition apply.hpp:17
shared_optional< T, true > shared_value
like shared_optional but can never be empty
Definition shared.hpp:86