/usr/include/libfilezilla/shared.hpp is in libfilezilla-dev 0.4.0.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #ifndef LIBFILEZILLA_SHARED_HEADER
#define LIBFILEZILLA_SHARED_HEADER
#include <memory>
/** \file
* \brief Declares the shared_optionsl and shared_value template classes.
*/
namespace fz {
/** \brief shared_optional is like std::shared_ptr but with relational operators acting like
* C++17's std::optional
*
* \tparam T that can be stored in the shared_optional
* \tparam Init controls whether the optional can be empty. If \c false, the default,
* it acts like a normal optional/shared_ptr. If \c true, it can never be
* empty. \see shared_value
*
* This class is thread-safe under the following assumptions:
* - The type stored in it must be thread-safe for reading
* - Any shared_optional instance a non-const member is called on (e.g. get())
* must not be used in different threads concurrently.
*/
template<typename T, bool Init = false> class shared_optional final
{
public:
shared_optional();
shared_optional(shared_optional<T, Init> const& v) = default;
shared_optional(shared_optional<T, Init> && v) noexcept = default;
explicit shared_optional(const T& v);
void clear();
/// Gets a reference to the stored object. A new object is created it if is not set.
T& get();
const T& operator*() const;
const T* operator->() const;
/**
* \name Deep relational operators
*
* If two instances point to
* different objects, those objects are compared.
* Empty instances are less than non-empty instances.
* \{
*/
bool operator==(shared_optional<T, Init> const& cmp) const;
bool operator==(T const& cmp) const;
bool operator<(shared_optional<T, Init> const& cmp) const;
bool operator<(T const& cmp) const;
inline bool operator!=(const shared_optional<T, Init>& cmp) const { return !(*this == cmp); }
inline bool operator!=(T const& cmp) const { return !(*this == cmp); }
/// \}
shared_optional<T, Init>& operator=(shared_optional<T, Init> const& v) = default;
shared_optional<T, Init>& operator=(shared_optional<T, Init> && v) noexcept = default;
explicit operator bool() const { return static_cast<bool>(data_); }
bool empty() const { return !data_; }
private:
std::shared_ptr<T> data_;
};
/** \brief like shared_optional but can never be empty
*
* All operations that would result in an empty shared_optional instead
* result in a default-constructed value.
*
* As such, operator* and operator-> are always well-defined.
*/
template<typename T>
using shared_value = shared_optional<T, true>;
template<typename T, bool Init> shared_optional<T, Init>::shared_optional()
: data_(Init ? std::make_shared<T>() : 0)
{
}
template<typename T, bool Init> shared_optional<T, Init>::shared_optional(const T& v)
: data_(std::make_shared<T>(v))
{
}
template<typename T, bool Init> bool shared_optional<T, Init>::operator==(shared_optional<T, Init> const& cmp) const
{
if (data_ == cmp.data_) {
return true;
}
else if (!Init && (!data_ || !cmp.data_)) {
return false;
}
return *data_ == *cmp.data_;
}
template<typename T, bool Init> bool shared_optional<T, Init>::operator==(T const& cmp) const
{
if (!Init && !data_) {
return false;
}
return *data_ == cmp;
}
template<typename T, bool Init> T& shared_optional<T, Init>::get()
{
if (!Init && !data_) {
data_ = std::make_shared<T>();
}
if (!data_.unique()) {
data_ = std::make_shared<T>(*data_);
}
return *data_;
}
template<typename T, bool Init> bool shared_optional<T, Init>::operator<(shared_optional<T, Init> const& cmp) const
{
if (data_ == cmp.data_)
return false;
else if (!Init && !data_) {
return static_cast<bool>(cmp.data_);
}
else if (!Init && !cmp.data_) {
return false;
}
return *data_ < *cmp.data_;
}
template<typename T, bool Init> bool shared_optional<T, Init>::operator<(T const& cmp) const
{
if (!Init && !data_) {
return true;
}
return *data_ < cmp;
}
template<typename T, bool Init> void shared_optional<T, Init>::clear()
{
if (!Init) {
data_.reset();
}
else if (data_.unique()) {
*data_ = T();
}
else {
data_ = std::make_shared<T>();
}
}
template<typename T, bool Init> const T& shared_optional<T, Init>::operator*() const
{
return *data_;
}
template<typename T, bool Init> const T* shared_optional<T, Init>::operator->() const
{
return data_.get();
}
}
#endif
|