mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-22 18:59:59 +08:00
Possible clarification and reimplementation of Ref<T> classes (#719)
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
parent
461d557674
commit
06ba1c10b9
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <ftxui/screen/string.hpp>
|
#include <ftxui/screen/string.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
@ -10,104 +11,85 @@ namespace ftxui {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class ConstRef {
|
class ConstRef {
|
||||||
public:
|
public:
|
||||||
ConstRef() {}
|
ConstRef() = default;
|
||||||
ConstRef(T t) : owned_(t) {}
|
ConstRef(const ConstRef<T>&) = default;
|
||||||
ConstRef(const T* t) : address_(t) {}
|
ConstRef(const T& t) : variant_(t) {}
|
||||||
ConstRef(const ConstRef& t) : owned_(t.owned_), address_(t.address_) {}
|
ConstRef(const T* t) : variant_(t) {}
|
||||||
ConstRef& operator=(const ConstRef& t) {
|
|
||||||
owned_ = t.owned_;
|
// Make a "resetable" reference
|
||||||
address_ = t.address_;
|
ConstRef<T>& operator=(const ConstRef<T>&) = default;
|
||||||
return *this;
|
|
||||||
}
|
// Accessors:
|
||||||
const T& operator*() const { return address_ ? *address_ : owned_; }
|
const T& operator()() const { return *Address(); }
|
||||||
const T& operator()() const { return address_ ? *address_ : owned_; }
|
const T& operator*() const { return *Address(); }
|
||||||
const T* operator->() const { return address_ ? address_ : &owned_; }
|
const T* operator->() const { return Address(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T owned_;
|
std::variant<T, const T*> variant_ = T{};
|
||||||
const T* address_ = nullptr;
|
|
||||||
|
const T* Address() const {
|
||||||
|
return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
|
||||||
|
: std::get<const T*>(variant_);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief An adapter. Own or reference an mutable object.
|
/// @brief An adapter. Own or reference an mutable object.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Ref {
|
class Ref {
|
||||||
public:
|
public:
|
||||||
Ref() {}
|
Ref() = default;
|
||||||
Ref(const T& t) : owned_(t) {}
|
Ref(const Ref<T>&) = default;
|
||||||
Ref(T&& t) : owned_(std::forward<T>(t)) {}
|
Ref(const T& t) : variant_(t) {}
|
||||||
Ref(T* t) : owned_(), address_(t) {}
|
Ref(T&& t) : variant_(std::forward<T>(t)) {}
|
||||||
Ref(const Ref& t) : owned_(t.owned_), address_(t.address_) {}
|
Ref(T* t) : variant_(t) {}
|
||||||
Ref& operator=(const Ref& t) {
|
|
||||||
owned_ = t.owned_;
|
// Make a "resetable" reference
|
||||||
address_ = t.address_;
|
Ref<T>& operator=(const Ref<T>&) = default;
|
||||||
return *this;
|
|
||||||
}
|
// Accessors:
|
||||||
T& operator*() { return address_ ? *address_ : owned_; }
|
T& operator()() { return *Address(); }
|
||||||
T& operator()() { return address_ ? *address_ : owned_; }
|
T& operator*() { return *Address(); }
|
||||||
T* operator->() { return address_ ? address_ : &owned_; }
|
T* operator->() { return Address(); }
|
||||||
|
const T& operator()() const { return *Address(); }
|
||||||
|
const T& operator*() const { return *Address(); }
|
||||||
|
const T* operator->() const { return Address(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T owned_;
|
std::variant<T, T*> variant_ = T{};
|
||||||
T* address_ = nullptr;
|
|
||||||
|
const T* Address() const {
|
||||||
|
return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
|
||||||
|
: std::get<T*>(variant_);
|
||||||
|
}
|
||||||
|
T* Address() {
|
||||||
|
return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
|
||||||
|
: std::get<T*>(variant_);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief An adapter. Own or reference a constant string. For convenience, this
|
/// @brief An adapter. Own or reference a constant string. For convenience, this
|
||||||
/// class convert multiple mutable string toward a shared representation.
|
/// class convert multiple mutable string toward a shared representation.
|
||||||
class StringRef {
|
class StringRef : public Ref<std::string> {
|
||||||
public:
|
public:
|
||||||
StringRef(std::string* ref) : address_(ref) {}
|
using Ref<std::string>::Ref;
|
||||||
StringRef(std::string ref) : owned_(std::move(ref)) {}
|
|
||||||
StringRef(const wchar_t* ref) : StringRef(to_string(std::wstring(ref))) {}
|
StringRef(const wchar_t* ref) : StringRef(to_string(std::wstring(ref))) {}
|
||||||
StringRef(const char* ref) : StringRef(std::string(ref)) {}
|
StringRef(const char* ref) : StringRef(std::string(ref)) {}
|
||||||
StringRef(const StringRef& t) : owned_(t.owned_), address_(t.address_) {}
|
|
||||||
StringRef& operator=(const StringRef& t) {
|
|
||||||
owned_ = t.owned_;
|
|
||||||
address_ = t.address_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
std::string& operator*() { return address_ ? *address_ : owned_; }
|
|
||||||
std::string& operator()() { return address_ ? *address_ : owned_; }
|
|
||||||
std::string* operator->() { return address_ ? address_ : &owned_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string owned_;
|
|
||||||
std::string* address_ = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief An adapter. Own or reference a constant string. For convenience, this
|
/// @brief An adapter. Own or reference a constant string. For convenience, this
|
||||||
/// class convert multiple immutable string toward a shared representation.
|
/// class convert multiple immutable string toward a shared representation.
|
||||||
class ConstStringRef {
|
class ConstStringRef : public ConstRef<std::string> {
|
||||||
public:
|
public:
|
||||||
ConstStringRef(const std::string* ref) : address_(ref) {}
|
using ConstRef<std::string>::ConstRef;
|
||||||
ConstStringRef(const std::wstring* ref) : ConstStringRef(to_string(*ref)) {}
|
|
||||||
ConstStringRef(std::string ref) : owned_(std::move(ref)) {}
|
|
||||||
ConstStringRef(std::wstring ref) : ConstStringRef(to_string(ref)) {}
|
|
||||||
ConstStringRef(const wchar_t* ref) : ConstStringRef(std::wstring(ref)) {}
|
|
||||||
ConstStringRef(const char* ref)
|
|
||||||
: ConstStringRef(to_wstring(std::string(ref))) {}
|
|
||||||
ConstStringRef(const ConstStringRef& t)
|
|
||||||
: owned_(t.owned_), address_(t.address_) {}
|
|
||||||
ConstStringRef& operator=(const ConstStringRef& t) {
|
|
||||||
owned_ = t.owned_;
|
|
||||||
address_ = t.address_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ConstStringRef& operator=(ConstStringRef&& t) {
|
|
||||||
owned_ = std::move(t.owned_);
|
|
||||||
address_ = t.address_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
const std::string& operator()() const {
|
|
||||||
return address_ ? *address_ : owned_;
|
|
||||||
}
|
|
||||||
const std::string& operator*() const { return address_ ? *address_ : owned_; }
|
|
||||||
const std::string* operator->() const {
|
|
||||||
return address_ ? address_ : &owned_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
ConstStringRef(const std::wstring* ref) : ConstStringRef(to_string(*ref)) {}
|
||||||
std::string owned_;
|
ConstStringRef(const std::wstring ref) : ConstStringRef(to_string(ref)) {}
|
||||||
const std::string* address_ = nullptr;
|
ConstStringRef(const wchar_t* ref)
|
||||||
|
: ConstStringRef(to_string(std::wstring(ref))) {}
|
||||||
|
ConstStringRef(const char* ref) : ConstStringRef(std::string(ref)) {}
|
||||||
|
|
||||||
|
ConstStringRef& operator=(const ConstStringRef&) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief An adapter. Reference a list of strings.
|
/// @brief An adapter. Reference a list of strings.
|
||||||
|
@ -568,7 +568,7 @@ Component Input(InputOption option) {
|
|||||||
/// placeholder
|
/// placeholder
|
||||||
/// ```
|
/// ```
|
||||||
Component Input(StringRef content, InputOption option) {
|
Component Input(StringRef content, InputOption option) {
|
||||||
option.content = content;
|
option.content = std::move(content);
|
||||||
return Make<InputBase>(std::move(option));
|
return Make<InputBase>(std::move(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,8 +594,8 @@ Component Input(StringRef content, InputOption option) {
|
|||||||
/// placeholder
|
/// placeholder
|
||||||
/// ```
|
/// ```
|
||||||
Component Input(StringRef content, StringRef placeholder, InputOption option) {
|
Component Input(StringRef content, StringRef placeholder, InputOption option) {
|
||||||
option.content = content;
|
option.content = std::move(content);
|
||||||
option.placeholder = placeholder;
|
option.placeholder = std::move(placeholder);
|
||||||
return Make<InputBase>(std::move(option));
|
return Make<InputBase>(std::move(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,15 +849,14 @@ class CanvasNodeBase : public Node {
|
|||||||
Element canvas(ConstRef<Canvas> canvas) {
|
Element canvas(ConstRef<Canvas> canvas) {
|
||||||
class Impl : public CanvasNodeBase {
|
class Impl : public CanvasNodeBase {
|
||||||
public:
|
public:
|
||||||
// NOLINTNEXTLINE
|
explicit Impl(ConstRef<Canvas> canvas) : canvas_(canvas) {
|
||||||
explicit Impl(ConstRef<Canvas> canvas) : canvas_(std::move(canvas)) {
|
|
||||||
requirement_.min_x = (canvas_->width() + 1) / 2;
|
requirement_.min_x = (canvas_->width() + 1) / 2;
|
||||||
requirement_.min_y = (canvas_->height() + 3) / 4;
|
requirement_.min_y = (canvas_->height() + 3) / 4;
|
||||||
}
|
}
|
||||||
const Canvas& canvas() final { return *canvas_; }
|
const Canvas& canvas() final { return *canvas_; }
|
||||||
ConstRef<Canvas> canvas_;
|
ConstRef<Canvas> canvas_;
|
||||||
};
|
};
|
||||||
return std::make_shared<Impl>(std::move(canvas));
|
return std::make_shared<Impl>(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Produce an element drawing a canvas of requested size.
|
/// @brief Produce an element drawing a canvas of requested size.
|
||||||
|
Loading…
Reference in New Issue
Block a user