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
14#include "ftxui/util/export.hpp"
15
16namespace ftxui {
17
18/// @brief An adapter. Own or reference an immutable object.
19template <typename T>
20class ConstRef {
21 public:
22 ConstRef() = default;
23
24 // Owning constructors:
25 ConstRef(T t) : variant_(std::move(t)) {} // NOLINT
26
27 // Referencing constructors:
28 ConstRef(const T* t) : variant_(t) {} // NOLINT
29
30 ConstRef& operator=(ConstRef&&) noexcept = default;
31 ConstRef(const ConstRef<T>&) = default;
32 ConstRef(ConstRef<T>&&) noexcept = default;
33 ~ConstRef() = default;
34
35 // Make a "reseatable" reference
36 ConstRef<T>& operator=(const ConstRef<T>&) = default;
37
38 // Accessors:
39 const T& operator()() const { return *Address(); }
40 const T& operator*() const { return *Address(); }
41 const T* operator->() const { return Address(); }
42
43 private:
44 std::variant<T, const T*> variant_ = T{};
45
46 const T* Address() const {
47 if (const T* t = std::get_if<T>(&variant_)) {
48 return t;
49 }
50 return std::get<const T*>(variant_);
51 }
52};
53
54/// @brief An adapter. Own or reference an mutable object.
55template <typename T>
56class Ref {
57 public:
58 Ref() = default;
59
60 // Owning constructors:
61 Ref(T t)
62 : variant_(std::move(t)) {} // NOLINT
63 //
64 // Referencing constructors:
65 Ref(T* t)
66 : variant_(t) {} // NOLINT
67 //
68 ~Ref() = default;
69 Ref& operator=(Ref&&) noexcept = default;
70 Ref(const Ref<T>&) = default;
71 Ref(Ref<T>&&) noexcept = default;
72
73 // Make a "reseatable" reference.
74 Ref<T>& operator=(const Ref<T>&) = default;
75
76 // Accessors:
77 T& operator()() { return *Address(); }
78 T& operator*() { return *Address(); }
79 T* operator->() { return Address(); }
80 const T& operator()() const { return *Address(); }
81 const T& operator*() const { return *Address(); }
82 const T* operator->() const { return Address(); }
83
84 private:
85 std::variant<T, T*> variant_ = T{};
86
87 const T* Address() const {
88 if (const T* t = std::get_if<T>(&variant_)) {
89 return t;
90 }
91 return std::get<T*>(variant_);
92 }
93 T* Address() {
94 if (T* t = std::get_if<T>(&variant_)) {
95 return t;
96 }
97 return std::get<T*>(variant_);
98 }
99};
100
101/// @brief An adapter. Own or reference a constant string. For convenience, this
102/// class convert multiple mutable string toward a shared representation.
103class FTXUI_EXPORT(SCREEN) StringRef : public Ref<std::string> {
104 public:
105 using Ref<std::string>::Ref;
106
107 // Owning constructors:
108 StringRef(const wchar_t* ref) // NOLINT
109 : StringRef(to_string(std::wstring(ref))) {}
110 StringRef(const char* ref) // NOLINT
111 : StringRef(std::string(ref)) {}
112 StringRef(std::string_view ref) // NOLINT
113 : StringRef(std::string(ref)) {}
114 StringRef(std::wstring_view ref) // NOLINT
115 : StringRef(to_string(ref)) {}
116};
117
118/// @brief An adapter. Own or reference a constant string. For convenience, this
119/// class convert multiple immutable string toward a shared representation.
120class FTXUI_EXPORT(SCREEN) ConstStringRef : public ConstRef<std::string> {
121 public:
122 using ConstRef<std::string>::ConstRef;
123
124 // Referencing constructors:
125 ConstStringRef(const std::wstring* ref) // NOLINT
126 : ConstStringRef(to_string(*ref)) {}
127
128 // Owning constructors:
129 ConstStringRef(const std::wstring ref) // NOLINT
130 : ConstStringRef(to_string(ref)) {}
131 ConstStringRef(std::wstring_view ref) // NOLINT
132 : ConstStringRef(to_string(ref)) {}
133 ConstStringRef(const wchar_t* ref) // NOLINT
134 : ConstStringRef(to_string(std::wstring(ref))) {}
135 ConstStringRef(const char* ref) // NOLINT
136 : ConstStringRef(std::string(ref)) {}
137 ConstStringRef(std::string_view ref) // NOLINT
138 : ConstStringRef(std::string(ref)) {}
139};
140
141/// @brief An adapter. Reference a list of strings.
142///
143/// Supported input:
144/// - `std::vector<std::string>`
145/// - `std::vector<std::string>*`
146/// - `std::vector<std::wstring>*`
147/// - `Adapter*`
148/// - `std::unique_ptr<Adapter>`
149class FTXUI_EXPORT(SCREEN) ConstStringListRef {
150 public:
151 // Bring your own adapter:
152 class Adapter {
153 public:
154 Adapter() = default;
155 Adapter(const Adapter&) = default;
156 Adapter& operator=(const Adapter&) = default;
157 Adapter(Adapter&&) = default;
158 Adapter& operator=(Adapter&&) = default;
159 virtual ~Adapter() = default;
160 virtual size_t size() const = 0;
161 virtual std::string_view operator[](size_t i) const = 0;
162 };
163 using Variant = std::variant<const std::vector<std::string>, //
164 const std::vector<std::string>*, //
165 const std::vector<std::string_view>, //
166 const std::vector<std::string_view>*, //
167 const std::vector<std::wstring>*, //
168 Adapter*, //
169 std::unique_ptr<Adapter> //
170 >;
171
172 ConstStringListRef() = default;
173 ~ConstStringListRef() = default;
174 ConstStringListRef& operator=(const ConstStringListRef&) = default;
175 ConstStringListRef& operator=(ConstStringListRef&&) = default;
176 ConstStringListRef(ConstStringListRef&&) = default;
177 ConstStringListRef(const ConstStringListRef&) = default;
178
179 ConstStringListRef(std::vector<std::string> value) { // NOLINT
180 variant_ = std::make_shared<Variant>(value);
181 }
182 ConstStringListRef(const std::vector<std::string>* value) { // NOLINT
183 variant_ = std::make_shared<Variant>(value);
184 }
185 ConstStringListRef(std::vector<std::string_view> value) { // NOLINT
186 variant_ = std::make_shared<Variant>(value);
187 }
188 ConstStringListRef(const std::vector<std::string_view>* value) { // NOLINT
189 variant_ = std::make_shared<Variant>(value);
190 }
191 ConstStringListRef(const std::vector<std::wstring>* value) { // NOLINT
192 variant_ = std::make_shared<Variant>(value);
193 }
194 ConstStringListRef(Adapter* adapter) { // NOLINT
195 variant_ = std::make_shared<Variant>(adapter);
196 }
197 template <typename AdapterType>
198 ConstStringListRef(std::unique_ptr<AdapterType> adapter) { // NOLINT
199 variant_ = std::make_shared<Variant>(
200 static_cast<std::unique_ptr<Adapter>>(std::move(adapter)));
201 }
202
203 size_t size() const {
204 return variant_ ? std::visit(SizeVisitor(), *variant_) : 0;
205 }
206
207 std::string_view operator[](size_t i) const {
208 return variant_ ? std::visit(IndexedGetter{i}, *variant_) : "";
209 }
210
211 private:
212 struct IndexedGetter {
213 size_t i;
214 std::string_view operator()(const std::vector<std::string>& v) const {
215 return v[i];
216 }
217 std::string_view operator()(const std::vector<std::string>* v) const {
218 return (*v)[i];
219 }
220 std::string_view operator()(const std::vector<std::string_view>& v) const {
221 return v[i];
222 }
223 std::string_view operator()(const std::vector<std::string_view>* v) const {
224 return (*v)[i];
225 }
226 std::string_view operator()(
227 [[maybe_unused]] const std::vector<std::wstring>* v) const {
228 return ""; // Temporary fix: Cannot return a view to a temporary
229 // conversion.
230 }
231 std::string_view operator()(Adapter* v) const { return (*v)[i]; }
232 std::string_view operator()(const std::unique_ptr<Adapter>& v) const {
233 return (*v)[i];
234 }
235 };
236
237 struct SizeVisitor {
238 size_t operator()(const std::vector<std::string>& v) const {
239 return v.size();
240 }
241 size_t operator()(const std::vector<std::string>* v) const {
242 return v->size();
243 }
244 size_t operator()(const std::vector<std::string_view>& v) const {
245 return v.size();
246 }
247 size_t operator()(const std::vector<std::string_view>* v) const {
248 return v->size();
249 }
250 size_t operator()(const std::vector<std::wstring>* v) const {
251 return v->size();
252 }
253 size_t operator()(const Adapter* v) const { return v->size(); }
254 size_t operator()(const std::unique_ptr<Adapter>& v) const {
255 return v->size();
256 }
257 };
258
259 std::shared_ptr<Variant> variant_;
260};
261
262} // namespace ftxui
263
264#endif /* end of include guard: FTXUI_UTIL_REF_HPP */
An adapter. Own or reference an immutable object.
Definition ref.hpp:20
const T & operator*() const
Definition ref.hpp:40
ConstRef()=default
ConstRef(const T *t)
Definition ref.hpp:28
ConstRef(T t)
Definition ref.hpp:25
const T * operator->() const
Definition ref.hpp:41
ConstRef & operator=(ConstRef &&) noexcept=default
An adapter. Own or reference an mutable object.
Definition ref.hpp:56
const T & operator*() const
Definition ref.hpp:81
~Ref()=default
T & operator*()
Definition ref.hpp:78
T * operator->()
Definition ref.hpp:79
Ref()=default
Ref(T t)
Definition ref.hpp:61
const T * operator->() const
Definition ref.hpp:82
Ref & operator=(Ref &&) noexcept=default
Ref(T *t)
Definition ref.hpp:65
const T & operator()() const
Definition ref.hpp:80
The FTXUI ftxui:: namespace.
Definition animation.hpp:11