format.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "crucible/core/format.inl" #include "crucible/core/demangle.inl" #include "crucible/core/string.inl" #include "crucible/core/utility.inl" namespace crucible::core { FormatContext::FormatContext(std::size_t const indent_size, std::size_t const nesting) : my_indent_size { indent_size }, my_nesting { nesting } {} auto FormatContext::get_indent() const -> String { constexpr String_View SPACE { " " }; return SPACE.repeat(my_indent_size * my_nesting); } auto FormatContext::nest() const -> FormatContext { return FormatContext { my_indent_size, my_nesting + 1 }; } auto FormatContextBuilder::set_indent_size(std::size_t const indent_size) -> FormatContextBuilder & { my_indent_size = indent_size; return *this; } auto FormatContextBuilder::get() const -> FormatContext { return FormatContext { my_indent_size, 0 }; } Formatter::Formatter(String_View const name, FormatContext const &context) : my_name { name }, my_outer_context { context }, my_inner_context { context.nest() } {} auto Formatter::get() const -> String { return my_name + " {\n" + my_buffer + my_outer_context.get_indent() + "}"; } auto build_format_context() -> FormatContextBuilder { return FormatContextBuilder {}; } auto build_formatter(String_View const name, FormatContext const &context) -> Formatter { return Formatter { name, context }; } auto format_bool(bool const value) -> String { if (value) { return String { "true" }; } return String { "false" }; } auto format_address(void const *value) -> String { if (value == nullptr) { return String { "nullptr" }; } return format_unsigned_hexadecimal(reinterpret_cast<std::uintptr_t>(value)); } auto format_cstring(char const *value, std::size_t const size) -> String { String result; result += "\""; result += String { value, size }; result += "\""; return result; } auto format_std_string(std::string const &value) -> String { return "std::string { [synthetic] contents: \"" + String { value.data(), value.size() } + "\" }"; } auto format_std_byte(std::byte const &value) -> String { return "std::byte { " + format_unsigned_hexadecimal(std::to_integer<std::uint8_t>(value)) + " }"; } auto format_std_type_info(std::type_info const &value) -> String { char const *value_name_data { value.name() }; std::size_t const value_name_size { std::strlen(value_name_data) }; String_View const value_name { value_name_data, value_name_size }; auto const handle_failure { [&value_name](Demangle_Error const &error) -> String { return value_name + " (" + error.describe() + ")"; } }; auto const demangled_name { demangle(value_name.view_data()) .resolve(handle_failure, identity<String>) }; return "std::type_info { [synthetic] name: " + format_cstring(demangled_name.data(), demangled_name.size()) + " }"; } }