From 942ab6a82d8dd555e7b8961a2e2dcab8c6bac54e Mon Sep 17 00:00:00 2001 From: ArthurSonzogni Date: Sun, 14 Dec 2025 18:08:16 +0100 Subject: [PATCH] Add std::string_view to ConstStringRef --- include/ftxui/util/ref.hpp | 125 +++++++++++++------------------ src/ftxui/component/menu.cpp | 2 +- src/ftxui/component/radiobox.cpp | 2 +- 3 files changed, 56 insertions(+), 73 deletions(-) diff --git a/include/ftxui/util/ref.hpp b/include/ftxui/util/ref.hpp index d0a615a69..f30ff2fcb 100644 --- a/include/ftxui/util/ref.hpp +++ b/include/ftxui/util/ref.hpp @@ -18,8 +18,13 @@ template class ConstRef { public: ConstRef() = default; + + // Owning constructors: ConstRef(T t) : variant_(std::move(t)) {} // NOLINT + + // Referencing constructors: ConstRef(const T* t) : variant_(t) {} // NOLINT + ConstRef& operator=(ConstRef&&) noexcept = default; ConstRef(const ConstRef&) = default; ConstRef(ConstRef&&) noexcept = default; @@ -47,8 +52,13 @@ template class Ref { public: Ref() = default; + + // Owning constructors: Ref(T t) : variant_(std::move(t)) {} // NOLINT + // + // Referencing constructors: Ref(T* t) : variant_(t) {} // NOLINT + // ~Ref() = default; Ref& operator=(Ref&&) noexcept = default; Ref(const Ref&) = default; @@ -84,10 +94,15 @@ class StringRef : public Ref { public: using Ref::Ref; + // Owning constructors: StringRef(const wchar_t* ref) // NOLINT : StringRef(to_string(std::wstring(ref))) {} StringRef(const char* ref) // NOLINT : StringRef(std::string(ref)) {} + StringRef(std::string_view ref) // NOLINT + : StringRef(std::string(ref)) {} + StringRef(std::wstring_view ref) // NOLINT + : StringRef(to_string(ref)) {} }; /// @brief An adapter. Own or reference a constant string. For convenience, this @@ -96,14 +111,21 @@ class ConstStringRef : public ConstRef { public: using ConstRef::ConstRef; + // Referencing constructors: ConstStringRef(const std::wstring* ref) // NOLINT : ConstStringRef(to_string(*ref)) {} + + // Owning constructors: ConstStringRef(const std::wstring ref) // NOLINT : ConstStringRef(to_string(ref)) {} + ConstStringRef(std::wstring_view ref) // NOLINT + : ConstStringRef(to_string(ref)) {} ConstStringRef(const wchar_t* ref) // NOLINT : ConstStringRef(to_string(std::wstring(ref))) {} ConstStringRef(const char* ref) // NOLINT : ConstStringRef(std::string(ref)) {} + ConstStringRef(std::string_view ref) // NOLINT + : ConstStringRef(std::string(ref)) {} }; /// @brief An adapter. Reference a list of strings. @@ -144,33 +166,26 @@ class ConstStringListRef { ConstStringListRef(ConstStringListRef&&) = default; ConstStringListRef(const ConstStringListRef&) = default; - ConstStringListRef(std::vector value) // NOLINT - { + ConstStringListRef(std::vector value) { // NOLINT variant_ = std::make_shared(value); } - ConstStringListRef(const std::vector* value) // NOLINT - { + ConstStringListRef(const std::vector* value) {// NOLINT variant_ = std::make_shared(value); } - ConstStringListRef(std::vector value) // NOLINT - { + ConstStringListRef(std::vector value) { // NOLINT variant_ = std::make_shared(value); } - ConstStringListRef(const std::vector* value) // NOLINT - { + ConstStringListRef(const std::vector* value) { // NOLINT variant_ = std::make_shared(value); } - ConstStringListRef(const std::vector* value) // NOLINT - { + ConstStringListRef(const std::vector* value) { // NOLINT variant_ = std::make_shared(value); } - ConstStringListRef(Adapter* adapter) // NOLINT - { + ConstStringListRef(Adapter* adapter) { // NOLINT variant_ = std::make_shared(adapter); } template - ConstStringListRef(std::unique_ptr adapter) // NOLINT - { + ConstStringListRef(std::unique_ptr adapter) { // NOLINT variant_ = std::make_shared( static_cast>(std::move(adapter))); } @@ -179,66 +194,34 @@ class ConstStringListRef { return variant_ ? std::visit(SizeVisitor(), *variant_) : 0; } - std::string operator[](size_t i) const { - if (!variant_) { - return ""; - } - auto& v = *variant_; - if (std::holds_alternative>(v)) { - return std::get>(v)[i]; - } - if (std::holds_alternative*>(v)) { - return (*std::get*>(v))[i]; - } - if (std::holds_alternative>(v)) { - return std::string(std::get>(v)[i]); - } - if (std::holds_alternative*>(v)) { - return std::string( - (*std::get*>(v))[i]); - } - if (std::holds_alternative*>(v)) { - return to_string((*std::get*>(v))[i]); - } - if (std::holds_alternative(v)) { - return std::string((*std::get(v))[i]); - } - if (std::holds_alternative>(v)) { - return std::string((*std::get>(v))[i]); - } - return ""; - } - - std::string_view at(size_t i) const { - if (!variant_) { - return ""; - } - auto& v = *variant_; - if (std::holds_alternative>(v)) { - return std::get>(v)[i]; - } - if (std::holds_alternative*>(v)) { - return (*std::get*>(v))[i]; - } - if (std::holds_alternative>(v)) { - return std::get>(v)[i]; - } - if (std::holds_alternative*>(v)) { - return (*std::get*>(v))[i]; - } - if (std::holds_alternative*>(v)) { - return {}; - } - if (std::holds_alternative(v)) { - return (*std::get(v))[i]; - } - if (std::holds_alternative>(v)) { - return (*std::get>(v))[i]; - } - return {}; + std::string_view operator[](size_t i) const { + return variant_ ? std::visit(IndexedGetter{i}, *variant_) : ""; } private: + struct IndexedGetter { + size_t i; + std::string_view operator()(const std::vector& v) const { + return v[i]; + } + std::string_view operator()(const std::vector* v) const { + return (*v)[i]; + } + std::string_view operator()(const std::vector& v) const { + return std::string(v[i]); + } + std::string_view operator()(const std::vector* v) const { + return std::string((*v)[i]); + } + std::string_view operator()(const std::vector* v) const { + return to_string((*v)[i]); + } + std::string_view operator()(Adapter* v) const { return std::string((*v)[i]); } + std::string_view operator()(const std::unique_ptr& v) const { + return (*v)[i]; + } + }; + struct SizeVisitor { size_t operator()(const std::vector& v) const { return v.size(); diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp index e63076ecd..cd4d570cb 100644 --- a/src/ftxui/component/menu.cpp +++ b/src/ftxui/component/menu.cpp @@ -123,7 +123,7 @@ class MenuBase : public ComponentBase, public MenuOption { const bool is_selected = (selected() == i); const EntryState state = { - entries[i], false, is_selected, is_focused, i, + std::string(entries[i]), false, is_selected, is_focused, i, }; Element element = (entries_option.transform ? entries_option.transform diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp index 452bc972c..1c431f31b 100644 --- a/src/ftxui/component/radiobox.cpp +++ b/src/ftxui/component/radiobox.cpp @@ -37,7 +37,7 @@ class RadioboxBase : public ComponentBase, public RadioboxOption { const bool is_focused = (focused_entry() == i) && is_menu_focused; const bool is_selected = (hovered_ == i); auto state = EntryState{ - entries[i], selected() == i, is_selected, is_focused, i, + std::string(entries[i]), selected() == i, is_selected, is_focused, i, }; auto element = (transform ? transform : RadioboxOption::Simple().transform)(state);