FTXUI 7.0.3
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 一個適配器。擁有或引用一個不可變的物件。
19template <typename T>
20class ConstRef {
21 public:
22 ConstRef() = default;
23
24 // 擁有型建構子:
25 ConstRef(T t) : variant_(std::move(t)) {} // NOLINT
26
27 // 參照型建構子:
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 // 建立一個「可重新設定」的參照
36 ConstRef<T>& operator=(const ConstRef<T>&) = default;
37
38 // 存取器:
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 一個適配器。擁有或引用一個可變的物件。
55template <typename T>
56class Ref {
57 public:
58 Ref() = default;
59
60 // 擁有型建構子:
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 // 建立一個「可重新設定」的參照。
74 Ref<T>& operator=(const Ref<T>&) = default;
75
76 // 存取器:
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 一個適配器。擁有或引用一個常數字串。為方便起見,此類別將多個可變字串轉換為共享表示。
102class FTXUI_EXPORT(SCREEN) StringRef : public Ref<std::string> {
103 public:
104 using Ref<std::string>::Ref;
105
106 // 擁有型建構子:
107 StringRef(const wchar_t* ref) // NOLINT
108 : StringRef(to_string(std::wstring(ref))) {}
109 StringRef(const char* ref) // NOLINT
110 : StringRef(std::string(ref)) {}
111 StringRef(std::string_view ref) // NOLINT
112 : StringRef(std::string(ref)) {}
113 StringRef(std::wstring_view ref) // NOLINT
114 : StringRef(to_string(ref)) {}
115};
116
117/// @brief 一個適配器。擁有或引用一個常數字串。為方便起見,此類別將多個不可變字串轉換為共享表示。
118class FTXUI_EXPORT(SCREEN) ConstStringRef : public ConstRef<std::string> {
119 public:
120 using ConstRef<std::string>::ConstRef;
121
122 // 參照型建構子:
123 ConstStringRef(const std::wstring* ref) // NOLINT
124 : ConstStringRef(to_string(*ref)) {}
125
126 // 擁有型建構子:
127 ConstStringRef(const std::wstring ref) // NOLINT
128 : ConstStringRef(to_string(ref)) {}
129 ConstStringRef(std::wstring_view ref) // NOLINT
130 : ConstStringRef(to_string(ref)) {}
131 ConstStringRef(const wchar_t* ref) // NOLINT
132 : ConstStringRef(to_string(std::wstring(ref))) {}
133 ConstStringRef(const char* ref) // NOLINT
134 : ConstStringRef(std::string(ref)) {}
135 ConstStringRef(std::string_view ref) // NOLINT
136 : ConstStringRef(std::string(ref)) {}
137};
138
139/// @brief 一個適配器。引用一個字串列表。
140///
141/// 支援的輸入:
142/// - `std::vector<std::string>`
143/// - `std::vector<std::string>*`
144/// - `std::vector<std::wstring>*`
145/// - `Adapter*`
146/// - `std::unique_ptr<Adapter>`
147class FTXUI_EXPORT(SCREEN) ConstStringListRef {
148 public:
149 // 自帶配接器:
150 class Adapter {
151 public:
152 Adapter() = default;
153 Adapter(const Adapter&) = default;
154 Adapter& operator=(const Adapter&) = default;
155 Adapter(Adapter&&) = default;
156 Adapter& operator=(Adapter&&) = default;
157 virtual ~Adapter() = default;
158 virtual size_t size() const = 0;
159 virtual std::string_view operator[](size_t i) const = 0;
160 };
161 using Variant = std::variant<const std::vector<std::string>, //
162 const std::vector<std::string>*, //
163 const std::vector<std::string_view>, //
164 const std::vector<std::string_view>*, //
165 const std::vector<std::wstring>*, //
166 Adapter*, //
167 std::unique_ptr<Adapter> //
168 >;
169
170 ConstStringListRef() = default;
171 ~ConstStringListRef() = default;
172 ConstStringListRef& operator=(const ConstStringListRef&) = default;
173 ConstStringListRef& operator=(ConstStringListRef&&) = default;
174 ConstStringListRef(ConstStringListRef&&) = default;
175 ConstStringListRef(const ConstStringListRef&) = default;
176
177 ConstStringListRef(std::vector<std::string> value) { // NOLINT
178 variant_ = std::make_shared<Variant>(value);
179 }
180 ConstStringListRef(const std::vector<std::string>* value) { // NOLINT
181 variant_ = std::make_shared<Variant>(value);
182 }
183 ConstStringListRef(std::vector<std::string_view> value) { // NOLINT
184 variant_ = std::make_shared<Variant>(value);
185 }
186 ConstStringListRef(const std::vector<std::string_view>* value) { // NOLINT
187 variant_ = std::make_shared<Variant>(value);
188 }
189 ConstStringListRef(const std::vector<std::wstring>* value) { // NOLINT
190 variant_ = std::make_shared<Variant>(value);
191 }
192 ConstStringListRef(Adapter* adapter) { // NOLINT
193 variant_ = std::make_shared<Variant>(adapter);
194 }
195 template <typename AdapterType>
196 ConstStringListRef(std::unique_ptr<AdapterType> adapter) { // NOLINT
197 variant_ = std::make_shared<Variant>(
198 static_cast<std::unique_ptr<Adapter>>(std::move(adapter)));
199 }
200
201 size_t size() const {
202 return variant_ ? std::visit(SizeVisitor(), *variant_) : 0;
203 }
204
205 std::string_view operator[](size_t i) const {
206 return variant_ ? std::visit(IndexedGetter{i}, *variant_) : "";
207 }
208
209 private:
210 struct IndexedGetter {
211 size_t i;
212 std::string_view operator()(const std::vector<std::string>& v) const {
213 return v[i];
214 }
215 std::string_view operator()(const std::vector<std::string>* v) const {
216 return (*v)[i];
217 }
218 std::string_view operator()(const std::vector<std::string_view>& v) const {
219 return v[i];
220 }
221 std::string_view operator()(const std::vector<std::string_view>* v) const {
222 return (*v)[i];
223 }
224 std::string_view operator()(
225 [[maybe_unused]] const std::vector<std::wstring>* v) const {
226 return ""; // 暫時的修正方案:無法回傳指向臨時物件的
227 // view。
228 }
229 std::string_view operator()(Adapter* v) const { return (*v)[i]; }
230 std::string_view operator()(const std::unique_ptr<Adapter>& v) const {
231 return (*v)[i];
232 }
233 };
234
235 struct SizeVisitor {
236 size_t operator()(const std::vector<std::string>& v) const {
237 return v.size();
238 }
239 size_t operator()(const std::vector<std::string>* v) const {
240 return v->size();
241 }
242 size_t operator()(const std::vector<std::string_view>& v) const {
243 return v.size();
244 }
245 size_t operator()(const std::vector<std::string_view>* v) const {
246 return v->size();
247 }
248 size_t operator()(const std::vector<std::wstring>* v) const {
249 return v->size();
250 }
251 size_t operator()(const Adapter* v) const { return v->size(); }
252 size_t operator()(const std::unique_ptr<Adapter>& v) const {
253 return v->size();
254 }
255 };
256
257 std::shared_ptr<Variant> variant_;
258};
259
260} // namespace ftxui
261
262#endif /* end of include guard: FTXUI_UTIL_REF_HPP */
一個適配器。擁有或引用一個不可變的物件。
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
一個適配器。擁有或引用一個可變的物件。
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
FTXUI ftxui:: 命名空間
Definition animation.hpp:11