mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-11-01 02:58:12 +08:00 
			
		
		
		
	Possible clarification and reimplementation of Ref<T> classes (#719)
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
		| @@ -3,6 +3,7 @@ | ||||
|  | ||||
| #include <ftxui/screen/string.hpp> | ||||
| #include <string> | ||||
| #include <variant> | ||||
|  | ||||
| namespace ftxui { | ||||
|  | ||||
| @@ -10,104 +11,85 @@ namespace ftxui { | ||||
| template <typename T> | ||||
| class ConstRef { | ||||
|  public: | ||||
|   ConstRef() {} | ||||
|   ConstRef(T t) : owned_(t) {} | ||||
|   ConstRef(const T* t) : address_(t) {} | ||||
|   ConstRef(const ConstRef& t) : owned_(t.owned_), address_(t.address_) {} | ||||
|   ConstRef& operator=(const ConstRef& t) { | ||||
|     owned_ = t.owned_; | ||||
|     address_ = t.address_; | ||||
|     return *this; | ||||
|   } | ||||
|   const T& operator*() const { return address_ ? *address_ : owned_; } | ||||
|   const T& operator()() const { return address_ ? *address_ : owned_; } | ||||
|   const T* operator->() const { return address_ ? address_ : &owned_; } | ||||
|   ConstRef() = default; | ||||
|   ConstRef(const ConstRef<T>&) = default; | ||||
|   ConstRef(const T& t) : variant_(t) {} | ||||
|   ConstRef(const T* t) : variant_(t) {} | ||||
|  | ||||
|   // Make a "resetable" reference | ||||
|   ConstRef<T>& operator=(const ConstRef<T>&) = default; | ||||
|  | ||||
|   // Accessors: | ||||
|   const T& operator()() const { return *Address(); } | ||||
|   const T& operator*() const { return *Address(); } | ||||
|   const T* operator->() const { return Address(); } | ||||
|  | ||||
|  private: | ||||
|   T owned_; | ||||
|   const T* address_ = nullptr; | ||||
|   std::variant<T, const T*> variant_ = T{}; | ||||
|  | ||||
|   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. | ||||
| template <typename T> | ||||
| class Ref { | ||||
|  public: | ||||
|   Ref() {} | ||||
|   Ref(const T& t) : owned_(t) {} | ||||
|   Ref(T&& t) : owned_(std::forward<T>(t)) {} | ||||
|   Ref(T* t) : owned_(), address_(t) {} | ||||
|   Ref(const Ref& t) : owned_(t.owned_), address_(t.address_) {} | ||||
|   Ref& operator=(const Ref& t) { | ||||
|     owned_ = t.owned_; | ||||
|     address_ = t.address_; | ||||
|     return *this; | ||||
|   } | ||||
|   T& operator*() { return address_ ? *address_ : owned_; } | ||||
|   T& operator()() { return address_ ? *address_ : owned_; } | ||||
|   T* operator->() { return address_ ? address_ : &owned_; } | ||||
|   Ref() = default; | ||||
|   Ref(const Ref<T>&) = default; | ||||
|   Ref(const T& t) : variant_(t) {} | ||||
|   Ref(T&& t) : variant_(std::forward<T>(t)) {} | ||||
|   Ref(T* t) : variant_(t) {} | ||||
|  | ||||
|   // Make a "resetable" reference | ||||
|   Ref<T>& operator=(const Ref<T>&) = default; | ||||
|  | ||||
|   // Accessors: | ||||
|   T& operator()() { return *Address(); } | ||||
|   T& operator*() { return *Address(); } | ||||
|   T* operator->() { return Address(); } | ||||
|   const T& operator()() const { return *Address(); } | ||||
|   const T& operator*() const { return *Address(); } | ||||
|   const T* operator->() const { return Address(); } | ||||
|  | ||||
|  private: | ||||
|   T owned_; | ||||
|   T* address_ = nullptr; | ||||
|   std::variant<T, T*> variant_ = T{}; | ||||
|  | ||||
|   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 | ||||
| /// class convert multiple mutable string toward a shared representation. | ||||
| class StringRef { | ||||
| class StringRef : public Ref<std::string> { | ||||
|  public: | ||||
|   StringRef(std::string* ref) : address_(ref) {} | ||||
|   StringRef(std::string ref) : owned_(std::move(ref)) {} | ||||
|   using Ref<std::string>::Ref; | ||||
|  | ||||
|   StringRef(const wchar_t* ref) : StringRef(to_string(std::wstring(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 | ||||
| /// class convert multiple immutable string toward a shared representation. | ||||
| class ConstStringRef { | ||||
| class ConstStringRef : public ConstRef<std::string> { | ||||
|  public: | ||||
|   ConstStringRef(const std::string* ref) : address_(ref) {} | ||||
|   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_; | ||||
|   } | ||||
|   using ConstRef<std::string>::ConstRef; | ||||
|  | ||||
|  private: | ||||
|   std::string owned_; | ||||
|   const std::string* address_ = nullptr; | ||||
|   ConstStringRef(const std::wstring* ref) : ConstStringRef(to_string(*ref)) {} | ||||
|   ConstStringRef(const std::wstring ref) : ConstStringRef(to_string(ref)) {} | ||||
|   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. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 mr-mocap
					mr-mocap