visualize.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_VISUALIZE_HPP_INCLUDED
5 #define LEXY_VISUALIZE_HPP_INCLUDED
6 
7 #include <cstdio>
11 #include <lexy/lexeme.hpp>
12 
13 //=== visualization_options ===//
14 namespace lexy
15 {
17 {
19 
26 
29 
31  visualize_space = 1 << 3,
32 };
33 
35 {
36  return visualization_flags(int(lhs) | int(rhs));
37 }
38 
41 {
42  static constexpr unsigned char max_tree_depth_limit = 32;
43 
46 
52  unsigned char max_lexeme_width = 0;
55  unsigned char tab_width = 0;
56 
57  constexpr bool is_set(visualization_flags f) const noexcept
58  {
59  return (flags & f) != 0;
60  }
61 
63  {
64  auto copy = *this;
65  copy.flags = visualization_flags(copy.flags & ~f);
66  return copy;
67  }
68 
70  visualization_flags rhs) noexcept
71  {
72  lhs.flags = lhs.flags | rhs;
73  return lhs;
74  }
75 };
76 } // namespace lexy
77 
78 //=== visualize_to ===//
79 namespace lexy::_detail
80 {
81 template <typename Encoding>
82 constexpr auto make_literal_lexeme(const typename Encoding::char_type* str, std::size_t length)
83 {
84  struct reader
85  {
86  using encoding = Encoding;
87  using iterator = const typename Encoding::char_type*;
88  };
89 
90  return lexy::lexeme<reader>(str, str + length);
91 }
92 
93 template <typename OutIt>
94 constexpr OutIt write_str(OutIt out, const char* str)
95 {
96  while (*str)
97  *out++ = *str++;
98  return out;
99 }
100 template <typename OutIt>
101 constexpr OutIt write_str(OutIt out, const LEXY_CHAR8_T* str)
102 {
103  while (*str)
104  *out++ = static_cast<char>(*str++);
105  return out;
106 }
107 
108 template <int N = 16, typename OutIt, typename... Args>
109 constexpr OutIt write_format(OutIt out, const char* fmt, const Args&... args)
110 {
111  char buffer[std::size_t(N + 1)];
112  auto count = std::snprintf(buffer, N, fmt, args...);
113  LEXY_ASSERT(count <= N, "buffer not big enough");
114 
115  for (auto i = 0; i != count; ++i)
116  *out++ = buffer[i];
117  return out;
118 }
119 
120 enum class color
121 {
122  reset = 0,
123  bold = 1,
124  faint = 2,
125  italic = 3,
126 
127  black = 30,
128  red = 31,
129  green = 32,
130  yellow = 33,
131  blue = 34,
132  magenta = 35,
133  cyan = 36,
134  white = 37,
135 };
136 
137 template <color CodeHead, color... CodeTail, typename OutIt>
138 constexpr OutIt write_color(OutIt out, visualization_options opts)
139 {
140  if (!opts.is_set(visualize_use_color))
141  return out;
142 
143  out = write_str(out, "\033[");
144 
145  auto write_code = [](OutIt out, int code) {
146  if (code > 10)
147  {
148  *out++ = static_cast<char>((code / 10) + '0');
149  *out++ = static_cast<char>((code % 10) + '0');
150  }
151  else
152  {
153  *out++ = static_cast<char>(code + '0');
154  }
155  return out;
156  };
157  out = write_code(out, int(CodeHead));
158  ((*out++ = ';', write_code(out, int(CodeTail))), ...);
159 
160  *out++ = 'm';
161  return out;
162 }
163 
164 template <typename OutIt>
165 constexpr OutIt write_ellipsis(OutIt out, visualization_options opts)
166 {
167  if (opts.is_set(visualize_use_unicode))
168  return _detail::write_str(out, u8"…");
169  else
170  return _detail::write_str(out, "...");
171 }
172 
173 template <typename OutIt, typename Fn>
174 constexpr OutIt write_special_char(OutIt out, visualization_options opts, Fn inner)
175 {
176  out = _detail::write_color<_detail::color::cyan, _detail::color::faint>(out, opts);
177  if (opts.is_set(visualize_use_unicode))
178  out = _detail::write_str(out, u8"⟨");
179  else
180  out = _detail::write_str(out, "\\");
181 
182  out = inner(out);
183 
184  if (opts.is_set(visualize_use_unicode))
185  out = _detail::write_str(out, u8"⟩");
186  out = _detail::write_color<_detail::color::reset>(out, opts);
187  return out;
188 }
189 } // namespace lexy::_detail
190 
191 namespace lexy
192 {
193 template <typename OutputIt>
194 OutputIt visualize_to(OutputIt out, lexy::code_point cp, visualization_options opts = {})
195 {
196  if (!cp.is_valid())
197  {
198  out = _detail::write_special_char(out, opts, [opts](OutputIt out) {
199  if (opts.is_set(visualize_use_unicode))
200  return _detail::write_str(out, "U+????");
201  else
202  return _detail::write_str(out, "u????");
203  });
204  return out;
205  }
206  else if (cp.is_control())
207  {
208  auto c = static_cast<int>(cp.value());
209  switch (c)
210  {
211  case '\0':
212  out = _detail::write_special_char(out, opts, [opts](OutputIt out) {
213  if (opts.is_set(visualize_use_unicode))
214  return _detail::write_str(out, "NUL");
215  else
216  return _detail::write_str(out, "0");
217  });
218  break;
219  case '\r':
220  out = _detail::write_special_char(out, opts, [opts](OutputIt out) {
221  if (opts.is_set(visualize_use_unicode))
222  return _detail::write_str(out, "CR");
223  else
224  return _detail::write_str(out, "r");
225  });
226  break;
227 
228  case '\n':
229  if (opts.is_set(visualize_use_symbols))
230  {
231  out = _detail::write_color<_detail::color::faint>(out, opts);
232  out = _detail::write_str(out, u8"⏎");
233  out = _detail::write_color<_detail::color::reset>(out, opts);
234  }
235  else if (opts.is_set(visualize_use_unicode))
236  {
237  out = _detail::write_special_char(out, opts, [](OutputIt out) {
238  return _detail::write_str(out, "LF");
239  });
240  }
241  else
242  {
243  out = _detail::write_special_char(out, opts, [](OutputIt out) {
244  return _detail::write_str(out, "n");
245  });
246  }
247  break;
248  case '\t':
249  if (opts.tab_width > 0)
250  {
251  // We print that many space characters.
252  // This is recursion, but the recursive call does not recurse further.
253  for (auto i = 0u; i < opts.tab_width; ++i)
254  out = visualize_to(out, lexy::code_point(' '), opts);
255  }
256  else if (opts.is_set(visualize_use_symbols))
257  {
258  out = _detail::write_color<_detail::color::faint>(out, opts);
259  out = _detail::write_str(out, u8"⇨");
260  out = _detail::write_color<_detail::color::reset>(out, opts);
261  }
262  else if (opts.is_set(visualize_use_unicode))
263  {
264  out = _detail::write_special_char(out, opts, [](OutputIt out) {
265  return _detail::write_str(out, "HT");
266  });
267  }
268  else
269  {
270  out = _detail::write_special_char(out, opts, [](OutputIt out) {
271  return _detail::write_str(out, "t");
272  });
273  }
274  break;
275 
276  default:
277  out = _detail::write_special_char(out, opts, [opts, c](OutputIt out) {
278  if (opts.is_set(visualize_use_unicode))
279  return _detail::write_format(out, "U+%04X", c);
280  else
281  return _detail::write_format(out, "u%04X", c);
282  });
283  break;
284  }
285  return out;
286  }
287  else if (cp.value() == ' ')
288  {
289  if (opts.is_set(visualize_space))
290  {
291  if (opts.is_set(visualize_use_symbols))
292  {
293  out = _detail::write_color<_detail::color::faint>(out, opts);
294  out = _detail::write_str(out, u8"␣");
295  out = _detail::write_color<_detail::color::reset>(out, opts);
296  }
297  else if (opts.is_set(visualize_use_unicode))
298  {
299  out = _detail::write_special_char(out, opts, [](OutputIt out) {
300  return _detail::write_str(out, "SP");
301  });
302  }
303  else
304  {
305  out = _detail::write_special_char(out, opts, [](OutputIt out) {
306  return _detail::write_str(out, "u0020");
307  });
308  }
309  }
310  else
311  {
312  *out++ = ' ';
313  }
314 
315  return out;
316  }
317  else if (cp.value() == '\\')
318  {
319  if (!opts.is_set(visualize_use_unicode))
320  out = _detail::write_special_char(out, opts, [](OutputIt out) {
321  return _detail::write_str(out, "\\");
322  });
323  else
324  *out++ = '\\'; // Doesn't need escaping if we can use unicode.
325  return out;
326  }
327  else if (cp.is_ascii())
328  {
329  // ASCII, non-control character, print as-is.
330  *out++ = static_cast<char>(cp.value());
331  return out;
332  }
333  else
334  {
335  out = _detail::write_special_char(out, opts, [opts, cp](OutputIt out) {
336  auto c = static_cast<int>(cp.value());
337  if (opts.is_set(visualize_use_unicode))
338  return _detail::write_format(out, "U+%04X", c);
339  else if (cp.is_bmp())
340  return _detail::write_format(out, "u%04X", c);
341  else
342  return _detail::write_format(out, "U%08X", c);
343  });
344  return out;
345  }
346 }
347 
348 template <typename OutputIt, typename Reader>
349 OutputIt visualize_to(OutputIt out, lexy::lexeme<Reader> lexeme,
350  [[maybe_unused]] visualization_options opts = {})
351 {
352  // We need to ensure that we're not printing more "code points" than `opts.max_lexeme_width`,
353  // or unlimited if `opts.max_lexeme_width == 0`.
354  // The trick is to count and check for `count == opts.max_lexeme_width` after increment.
355 
356  [[maybe_unused]] auto write_escaped_byte = [opts](OutputIt out, unsigned char byte) {
357  return _detail::write_special_char(out, opts, [opts, byte](OutputIt out) {
358  if (opts.is_set(visualize_use_unicode))
359  return _detail::write_format(out, "0x%02X", byte);
360  else
361  return _detail::write_format(out, "x%02X", byte);
362  });
363  };
364 
365  using encoding = typename Reader::encoding;
366  if constexpr (lexy::is_unicode_encoding<encoding>)
367  {
368  // Parse the individual code points, and write them out.
370  auto reader = input.reader();
371 
372  auto count = 0u;
373  while (true)
374  {
375  if (auto result = lexy::_detail::parse_code_point(reader);
376  result.error == lexy::_detail::cp_error::eof)
377  {
378  // No more code points in the lexeme, finish.
379  break;
380  }
381  else if (result.error == lexy::_detail::cp_error::success)
382  {
383  // Consume and visualize.
384  reader.reset(result.end);
385  out = visualize_to(out, lexy::code_point(result.cp), opts);
386  }
387  else
388  {
389  // Recover from the failed code point.
390  auto begin = reader.position();
391  lexy::_detail::recover_code_point(reader, result);
392  auto end = reader.position();
393 
394  // Visualize each skipped code unit as byte.
395  for (auto cur = begin; cur != end; ++cur)
396  {
397  if constexpr (std::is_same_v<encoding,
399  || std::is_same_v<encoding, lexy::utf8_char_encoding>)
400  {
401  out = write_escaped_byte(out, static_cast<unsigned char>(*cur & 0xFF));
402  }
403  else if constexpr (std::is_same_v<encoding, lexy::utf16_encoding>)
404  {
405  auto first = static_cast<unsigned char>((*cur >> 8) & 0xFF);
406  auto second = static_cast<unsigned char>(*cur & 0xFF);
407 
408  if (first != 0)
409  out = write_escaped_byte(out, first);
410  out = write_escaped_byte(out, second);
411  }
412  else if constexpr (std::is_same_v<encoding, lexy::utf32_encoding>)
413  {
414  auto first = static_cast<unsigned char>((*cur >> 24) & 0xFF);
415  auto second = static_cast<unsigned char>((*cur >> 16) & 0xFF);
416  auto third = static_cast<unsigned char>((*cur >> 8) & 0xFF);
417  auto fourth = static_cast<unsigned char>(*cur & 0xFF);
418 
419  if (first != 0)
420  out = write_escaped_byte(out, first);
421  if (first != 0 || second != 0)
422  out = write_escaped_byte(out, second);
423  if (first != 0 || second != 0 || third != 0)
424  out = write_escaped_byte(out, third);
425  out = write_escaped_byte(out, fourth);
426  }
427  }
428  }
429 
430  ++count;
431  if (count == opts.max_lexeme_width)
432  {
433  out = _detail::write_ellipsis(out, opts);
434  break;
435  }
436  }
437  return out;
438  }
439  else if constexpr (lexy::is_text_encoding<encoding>)
440  {
441  auto count = 0u;
442  for (char c : lexeme)
443  {
444  // If the character is in fact ASCII, visualize the code point.
445  // Otherwise, visualize as byte.
447  out = visualize_to(out, lexy::code_point(static_cast<char32_t>(c)), opts);
448  else
449  out = write_escaped_byte(out, static_cast<unsigned char>(c));
450 
451  ++count;
452  if (count == opts.max_lexeme_width)
453  {
454  out = _detail::write_ellipsis(out, opts);
455  break;
456  }
457  }
458  return out;
459  }
460  else if constexpr (lexy::is_byte_encoding<encoding>)
461  {
462  auto count = 0u;
463  for (auto iter = lexeme.begin(); iter != lexeme.end(); ++iter)
464  {
465  // Write each byte.
466  out = _detail::write_special_char(out, opts, [c = *iter](OutputIt out) {
467  return _detail::write_format(out, "%02X", c);
468  });
469 
470  ++count;
471  if (count == opts.max_lexeme_width)
472  {
473  out = _detail::write_ellipsis(out, opts);
474  break;
475  }
476  }
477  return out;
478  }
479  else if constexpr (lexy::is_node_encoding<encoding>)
480  {
481  // Visualize as an iterator range of characters.
483  input(lexeme.begin(), lexeme.end());
484  return visualize_to(out, lexy::lexeme_for<decltype(input)>(input.begin(), input.end()));
485  }
486  else
487  {
488  static_assert(lexy::_detail::error<encoding>, "unknown encoding");
489  return out;
490  }
491 }
492 
493 template <typename OutputIt, typename Tree, typename = decltype(LEXY_DECLVAL(Tree&).traverse())>
494 OutputIt visualize_to(OutputIt out, const Tree& tree, visualization_options opts = {})
495 {
496  struct label_t
497  {
498  const LEXY_CHAR_OF_u8* space;
499  const LEXY_CHAR_OF_u8* line;
500  const LEXY_CHAR_OF_u8* end;
501  const LEXY_CHAR_OF_u8* branch;
502  };
503  auto label = opts.is_set(visualize_use_unicode) ? label_t{u8" ", u8"│ ", u8"└──", u8"├──"}
504  : label_t{u8" ", u8" ", u8"- ", u8"- "};
505 
506  // True if the node currently opened at the depth is the last child of its parent,
507  // false otherwise.
508  bool is_last_child[visualization_options::max_tree_depth_limit] = {};
510 
511  // Writes the prefix using the last child information.
512  auto write_prefix
513  = [opts, label, &is_last_child](OutputIt out, std::size_t cur_depth, bool cur_is_last) {
514  if (cur_depth == 0)
515  // Root node doesn't have a prefix.
516  return out;
517 
518  out = _detail::write_color<_detail::color::faint>(out, opts);
519 
520  // We begin at depth 1, as depth 0 doesn't require a prefix.
521  for (auto i = 1u; i < cur_depth; ++i)
522  if (is_last_child[i])
523  // If the current node at that depth is the last child, we just indent.
524  out = _detail::write_str(out, label.space);
525  else
526  // Otherwise, we need to carry the line.
527  out = _detail::write_str(out, label.line);
528 
529  // Print the final branching symbol for the current node.
530  if (cur_is_last)
531  out = _detail::write_str(out, label.end);
532  else
533  out = _detail::write_str(out, label.branch);
534 
535  out = _detail::write_color<_detail::color::reset>(out, opts);
536  return out;
537  };
538 
539  // Traverse and print the tree.
540  std::size_t cur_depth = 0;
541  for (auto [event, node] : tree.traverse())
542  {
543  auto last_child = node.is_last_child();
544 
545  using event_t = typename decltype(tree.traverse())::event;
546  switch (event)
547  {
548  case event_t::enter:
549  if (cur_depth <= opts.max_tree_depth)
550  {
551  out = write_prefix(out, cur_depth, last_child);
552 
553  out = _detail::write_color<_detail::color::bold>(out, opts);
554  out = _detail::write_str(out, node.kind().name());
555  out = _detail::write_color<_detail::color::reset>(out, opts);
556 
557  if (cur_depth == opts.max_tree_depth)
558  {
559  // Print an ellipsis instead of children.
560  out = _detail::write_str(out, ": ");
561  out = _detail::write_ellipsis(out, opts);
562  out = _detail::write_str(out, "\n");
563  }
564  else
565  {
566  // Print a newline and prepare for children.
567  out = _detail::write_str(out, ":\n");
568  is_last_child[cur_depth] = last_child;
569  }
570  }
571  ++cur_depth;
572  break;
573 
574  case event_t::exit:
575  --cur_depth;
576  break;
577 
578  case event_t::leaf:
579  if (cur_depth <= opts.max_tree_depth)
580  {
581  out = write_prefix(out, cur_depth, last_child);
582 
583  out = _detail::write_color<_detail::color::bold>(out, opts);
584  out = _detail::write_str(out, node.kind().name());
585  out = _detail::write_color<_detail::color::reset>(out, opts);
586 
587  if (!node.lexeme().empty())
588  {
589  out = _detail::write_str(out, ": ");
590  out = visualize_to(out, node.lexeme(), opts | lexy::visualize_space);
591  }
592 
593  out = _detail::write_str(out, "\n");
594  }
595  break;
596  }
597  }
598 
599  return out;
600 }
601 } // namespace lexy
602 
603 //=== visualize ===//
604 namespace lexy
605 {
607 {
608  std::FILE* _file;
609 
610  explicit constexpr cfile_output_iterator(std::FILE* file) : _file(file) {}
611 
612  auto operator*() const noexcept
613  {
614  return *this;
615  }
616  auto operator++(int) const noexcept
617  {
618  return *this;
619  }
620 
622  {
623  std::fputc(c, _file);
624  return *this;
625  }
626 };
627 
629 {
630  auto operator*() const noexcept
631  {
632  return *this;
633  }
634  auto operator++(int) const noexcept
635  {
636  return *this;
637  }
638 
640  {
641  std::fputc(c, stderr);
642  return *this;
643  }
644 };
646 {
647  auto operator*() const noexcept
648  {
649  return *this;
650  }
651  auto operator++(int) const noexcept
652  {
653  return *this;
654  }
655 
657  {
658  std::fputc(c, stdout);
659  return *this;
660  }
661 };
662 
664 template <typename T>
665 void visualize(std::FILE* file, const T& obj, visualization_options opts = {})
666 {
667  visualize_to(cfile_output_iterator{file}, obj, opts);
668 }
669 } // namespace lexy
670 
671 //=== visualization_display_width ===//
672 namespace lexy
673 {
674 template <typename T>
675 std::size_t visualization_display_width(const T& obj, visualization_options opts = {})
676 {
677  struct iterator
678  {
679  std::size_t width;
680 
681  iterator& operator*() noexcept
682  {
683  return *this;
684  }
685  iterator& operator++(int) noexcept
686  {
687  return *this;
688  }
689 
690  iterator& operator=(char c)
691  {
692  // We're having ASCII or UTF-8 characters.
693  // All unicode characters used occupy a single cell,
694  // so we just need to count all code units that are not continuation bytes.
695  auto value = static_cast<unsigned char>(c);
696  if ((value & 0b1100'0000) != 0b1000'0000)
697  ++width;
698  return *this;
699  }
700  };
701 
702  // Disable usage of color, as they introduce additional characters that must nobe counted.
703  return visualize_to(iterator{0}, obj, opts.reset(visualize_use_color)).width;
704 }
705 } // namespace lexy
706 
707 #endif // LEXY_VISUALIZE_HPP_INCLUDED
708 
lexy::_detail::color
color
Definition: visualize.hpp:120
lexy::_detail::color::white
@ white
lexy::_detail::write_ellipsis
constexpr OutIt write_ellipsis(OutIt out, visualization_options opts)
Definition: visualize.hpp:165
lexy::cfile_output_iterator::_file
std::FILE * _file
Definition: visualize.hpp:608
lexy::stderr_output_iterator::operator*
auto operator*() const noexcept
Definition: visualize.hpp:630
lexy::_detail::color::green
@ green
lexy::cfile_output_iterator::cfile_output_iterator
constexpr cfile_output_iterator(std::FILE *file)
Definition: visualize.hpp:610
lexy::_detail::color::magenta
@ magenta
lexy::visualize_use_color
@ visualize_use_color
Visualization can use ANSI color escape sequences.
Definition: visualize.hpp:23
lexy::_detail::write_format
constexpr OutIt write_format(OutIt out, const char *fmt, const Args &... args)
Definition: visualize.hpp:109
lexy::_detail::color::yellow
@ yellow
magic_enum::char_type
string_view::value_type char_type
Definition: magic_enum.hpp:145
lexy::stdout_output_iterator
Definition: visualize.hpp:645
lexy::visualization_display_width
std::size_t visualization_display_width(const T &obj, visualization_options opts={})
Definition: visualize.hpp:675
lexy::_detail::write_str
constexpr OutIt write_str(OutIt out, const char *str)
Definition: visualize.hpp:94
config.hpp
lexy::visualization_options::max_tree_depth
unsigned char max_tree_depth
Definition: visualize.hpp:49
lexy::_detail::parse_code_point
constexpr cp_result< Reader > parse_code_point(Reader reader)
Definition: _detail/code_point.hpp:142
lexy::_detail::write_color
constexpr OutIt write_color(OutIt out, visualization_options opts)
Definition: visualize.hpp:138
lexy::code_point::is_control
constexpr bool is_control() const noexcept
Definition: code_point.hpp:45
lexy::visualization_options
Options that control visualization.
Definition: visualize.hpp:40
lexy::_detail::color::bold
@ bold
lexy::visualization_options::is_set
constexpr bool is_set(visualization_flags f) const noexcept
Definition: visualize.hpp:57
lexy::_detail::recover_code_point
constexpr void recover_code_point(Reader &reader, cp_result< Reader > result)
Definition: _detail/code_point.hpp:338
lexy::visualization_options::tab_width
unsigned char tab_width
Definition: visualize.hpp:55
lexy::visualization_options::operator|
constexpr friend visualization_options operator|(visualization_options lhs, visualization_flags rhs) noexcept
Definition: visualize.hpp:69
lexy::visualization_options::reset
constexpr visualization_options reset(visualization_flags f) const noexcept
Definition: visualize.hpp:62
lexy::code_point::is_ascii
constexpr bool is_ascii() const noexcept
Definition: code_point.hpp:32
LEXY_CHAR_OF_u8
#define LEXY_CHAR_OF_u8
Definition: config.hpp:138
lexy::range_input
Definition: range_input.hpp:14
lexy::cfile_output_iterator
Definition: visualize.hpp:606
magic_enum::detail::value
constexpr E value(std::size_t i) noexcept
Definition: magic_enum.hpp:664
lexy::_detail::cp_error::eof
@ eof
lexy
Definition: any_ref.hpp:12
LEXY_PRECONDITION
#define LEXY_PRECONDITION(Expr)
Definition: assert.hpp:36
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
lexy::code_point::value
constexpr auto value() const noexcept
Definition: code_point.hpp:26
lexy::operator|
constexpr auto operator|(First first, Second second)
Composes two callbacks.
Definition: composition.hpp:100
lexy::_detail::make_literal_lexeme
constexpr auto make_literal_lexeme(const typename Encoding::char_type *str, std::size_t length)
Definition: visualize.hpp:82
lexy::visualize
void visualize(std::FILE *file, const T &obj, visualization_options opts={})
Writes the visualization to the FILE.
Definition: visualize.hpp:665
lexy::visualization_options::max_tree_depth_limit
static constexpr unsigned char max_tree_depth_limit
Definition: visualize.hpp:42
lexy::visualize_to
OutputIt visualize_to(OutputIt out, lexy::code_point cp, visualization_options opts={})
Definition: visualize.hpp:194
range_input.hpp
lexy::count
constexpr auto count
Sink that counts all arguments.
Definition: fold.hpp:88
lexy::stderr_output_iterator::operator=
stderr_output_iterator & operator=(char c)
Definition: visualize.hpp:639
lexeme.hpp
lexy::visualize_use_symbols
@ visualize_use_symbols
Visualization can use Unicode symbols e.g. for newline/space instead of the code point.
Definition: visualize.hpp:25
lexy::code_point::is_bmp
constexpr bool is_bmp() const noexcept
Definition: code_point.hpp:36
lexy::visualization_options::max_lexeme_width
unsigned char max_lexeme_width
Definition: visualize.hpp:52
lexy::stdout_output_iterator::operator++
auto operator++(int) const noexcept
Definition: visualize.hpp:651
lexy::utf8_encoding
An encoding where the input is assumed to be valid UTF-8.
Definition: encoding.hpp:84
lexy::_detail::color::reset
@ reset
lexy::_detail::is_ascii
constexpr bool is_ascii(CharT c)
Definition: encoding.hpp:291
code_point.hpp
lexy::visualize_fancy
@ visualize_fancy
Visualization can use unicode, color and symbols.
Definition: visualize.hpp:28
lexy::stdout_output_iterator::operator=
stdout_output_iterator & operator=(char c)
Definition: visualize.hpp:656
lexy::cfile_output_iterator::operator=
cfile_output_iterator & operator=(char c)
Definition: visualize.hpp:621
f
static FILE * f
Definition: minitrace.cpp:74
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::code_point::is_valid
constexpr bool is_valid() const noexcept
Definition: code_point.hpp:40
wildcards::detail::is_set_state::first
@ first
lexy::cfile_output_iterator::operator*
auto operator*() const noexcept
Definition: visualize.hpp:612
lexy::_detail
Definition: any_ref.hpp:12
lexy::buffer
Definition: buffer.hpp:95
lexy::visualization_flags
visualization_flags
Definition: visualize.hpp:16
lexy::visualize_default
@ visualize_default
Definition: visualize.hpp:18
lexy::lexeme
Definition: lexeme.hpp:16
lexy::_detail::cp_error::success
@ success
lexyd::byte
constexpr auto byte
Matches an arbitrary byte.
Definition: byte.hpp:133
lexy::_detail::color::red
@ red
lexy::lexeme
lexeme(const Reader &, typename Reader::iterator) -> lexeme< typename Reader::canonical_reader >
lexy::stderr_output_iterator
Definition: visualize.hpp:628
lexy::stderr_output_iterator::operator++
auto operator++(int) const noexcept
Definition: visualize.hpp:634
lexyd::ascii::space
constexpr auto space
Definition: ascii.hpp:112
lexy::_detail::color::italic
@ italic
lexy::visualize_space
@ visualize_space
Visualize space ' ' as visible character/symbol.
Definition: visualize.hpp:31
lexy::_detail::color::blue
@ blue
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:32
lexy::visualize_use_unicode
@ visualize_use_unicode
Visualization can use unicode characters.
Definition: visualize.hpp:21
lexy::_detail::color::cyan
@ cyan
lexy::cfile_output_iterator::operator++
auto operator++(int) const noexcept
Definition: visualize.hpp:616
lexy::_detail::color::black
@ black
lexy::visualization_options::flags
visualization_flags flags
Boolean flags.
Definition: visualize.hpp:45
lexy::stdout_output_iterator::operator*
auto operator*() const noexcept
Definition: visualize.hpp:647
lexy::_detail::color::faint
@ faint
LEXY_ASSERT
#define LEXY_ASSERT(Expr, Msg)
Definition: assert.hpp:37
LEXY_CHAR8_T
#define LEXY_CHAR8_T
Definition: config.hpp:139
lexy::code_point
A unicode code point.
Definition: code_point.hpp:20
lexy::_detail::write_special_char
constexpr OutIt write_special_char(OutIt out, visualization_options opts, Fn inner)
Definition: visualize.hpp:174


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Dec 13 2024 03:19:17