FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
ref.hpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#ifndef FTXUI_UTIL_REF_HPP
5#define FTXUI_UTIL_REF_HPP
6
8#include <memory>
9#include <string>
10#include <string_view>
11#include <variant>
12#include <vector>
13
14namespace ftxui {
15
16/// @brief An adapter. Own or reference an immutable object.
17template <typename T>
18class ConstRef {
19 public:
20 ConstRef() = default;
21 ConstRef(T t) : variant_(std::move(t)) {} // NOLINT
22 ConstRef(const T* t) : variant_(t) {} // NOLINT
23 ConstRef& operator=(ConstRef&&) noexcept = default;
24 ConstRef(const ConstRef<T>&) = default;
25 ConstRef(ConstRef<T>&&) noexcept = default;
26 ~ConstRef() = default;
27
28 // Make a "reseatable" reference
29 ConstRef<T>& operator=(const ConstRef<T>&) = default;
30
31 // Accessors:
32 const T& operator()() const { return *Address(); }
33 const T& operator*() const { return *Address(); }
34 const T* operator->() const { return Address(); }
35
36 private:
37 std::variant<T, const T*> variant_ = T{};
38
39 const T* Address() const {
40 return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
41 : std::get<const T*>(variant_);
42 }
43};
44
45/// @brief An adapter. Own or reference an mutable object.
46template <typename T>
47class Ref {
48 public:
49 Ref() = default;
50 Ref(T t) : variant_(std::move(t)) {} // NOLINT
51 Ref(T* t) : variant_(t) {} // NOLINT
52 ~Ref() = default;
53 Ref& operator=(Ref&&) noexcept = default;
54 Ref(const Ref<T>&) = default;
55 Ref(Ref<T>&&) noexcept = default;
56
57 // Make a "reseatable" reference.
58 Ref<T>& operator=(const Ref<T>&) = default;
59
60 // Accessors:
61 T& operator()() { return *Address(); }
62 T& operator*() { return *Address(); }
63 T* operator->() { return Address(); }
64 const T& operator()() const { return *Address(); }
65 const T& operator*() const { return *Address(); }
66 const T* operator->() const { return Address(); }
67
68 private:
69 std::variant<T, T*> variant_ = T{};
70
71 const T* Address() const {
72 return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
73 : std::get<T*>(variant_);
74 }
75 T* Address() {
76 return std::holds_alternative<T>(variant_) ? &std::get<T>(variant_)
77 : std::get<T*>(variant_);
78 }
79};
80
81/// @brief An adapter. Own or reference a constant string. For convenience, this
82/// class convert multiple mutable string toward a shared representation.
83class StringRef : public Ref<std::string> {
84 public:
85 using Ref<std::string>::Ref;
86
87 StringRef(const wchar_t* ref) // NOLINT
88 : StringRef(to_string(std::wstring(ref))) {}
89 StringRef(const char* ref) // NOLINT
90 : StringRef(std::string(ref)) {}
91};
92
93/// @brief An adapter. Own or reference a constant string. For convenience, this
94/// class convert multiple immutable string toward a shared representation.
95class ConstStringRef : public ConstRef<std::string> {
96 public:
97 using ConstRef<std::string>::ConstRef;
98
99 ConstStringRef(const std::wstring* ref) // NOLINT
100 : ConstStringRef(to_string(*ref)) {}
101 ConstStringRef(const std::wstring ref) // NOLINT
102 : ConstStringRef(to_string(ref)) {}
103 ConstStringRef(const wchar_t* ref) // NOLINT
104 : ConstStringRef(to_string(std::wstring(ref))) {}
105 ConstStringRef(const char* ref) // NOLINT
106 : ConstStringRef(std::string(ref)) {}
107};
108
109/// @brief An adapter. Reference a list of strings.
110///
111/// Supported input:
112/// - `std::vector<std::string>`
113/// - `std::vector<std::string>*`
114/// - `std::vector<std::wstring>*`
115/// - `Adapter*`
116/// - `std::unique_ptr<Adapter>`
118 public:
119 // Bring your own adapter:
120 class Adapter {
121 public:
122 Adapter() = default;
123 Adapter(const Adapter&) = default;
124 Adapter& operator=(const Adapter&) = default;
125 Adapter(Adapter&&) = default;
126 Adapter& operator=(Adapter&&) = default;
127 virtual ~Adapter() = default;
128 virtual size_t size() const = 0;
129 virtual std::string_view operator[](size_t i) const = 0;
130 };
131 using Variant = std::variant<const std::vector<std::string>, //
132 const std::vector<std::string>*, //
133 const std::vector<std::string_view>, //
134 const std::vector<std::string_view>*, //
135 const std::vector<std::wstring>*, //
136 Adapter*, //
137 std::unique_ptr<Adapter> //
138 >;
139
146
147 ConstStringListRef(std::vector<std::string> value) // NOLINT
148 {
149 variant_ = std::make_shared<Variant>(value);
150 }
151 ConstStringListRef(const std::vector<std::string>* value) // NOLINT
152 {
153 variant_ = std::make_shared<Variant>(value);
154 }
155 ConstStringListRef(std::vector<std::string_view> value) // NOLINT
156 {
157 variant_ = std::make_shared<Variant>(value);
158 }
159 ConstStringListRef(const std::vector<std::string_view>* value) // NOLINT
160 {
161 variant_ = std::make_shared<Variant>(value);
162 }
163 ConstStringListRef(const std::vector<std::wstring>* value) // NOLINT
164 {
165 variant_ = std::make_shared<Variant>(value);
166 }
167 ConstStringListRef(Adapter* adapter) // NOLINT
168 {
169 variant_ = std::make_shared<Variant>(adapter);
170 }
171 template <typename AdapterType>
172 ConstStringListRef(std::unique_ptr<AdapterType> adapter) // NOLINT
173 {
174 variant_ = std::make_shared<Variant>(
175 static_cast<std::unique_ptr<Adapter>>(std::move(adapter)));
176 }
177
178 size_t size() const {
179 return variant_ ? std::visit(SizeVisitor(), *variant_) : 0;
180 }
181
182 std::string operator[](size_t i) const {
183 if (!variant_) {
184 return "";
185 }
186 auto& v = *variant_;
187 if (std::holds_alternative<const std::vector<std::string>>(v)) {
188 return std::get<const std::vector<std::string>>(v)[i];
189 }
190 if (std::holds_alternative<const std::vector<std::string>*>(v)) {
191 return (*std::get<const std::vector<std::string>*>(v))[i];
192 }
193 if (std::holds_alternative<const std::vector<std::string_view>>(v)) {
194 return std::string(std::get<const std::vector<std::string_view>>(v)[i]);
195 }
196 if (std::holds_alternative<const std::vector<std::string_view>*>(v)) {
197 return std::string(
198 (*std::get<const std::vector<std::string_view>*>(v))[i]);
199 }
200 if (std::holds_alternative<const std::vector<std::wstring>*>(v)) {
201 return to_string((*std::get<const std::vector<std::wstring>*>(v))[i]);
202 }
203 if (std::holds_alternative<Adapter*>(v)) {
204 return std::string((*std::get<Adapter*>(v))[i]);
205 }
206 if (std::holds_alternative<std::unique_ptr<Adapter>>(v)) {
207 return std::string((*std::get<std::unique_ptr<Adapter>>(v))[i]);
208 }
209 return "";
210 }
211
212 std::string_view at(size_t i) const {
213 if (!variant_) {
214 return "";
215 }
216 auto& v = *variant_;
217 if (std::holds_alternative<const std::vector<std::string>>(v)) {
218 return std::get<const std::vector<std::string>>(v)[i];
219 }
220 if (std::holds_alternative<const std::vector<std::string>*>(v)) {
221 return (*std::get<const std::vector<std::string>*>(v))[i];
222 }
223 if (std::holds_alternative<const std::vector<std::string_view>>(v)) {
224 return std::get<const std::vector<std::string_view>>(v)[i];
225 }
226 if (std::holds_alternative<const std::vector<std::string_view>*>(v)) {
227 return (*std::get<const std::vector<std::string_view>*>(v))[i];
228 }
229 if (std::holds_alternative<const std::vector<std::wstring>*>(v)) {
230 return {};
231 }
232 if (std::holds_alternative<Adapter*>(v)) {
233 return (*std::get<Adapter*>(v))[i];
234 }
235 if (std::holds_alternative<std::unique_ptr<Adapter>>(v)) {
236 return (*std::get<std::unique_ptr<Adapter>>(v))[i];
237 }
238 return {};
239 }
240
241 private:
242 struct SizeVisitor {
243 size_t operator()(const std::vector<std::string>& v) const {
244 return v.size();
245 }
246 size_t operator()(const std::vector<std::string>* v) const {
247 return v->size();
248 }
249 size_t operator()(const std::vector<std::string_view>& v) const {
250 return v.size();
251 }
252 size_t operator()(const std::vector<std::string_view>* v) const {
253 return v->size();
254 }
255 size_t operator()(const std::vector<std::wstring>* v) const {
256 return v->size();
257 }
258 size_t operator()(const Adapter* v) const { return v->size(); }
259 size_t operator()(const std::unique_ptr<Adapter>& v) const {
260 return v->size();
261 }
262 };
263
264 std::shared_ptr<Variant> variant_;
265};
266
267} // namespace ftxui
268
269#endif /* end of include guard: FTXUI_UTIL_REF_HPP */
An adapter. Own or reference an immutable object.
Definition ref.hpp:18
const T & operator*() const
Definition ref.hpp:33
ConstRef()=default
ConstRef(const T *t)
Definition ref.hpp:22
ConstRef(T t)
Definition ref.hpp:21
const T * operator->() const
Definition ref.hpp:34
ConstRef & operator=(ConstRef &&) noexcept=default
Adapter & operator=(Adapter &&)=default
virtual std::string_view operator[](size_t i) const =0
Adapter & operator=(const Adapter &)=default
virtual size_t size() const =0
Adapter(const Adapter &)=default
An adapter. Reference a list of strings.
Definition ref.hpp:117
ConstStringListRef(const std::vector< std::string_view > *value)
Definition ref.hpp:159
ConstStringListRef(std::vector< std::string > value)
Definition ref.hpp:147
ConstStringListRef(const std::vector< std::string > *value)
Definition ref.hpp:151
size_t size() const
Definition ref.hpp:178
ConstStringListRef(ConstStringListRef &&)=default
ConstStringListRef & operator=(ConstStringListRef &&)=default
ConstStringListRef & operator=(const ConstStringListRef &)=default
ConstStringListRef(std::vector< std::string_view > value)
Definition ref.hpp:155
std::variant< const std::vector< std::string >, const std::vector< std::string > *, const std::vector< std::string_view >, const std::vector< std::string_view > *, const std::vector< std::wstring > *, Adapter *, std::unique_ptr< Adapter > > Variant
Definition ref.hpp:131
std::string_view at(size_t i) const
Definition ref.hpp:212
ConstStringListRef(std::unique_ptr< AdapterType > adapter)
Definition ref.hpp:172
ConstStringListRef(const std::vector< std::wstring > *value)
Definition ref.hpp:163
ConstStringListRef(const ConstStringListRef &)=default
ConstStringListRef(Adapter *adapter)
Definition ref.hpp:167
std::string operator[](size_t i) const
Definition ref.hpp:182
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition ref.hpp:95
ConstStringRef(const char *ref)
Definition ref.hpp:105
ConstStringRef(const std::wstring ref)
Definition ref.hpp:101
ConstStringRef(const std::wstring *ref)
Definition ref.hpp:99
ConstStringRef(const wchar_t *ref)
Definition ref.hpp:103
An adapter. Own or reference an mutable object.
Definition ref.hpp:47
const T & operator*() const
Definition ref.hpp:65
~Ref()=default
T & operator*()
Definition ref.hpp:62
T * operator->()
Definition ref.hpp:63
Ref()=default
Ref(T t)
Definition ref.hpp:50
const T * operator->() const
Definition ref.hpp:66
Ref & operator=(Ref &&) noexcept=default
Ref(T *t)
Definition ref.hpp:51
const T & operator()() const
Definition ref.hpp:64
An adapter. Own or reference a constant string. For convenience, this class convert multiple mutable ...
Definition ref.hpp:83
StringRef(const char *ref)
Definition ref.hpp:89
StringRef(const wchar_t *ref)
Definition ref.hpp:87
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
std::string to_string(std::wstring_view s)
Convert a std::wstring into a UTF8 std::string.
Definition string.cpp:1565