FINAL CUT
fvtermbuffer.h
1 /***********************************************************************
2 * fvtermbuffer.h - Buffer for virtual terminal strings *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2017-2024 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Standalone class
24  * ════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
27  * ▕ FVTermBuffer ▏
28  * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
29  */
30 
31 #ifndef FVTERMBUFFER_H
32 #define FVTERMBUFFER_H
33 
34 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
35  #error "Only <final/final.h> can be included directly."
36 #endif
37 
38 #include <algorithm>
39 #include <string>
40 #include <utility>
41 #include <vector>
42 
43 #include "final/util/fstringstream.h"
44 
45 namespace finalcut
46 {
47 
48 // class forward declaration
49 class FStyle;
50 class FColorPair;
51 
52 //----------------------------------------------------------------------
53 // class FVTermBuffer
54 //----------------------------------------------------------------------
55 
57 {
58  public:
59  // Using-declarations
60  using FCharVector = std::vector<FChar>;
61  using iterator = FCharVector::iterator;
62  using const_iterator = FCharVector::const_iterator;
63  using reference = FCharVector::reference;
64  using const_reference = FCharVector::const_reference;
65  using difference_type = FCharVector::difference_type;
66 
67  // Constructor
68  FVTermBuffer();
69 
70  template <typename Iterator>
71  FVTermBuffer (Iterator, Iterator);
72 
73  // Overloaded operators
74  auto operator [] (std::size_t) -> reference;
75  auto operator [] (const std::size_t) const -> const_reference;
76 
77  template <typename NumT
78  , enable_if_arithmetic_without_char_t<NumT> = nullptr>
79  auto operator << (const NumT&) -> FVTermBuffer&;
80 
81  template <typename CharT
82  , enable_if_CString_t<CharT> = nullptr>
83  auto operator << (const CharT&) -> FVTermBuffer&;
84  auto operator << (char) -> FVTermBuffer&;
85  auto operator << (wchar_t) -> FVTermBuffer&;
86  auto operator << (const wchar_t*) -> FVTermBuffer&;
87  auto operator << (const UniChar&) -> FVTermBuffer&;
88  auto operator << (const std::string&) -> FVTermBuffer&;
89  auto operator << (const std::wstring&) -> FVTermBuffer&;
90  auto operator << (const FString&) -> FVTermBuffer&;
91  auto operator << (FChar&) -> FVTermBuffer&;
92  auto operator << (const FCharVector&) -> FVTermBuffer&;
93  auto operator << (const FStyle&) -> FVTermBuffer&;
94  auto operator << (const FColorPair&) -> FVTermBuffer&;
95 
96  // Accessors
97  auto getClassName() const -> FString;
98  auto getLength() const -> std::size_t;
99  auto getBuffer() const -> const FCharVector&;
100 
101  // Inquiry
102  auto isEmpty() const -> bool;
103 
104  // Methods
105  auto begin() -> iterator;
106  auto end() -> iterator;
107  auto begin() const -> const_iterator;
108  auto end() const -> const_iterator;
109  auto front() -> reference;
110  auto back() -> reference;
111  auto front() const -> const_reference;
112  auto back() const -> const_reference;
113  auto toString() const -> FString;
114  template <typename Iterator>
115  void assign (Iterator, Iterator);
116  void clear();
117  template <typename... Args>
118  auto printf (const FString&, Args&&...) -> int;
119  auto print (const FString&) -> int;
120  auto print (wchar_t) -> int;
121  void print (const FStyle&) const;
122  void print (const FColorPair&) const;
123  auto print () -> FVTermBuffer&;
124 
125  private:
126  struct UnicodeBoundary
127  {
128  FString::const_iterator cbegin{};
129  FString::const_iterator cend{};
130  FString::const_iterator iter{};
131  std::size_t char_width{0};
132  };
133 
134  void getNextCharacterAttribute();
135  void add (UnicodeBoundary&);
136 
137  // Data member
138  FCharVector data{};
139  FChar nc{}; // next character
140 
141  // Non-member operators
142  friend auto operator << ( FVTermBuffer::FCharVector& term_string
143  , const FVTermBuffer& buf ) -> FVTermBuffer::FCharVector&
144  {
145  if ( ! buf.data.empty() )
146  term_string.assign(buf.data.cbegin(), buf.data.cend());
147 
148  return term_string;
149  }
150 };
151 
152 // non-member function forward declarations
153 template<typename T>
154 constexpr void checkCapacity (T&, std::size_t) noexcept;
155 
156 // FVTermBuffer inline functions
157 //----------------------------------------------------------------------
158 template <typename Iterator>
159 inline FVTermBuffer::FVTermBuffer (Iterator first, Iterator last)
160 {
161  assign(first, last);
162 }
163 
164 //----------------------------------------------------------------------
165 inline auto FVTermBuffer::operator [] (std::size_t index) -> reference
166 {
167  return data[index];
168 }
169 
170 //----------------------------------------------------------------------
171 inline auto FVTermBuffer::operator [] (const std::size_t index) const -> const_reference
172 {
173  return data[index];
174 }
175 
176 //----------------------------------------------------------------------
177 template <typename NumT
178  , enable_if_arithmetic_without_char_t<NumT>>
179 inline auto FVTermBuffer::operator << (const NumT& n) -> FVTermBuffer&
180 {
181  print (FString(std::to_string(n)));
182  return *this;
183 }
184 
185 //----------------------------------------------------------------------
186 template <typename CharT
187  , enable_if_CString_t<CharT>>
188 inline auto FVTermBuffer::operator << (const CharT& s) -> FVTermBuffer&
189 {
190  print (FString(s));
191  return *this;
192 }
193 
194 //----------------------------------------------------------------------
195 inline auto FVTermBuffer::operator << (char c) -> FVTermBuffer&
196 {
197  print (wchar_t(uChar(c)));
198  return *this;
199 }
200 
201 //----------------------------------------------------------------------
202 inline auto FVTermBuffer::operator << (wchar_t c) -> FVTermBuffer&
203 {
204  print (c);
205  return *this;
206 }
207 
208 //----------------------------------------------------------------------
209 inline auto FVTermBuffer::operator << (const wchar_t* wide_string) -> FVTermBuffer&
210 {
211  print (FString(wide_string));
212  return *this;
213 }
214 
215 //----------------------------------------------------------------------
216 inline auto FVTermBuffer::operator << (const UniChar& c) -> FVTermBuffer&
217 {
218  print (static_cast<wchar_t>(c));
219  return *this;
220 }
221 
222 //----------------------------------------------------------------------
223 inline auto FVTermBuffer::operator << (const std::string& string) -> FVTermBuffer&
224 {
225  print (FString(string));
226  return *this;
227 }
228 
229 //----------------------------------------------------------------------
230 inline auto FVTermBuffer::operator << (const std::wstring& wstring) -> FVTermBuffer&
231 {
232  print (FString(wstring));
233  return *this;
234 }
235 
236 //----------------------------------------------------------------------
237 inline auto FVTermBuffer::operator << (const FString& fstring) -> FVTermBuffer&
238 {
239  print (fstring);
240  return *this;
241 }
242 
243 //----------------------------------------------------------------------
244 inline auto FVTermBuffer::operator << (FChar& fchar) -> FVTermBuffer&
245 {
246  data.emplace_back(fchar);
247  return *this;
248 }
249 
250 //----------------------------------------------------------------------
251 inline auto FVTermBuffer::operator << (const FCharVector& vec) -> FVTermBuffer&
252 {
253  std::copy(vec.cbegin(), vec.cend(), std::back_inserter(data));
254  return *this;
255 }
256 
257 //----------------------------------------------------------------------
258 inline auto FVTermBuffer::operator << (const FStyle& style) -> FVTermBuffer&
259 {
260  print (style);
261  return *this;
262 }
263 
264 //----------------------------------------------------------------------
265 inline auto FVTermBuffer::operator << (const FColorPair& pair) -> FVTermBuffer&
266 {
267  print (pair);
268  return *this;
269 }
270 
271 //----------------------------------------------------------------------
272 inline auto FVTermBuffer::getClassName() const -> FString
273 { return "FVTermBuffer"; }
274 
275 //----------------------------------------------------------------------
276 inline auto FVTermBuffer::getLength() const -> std::size_t
277 { return data.size(); }
278 
279 //----------------------------------------------------------------------
280 inline auto FVTermBuffer::getBuffer() const -> const FCharVector&
281 { return data; }
282 
283 //----------------------------------------------------------------------
284 inline auto FVTermBuffer::isEmpty() const -> bool
285 { return data.empty(); }
286 
287 //----------------------------------------------------------------------
288 inline auto FVTermBuffer::begin() -> iterator
289 { return data.begin(); }
290 
291 //----------------------------------------------------------------------
292 inline auto FVTermBuffer::end() -> iterator
293 { return data.end(); }
294 
295 //----------------------------------------------------------------------
296 inline auto FVTermBuffer::begin() const -> const_iterator
297 { return data.begin(); }
298 
299 //----------------------------------------------------------------------
300 inline auto FVTermBuffer::end() const -> const_iterator
301 { return data.end(); }
302 
303 //----------------------------------------------------------------------
304 inline auto FVTermBuffer::front() -> reference
305 { return data.front(); }
306 
307 //----------------------------------------------------------------------
308 inline auto FVTermBuffer::back() -> reference
309 { return data.back(); }
310 
311 //----------------------------------------------------------------------
312 inline auto FVTermBuffer::front() const -> const_reference
313 { return data.front(); }
314 
315 //----------------------------------------------------------------------
316 inline auto FVTermBuffer::back() const -> const_reference
317 { return data.back(); }
318 
319 //----------------------------------------------------------------------
320 template <typename Iterator>
321 inline void FVTermBuffer::assign (Iterator first, Iterator last)
322 {
323  if ( first >= last )
324  return;
325 
326  checkCapacity (data, std::size_t(last - first));
327  data.assign(first, last);
328 }
329 
330 //----------------------------------------------------------------------
331 inline void FVTermBuffer::clear()
332 {
333  data.clear();
334 }
335 
336 //----------------------------------------------------------------------
337 template <typename... Args>
338 inline auto FVTermBuffer::printf (const FString& format, Args&&... args) -> int
339 {
340  FString str{};
341  str.sprintf (format, std::forward<Args>(args)...);
342  return print(str);
343 }
344 
345 //----------------------------------------------------------------------
346 inline auto FVTermBuffer::print() -> FVTermBuffer&
347 { return *this; }
348 
349 //----------------------------------------------------------------------
350 template<typename T>
351 constexpr void checkCapacity (T& buffer, std::size_t size) noexcept
352 {
353  if ( size <= buffer.capacity() )
354  return;
355 
356  const auto new_size = [&size] ()
357  {
358  return std::size_t(std::pow(2, std::ceil(std::log(size) / std::log(2.0))));
359  }();
360 
361  buffer.reserve(new_size);
362 }
363 
364 } // namespace finalcut
365 
366 #endif // FVTERMBUFFER_H
Definition: fvtermbuffer.h:56
Definition: class_template.cpp:25
Definition: ftypes.h:423
Definition: fstring.h:79
Definition: fstyle.h:49
Definition: fcolorpair.h:49