IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
log_formatters.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/mem.hxx>
6#include <ice/stringid.hxx>
7#include <ice/mem_types.hxx>
8#include <ice/heap_string.hxx>
9#include <ice/clock_types.hxx>
10#include <ice/error_codes.hxx>
11#include <fmt/format.h>
12
13
14template<>
15struct fmt::formatter<ice::StringID_Hash>
16{
17 template<typename ParseContext>
18 constexpr auto parse(ParseContext& ctx)
19 {
20 return ctx.begin();
21 }
22
23 template<typename FormatContext>
24 constexpr auto format(ice::StringID_Hash value, FormatContext& ctx) const noexcept
25 {
26 if (value.value == ice::stringid_hash(ice::StringID_Invalid).value)
27 {
28 return fmt::format_to(ctx.out(), "[sid_hash:<invalid>]");
29 }
30 else
31 {
32 return fmt::format_to(ctx.out(), "[sid_hash:{:16x}]", value.value);
33 }
34 }
35};
36
37template<bool DebugImpl>
38struct fmt::formatter<ice::BaseStringID<DebugImpl>>
39{
40 template<typename ParseContext>
41 constexpr auto parse(ParseContext& ctx)
42 {
43 return ctx.begin();
44 }
45
46 template<typename FormatContext>
47 constexpr auto format(ice::StringID_Arg value, FormatContext& ctx) const noexcept
48 {
49 if (value == ice::StringID_Invalid)
50 {
51 return fmt::format_to(ctx.out(), "[sid:<invalid>]");
52 }
53 else
54 {
55 if constexpr (DebugImpl == false)
56 {
57 return fmt::format_to(ctx.out(), "[sid:{:16x}]", ice::stringid_hash(value).value);
58 }
59 else
60 {
61 return fmt::format_to(ctx.out(), "[sid:{:16x}]'{}'", ice::stringid_hash(value).value, ice::stringid_hint(value));
62 }
63 }
64 }
65};
66
67template<>
68struct fmt::formatter<ice::ncount>
69{
70 template<typename ParseContext>
71 constexpr auto parse(ParseContext& ctx)
72 {
73 return ctx.begin();
74 }
75
76 template<typename FormatContext>
77 constexpr auto format(ice::ncount value, FormatContext& ctx) const noexcept
78 {
79 return fmt::format_to(ctx.out(), "{}", value.native());
80 }
81};
82
83template<>
84struct fmt::formatter<ice::usize>
85{
86 char presentation = 'b'; // i - integral, b - bytes, p - pretty, P - pretty with spaces
87
88 template<typename ParseContext>
89 constexpr auto parse(ParseContext& ctx)
90 {
91 auto it = ctx.begin(), end = ctx.end();
92 // Parse the presentation format and store it in the formatter:
93 if (it != end && (*it == 'i' || *it == 'b' || *it == 'p' || *it == 'P')) presentation = *it++;
94
95 // Check if reached the end of the range:
96 if (it != end && *it != '}') throw fmt::format_error("invalid format");
97
98 // Return an iterator past the end of the parsed range:
99 return it;
100 }
101
102 template<typename FormatContext>
103 constexpr auto format(ice::usize value, FormatContext& ctx) const noexcept
104 {
105 using namespace ice;
106
107 switch (presentation)
108 {
109 case 'i':
110 return fmt::format_to(ctx.out(), "{}", value.value);
111 case 'p':
112 case 'P':
113 {
114 if (value < 1_KiB)
115 {
116 if (presentation == 'P')
117 {
118 return fmt::format_to(ctx.out(), "{} B", value.value);
119 }
120 else
121 {
122 return fmt::format_to(ctx.out(), "{}B", value.value);
123 }
124 }
125 else if (value < 1_MiB)
126 {
127 if (presentation == 'P')
128 {
129 return fmt::format_to(ctx.out(), "{} KiB {} B", (value.value / 1024), value.value % 1024);
130 }
131 else
132 {
133 return fmt::format_to(ctx.out(), "{}KiB {}B", (value.value / 1024), value.value % 1024);
134 }
135 }
136 else
137 {
138 if (presentation == 'P')
139 {
140 return fmt::format_to(
141 ctx.out(),
142 "{} MiB {} KiB {} B",
143 (value.value / (1024 * 1024)), (value.value / 1024) % 1024, value.value % 1024
144 );
145 }
146 else
147 {
148 return fmt::format_to(
149 ctx.out(),
150 "{}MiB {}KiB {}B",
151 (value.value / (1024 * 1024)), (value.value / 1024) % 1024, value.value % 1024
152 );
153 }
154 }
155 }
156 default:
157 return fmt::format_to(ctx.out(), "{}B", value.value);
158 }
159 }
160};
161
162template<>
163struct fmt::formatter<ice::isize> : fmt::formatter<ice::usize>
164{
165 template<typename FormatContext>
166 constexpr auto format(ice::isize value, FormatContext& ctx) const noexcept
167 {
168 auto output = ctx.out();
169 if (value.value < 0)
170 {
171 output = fmt::format_to(ctx.out(), "-");
172 value = -value;
173 }
174 return fmt::formatter<ice::usize>::format(value.to_usize(), ctx);
175 }
176};
177
178template<>
179struct fmt::formatter<ice::ErrorCode>
180{
181 template<typename ParseContext>
182 constexpr auto parse(ParseContext& ctx)
183 {
184 return ctx.begin();
185 }
186
187 template<typename FormatContext>
188 constexpr auto format(ice::ErrorCode value, FormatContext& ctx) const noexcept
189 {
190 fmt::string_view const type = value.type() == 'E' ? "Error" : "Success";
191 return fmt::format_to(ctx.out(), "{}({}, '{}')", type, value.category(), value.description());
192 }
193};
194
195template<ice::TimeType T>
196struct fmt::formatter<T>
197{
198 static constexpr auto presentation_type(ice::Ts t) noexcept { return 's'; }
199 static constexpr auto presentation_type(ice::Tms t) noexcept { return t.value > 9999 ? presentation_type(ice::Ts(t)) : 'm'; }
200 static constexpr auto presentation_type(ice::Tus t) noexcept { return t.value > 9999 ? presentation_type(ice::Tms(t)) : 'u'; }
201 static constexpr auto presentation_type(ice::Tns t) noexcept { return t.value > 9999 ? presentation_type(ice::Tus(t)) : 'n'; }
202
203 // 'd' - dynamic, 's' - second, 'm' - millisecond, 'u' - microsecond, 'n' - nanosecond
204 char presentation = 'd';// T::Constant_Precision <= ice::Tms::Constant_Precision ? 's' : 'u';
206
207 template<typename ParseContext>
208 constexpr auto parse(ParseContext& ctx)
209 {
210 auto it = ctx.begin(), end = ctx.end();
211
212 // Parse the presentation format and store it in the formatter:
213 if (it != end && it[0] == '.')
214 {
215 floatingp = it[1] - '0';
216 it += 2;
217 }
218
219 if (it != end && (*it == 'd' || *it == 's' || *it == 'm' || *it == 'u' || *it == 'n')) presentation = *it++;
220
221
222 // Check if reached the end of the range:
223 if (it != end && *it != '}') throw fmt::format_error("invalid format");
224
225 // Return an iterator past the end of the parsed range:
226 return it;
227 }
228
229 template<typename FormatContext>
230 constexpr auto format(ice::TimeType auto value, FormatContext& ctx) const noexcept
231 {
232 char final_presentation = presentation;
233 if (final_presentation == 'd')
234 {
235 final_presentation = presentation_type(value);
236 }
237
238 if (floatingp == 0)
239 {
240 switch(final_presentation)
241 {
242 case 's': return fmt::format_to(ctx.out(), "{:.3f}s", ice::Ts(value).value, floatingp);
243 case 'm': return fmt::format_to(ctx.out(), "{}ms", ice::Tms(value).value);
244 case 'u': return fmt::format_to(ctx.out(), "{}us", ice::Tus(value).value);
245 case 'n':
246 default: return fmt::format_to(ctx.out(), "{}ns", ice::Tns(value).value);
247 }
248 }
249 else
250 {
251 switch(final_presentation)
252 {
253 case 's': return fmt::format_to(ctx.out(), "{:.{}f}s", ice::Ts(value).value, floatingp);
254 case 'm': return fmt::format_to(ctx.out(), "{:.{}f}ms", ice::Tms(value).value * 1.0, floatingp);
255 case 'u': return fmt::format_to(ctx.out(), "{:.{}f}us", ice::Tus(value).value * 1.0, floatingp);
256 case 'n':
257 default: return fmt::format_to(ctx.out(), "{:.{}f}ns", ice::Tns(value).value * 1.0, floatingp);
258 }
259 }
260 }
261};
Definition clock_types.hxx:115
SPDX-License-Identifier: MIT.
Definition array.hxx:12
std::conditional_t< ice::build::Constant_StringID_DebugInfoEnabled, StringID const &, StringID > StringID_Arg
Argument type used to pass ice::StringID values to functions.
Definition stringid.hxx:23
constexpr auto stringid_hash(ice::BaseStringID< HasDebugInfo > val) noexcept -> ice::detail::stringid_type_v3::StringID_Hash
Definition stringid.hxx:183
constexpr auto stringid_hint(ice::BaseStringID< false > val) noexcept -> std::string_view
Definition stringid.hxx:155
std::uint8_t u8
Definition types.hxx:24
static constexpr ice::StringID StringID_Invalid
Definition stringid.hxx:90
static constexpr auto presentation_type(ice::Tus t) noexcept
Definition log_formatters.hxx:200
constexpr auto format(ice::TimeType auto value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:230
ice::u8 floatingp
Definition log_formatters.hxx:205
static constexpr auto presentation_type(ice::Ts t) noexcept
Definition log_formatters.hxx:198
char presentation
Definition log_formatters.hxx:204
static constexpr auto presentation_type(ice::Tns t) noexcept
Definition log_formatters.hxx:201
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:208
static constexpr auto presentation_type(ice::Tms t) noexcept
Definition log_formatters.hxx:199
constexpr auto format(ice::StringID_Arg value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:47
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:41
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:182
constexpr auto format(ice::ErrorCode value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:188
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:18
constexpr auto format(ice::StringID_Hash value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:24
constexpr auto format(ice::isize value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:166
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:71
constexpr auto format(ice::ncount value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:77
char presentation
Definition log_formatters.hxx:86
constexpr auto parse(ParseContext &ctx)
Definition log_formatters.hxx:89
constexpr auto format(ice::usize value, FormatContext &ctx) const noexcept
Definition log_formatters.hxx:103
Definition error.hxx:19
Represents time interval of milliseconds.
Definition clock_types.hxx:38
ValueType value
Definition clock_types.hxx:42
Represents time interval of nanoseconds.
Definition clock_types.hxx:73
ValueType value
Definition clock_types.hxx:77
Represents time interval of seconds.
Definition clock_types.hxx:21
ValueType value
Definition clock_types.hxx:25
Represents time interval of microseconds.
Definition clock_types.hxx:56
ValueType value
Definition clock_types.hxx:60
Internal hash type representing the hashed string value.
Definition stringid.hxx:34
Represents a signed size value on the given platform.
Definition mem_size_types.hxx:14
Definition ncount.hxx:14
Represents a unsigned size value on the given platform.
Definition mem_size_types.hxx:26