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-2026 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 noexcept -> std::size_t;
99  auto getBuffer() const noexcept -> const FCharVector&;
100 
101  // Predicate
102  auto isEmpty() const noexcept -> bool;
103 
104  // Methods
105  auto begin() noexcept -> iterator;
106  auto end() noexcept -> iterator;
107  auto begin() const noexcept -> const_iterator;
108  auto end() const noexcept -> 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() noexcept;
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 noexcept;
123  auto print () noexcept -> 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 setAttribute (FChar&) const noexcept;
135  void add (UnicodeBoundary&);
136 
137  // Data member
138  FCharVector data{};
139 
140  // Non-member operators
141  friend auto operator << ( FVTermBuffer::FCharVector& term_string
142  , const FVTermBuffer& buf ) -> FVTermBuffer::FCharVector&
143  {
144  if ( ! buf.data.empty() )
145  term_string.assign(buf.data.cbegin(), buf.data.cend());
146 
147  return term_string;
148  }
149 };
150 
151 // non-member function forward declarations
152 template<typename T>
153 constexpr void checkCapacity (T&, std::size_t) noexcept;
154 
155 // FVTermBuffer inline functions
156 //----------------------------------------------------------------------
157 template <typename Iterator>
158 inline FVTermBuffer::FVTermBuffer (Iterator first, Iterator last)
159 {
160  assign(first, last);
161 }
162 
163 //----------------------------------------------------------------------
164 inline auto FVTermBuffer::operator [] (std::size_t index) -> reference
165 {
166  return data[index];
167 }
168 
169 //----------------------------------------------------------------------
170 inline auto FVTermBuffer::operator [] (const std::size_t index) const -> const_reference
171 {
172  return data[index];
173 }
174 
175 //----------------------------------------------------------------------
176 template <typename NumT
177  , enable_if_arithmetic_without_char_t<NumT>>
178 inline auto FVTermBuffer::operator << (const NumT& n) -> FVTermBuffer&
179 {
180  print (FString(std::to_string(n)));
181  return *this;
182 }
183 
184 //----------------------------------------------------------------------
185 template <typename CharT
186  , enable_if_CString_t<CharT>>
187 inline auto FVTermBuffer::operator << (const CharT& s) -> FVTermBuffer&
188 {
189  print (FString(s));
190  return *this;
191 }
192 
193 //----------------------------------------------------------------------
194 inline auto FVTermBuffer::operator << (char c) -> FVTermBuffer&
195 {
196  print (wchar_t(uChar(c)));
197  return *this;
198 }
199 
200 //----------------------------------------------------------------------
201 inline auto FVTermBuffer::operator << (wchar_t c) -> FVTermBuffer&
202 {
203  print (c);
204  return *this;
205 }
206 
207 //----------------------------------------------------------------------
208 inline auto FVTermBuffer::operator << (const wchar_t* wide_string) -> FVTermBuffer&
209 {
210  print (FString(wide_string));
211  return *this;
212 }
213 
214 //----------------------------------------------------------------------
215 inline auto FVTermBuffer::operator << (const UniChar& c) -> FVTermBuffer&
216 {
217  print (static_cast<wchar_t>(c));
218  return *this;
219 }
220 
221 //----------------------------------------------------------------------
222 inline auto FVTermBuffer::operator << (const std::string& string) -> FVTermBuffer&
223 {
224  print (FString(string));
225  return *this;
226 }
227 
228 //----------------------------------------------------------------------
229 inline auto FVTermBuffer::operator << (const std::wstring& wstring) -> FVTermBuffer&
230 {
231  print (FString(wstring));
232  return *this;
233 }
234 
235 //----------------------------------------------------------------------
236 inline auto FVTermBuffer::operator << (const FString& fstring) -> FVTermBuffer&
237 {
238  print (fstring);
239  return *this;
240 }
241 
242 //----------------------------------------------------------------------
243 inline auto FVTermBuffer::operator << (FChar& fchar) -> FVTermBuffer&
244 {
245  data.emplace_back(fchar);
246  return *this;
247 }
248 
249 //----------------------------------------------------------------------
250 inline auto FVTermBuffer::operator << (const FCharVector& vec) -> FVTermBuffer&
251 {
252  std::copy(vec.cbegin(), vec.cend(), std::back_inserter(data));
253  return *this;
254 }
255 
256 //----------------------------------------------------------------------
257 inline auto FVTermBuffer::operator << (const FStyle& style) -> FVTermBuffer&
258 {
259  print (style);
260  return *this;
261 }
262 
263 //----------------------------------------------------------------------
264 inline auto FVTermBuffer::operator << (const FColorPair& pair) -> FVTermBuffer&
265 {
266  print (pair);
267  return *this;
268 }
269 
270 //----------------------------------------------------------------------
271 inline auto FVTermBuffer::getClassName() const -> FString
272 { return "FVTermBuffer"; }
273 
274 //----------------------------------------------------------------------
275 inline auto FVTermBuffer::getLength() const noexcept -> std::size_t
276 { return data.size(); }
277 
278 //----------------------------------------------------------------------
279 inline auto FVTermBuffer::getBuffer() const noexcept -> const FCharVector&
280 { return data; }
281 
282 //----------------------------------------------------------------------
283 inline auto FVTermBuffer::isEmpty() const noexcept -> bool
284 { return data.empty(); }
285 
286 //----------------------------------------------------------------------
287 inline auto FVTermBuffer::begin() noexcept -> iterator
288 { return data.begin(); }
289 
290 //----------------------------------------------------------------------
291 inline auto FVTermBuffer::end() noexcept -> iterator
292 { return data.end(); }
293 
294 //----------------------------------------------------------------------
295 inline auto FVTermBuffer::begin() const noexcept -> const_iterator
296 { return data.begin(); }
297 
298 //----------------------------------------------------------------------
299 inline auto FVTermBuffer::end() const noexcept -> const_iterator
300 { return data.end(); }
301 
302 //----------------------------------------------------------------------
303 inline auto FVTermBuffer::front() -> reference
304 { return data.front(); }
305 
306 //----------------------------------------------------------------------
307 inline auto FVTermBuffer::back() -> reference
308 { return data.back(); }
309 
310 //----------------------------------------------------------------------
311 inline auto FVTermBuffer::front() const -> const_reference
312 { return data.front(); }
313 
314 //----------------------------------------------------------------------
315 inline auto FVTermBuffer::back() const -> const_reference
316 { return data.back(); }
317 
318 //----------------------------------------------------------------------
319 template <typename Iterator>
320 inline void FVTermBuffer::assign (Iterator first, Iterator last)
321 {
322  if ( first >= last )
323  return;
324 
325  checkCapacity (data, std::size_t(last - first));
326  data.assign(first, last);
327 }
328 
329 //----------------------------------------------------------------------
330 inline void FVTermBuffer::clear() noexcept
331 {
332  data.clear();
333 }
334 
335 //----------------------------------------------------------------------
336 template <typename... Args>
337 inline auto FVTermBuffer::printf (const FString& format, Args&&... args) -> int
338 {
339  FString str{};
340  str.sprintf (format, std::forward<Args>(args)...);
341  return print(str);
342 }
343 
344 //----------------------------------------------------------------------
345 inline auto FVTermBuffer::print() noexcept -> FVTermBuffer&
346 { return *this; }
347 
348 //----------------------------------------------------------------------
349 template<typename T>
350 constexpr void checkCapacity (T& buffer, std::size_t size) noexcept
351 {
352  if ( size <= buffer.capacity() )
353  return;
354 
355  const auto new_size = [size] () noexcept
356  {
357  return std::size_t(std::pow(2, std::ceil(std::log(size) / std::log(2.0))));
358  }();
359 
360  buffer.reserve(new_size);
361 }
362 
363 } // namespace finalcut
364 
365 #endif // FVTERMBUFFER_H
Definition: fvtermbuffer.h:56
Definition: class_template.cpp:25
Definition: ftypes.h:1081
Definition: fstring.h:82
Definition: fstyle.h:49
Definition: fcolorpair.h:49