libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
literal.hpp
1
13{
18enum class Frontend : uint8_t
19{
20 Auto,
21 Format,
22 Printf,
23};
24
30enum class Resolution : uint8_t
31{
32 None,
33 Format,
34 Printf,
35 Ambiguous,
37};
38
43template <Print::Text Source>
44[[nodiscard]] consteval bool UsesFormatSyntax()
45{
46 for (size_t i = 0; i < Source.Size(); ++i)
47 {
48 if (Source.data[i] == '{' || Source.data[i] == '}')
49 {
50 return true;
51 }
52 }
53 return false;
54}
55
60template <Print::Text Source>
61[[nodiscard]] consteval bool UsesPrintfSyntax()
62{
63 for (size_t i = 0; i < Source.Size(); ++i)
64 {
65 if (Source.data[i] == '%')
66 {
67 return true;
68 }
69 }
70 return false;
71}
72
77template <Print::Text Source>
78[[nodiscard]] consteval bool FormatSourceValid()
79{
80 return Print::Detail::FormatFrontend::Analyze<Source>().error ==
81 Print::Detail::FormatFrontend::Error::None;
82}
83
88template <Print::Text Source>
89[[nodiscard]] consteval bool PrintfSourceValid()
90{
91 return Print::Detail::PrintfCompile::Analyze<Source>().error ==
92 Print::Printf::Error::None;
93}
94
106template <Print::Text Source, typename... Args>
107[[nodiscard]] consteval bool FormatMatches()
108{
109 if constexpr (!FormatSourceValid<Source>())
110 {
111 return false;
112 }
113 else
114 {
115 return LibXR::Format<Source>::template Matches<Args...>();
116 }
117}
118
124template <Print::Text Source, typename... Args>
125[[nodiscard]] consteval bool PrintfMatches()
126{
127 if constexpr (!PrintfSourceValid<Source>())
128 {
129 return false;
130 }
131 else
132 {
133 return Print::Printf::template Matches<Source, Args...>();
134 }
135}
136
142template <Frontend Forced, Print::Text Source, typename... Args>
143[[nodiscard]] consteval Resolution ResolveFrontend()
144{
145 constexpr bool format_match = FormatMatches<Source, Args...>();
146 constexpr bool printf_match = PrintfMatches<Source, Args...>();
147
148 if constexpr (Forced == Frontend::Format)
149 {
150 return format_match ? Resolution::Format : Resolution::None;
151 }
152 else if constexpr (Forced == Frontend::Printf)
153 {
154 return printf_match ? Resolution::Printf : Resolution::None;
155 }
156 else if constexpr (format_match && !printf_match)
157 {
158 return Resolution::Format;
159 }
160 else if constexpr (!format_match && printf_match)
161 {
162 return Resolution::Printf;
163 }
164 else if constexpr (!format_match && !printf_match)
165 {
166 return Resolution::None;
167 }
168 else
169 {
170 constexpr bool format_uses_syntax = UsesFormatSyntax<Source>();
171 constexpr bool printf_uses_syntax = UsesPrintfSyntax<Source>();
172
173 if constexpr (format_uses_syntax && !printf_uses_syntax)
174 {
175 return Resolution::Format;
176 }
177 else if constexpr (!format_uses_syntax && printf_uses_syntax)
178 {
179 return Resolution::Printf;
180 }
181 else if constexpr (!format_uses_syntax && !printf_uses_syntax)
182 {
183 return Resolution::Format;
184 }
185 else
186 {
188 }
189 }
190}
191
197template <Frontend Forced, Print::Text Source, typename... Args>
198[[nodiscard]] consteval Frontend SelectFrontend()
199{
200 constexpr auto resolution = ResolveFrontend<Forced, Source, Args...>();
201
202 if constexpr (Forced == Frontend::Format)
203 {
204 static_assert(
205 resolution == Resolution::Format,
206 "LibXR::Logger: XR_FMT(...) literal is not accepted by the brace frontend");
207 return Frontend::Format;
208 }
209 else if constexpr (Forced == Frontend::Printf)
210 {
211 static_assert(
212 resolution == Resolution::Printf,
213 "LibXR::Logger: XR_PRINTF(...) literal is not accepted by the printf frontend");
214 return Frontend::Printf;
215 }
216 else if constexpr (resolution == Resolution::Format)
217 {
218 return Frontend::Format;
219 }
220 else if constexpr (resolution == Resolution::Printf)
221 {
222 return Frontend::Printf;
223 }
224 else if constexpr (resolution == Resolution::Ambiguous)
225 {
226 static_assert(resolution != Resolution::Ambiguous,
227 "LibXR::Logger: literal is ambiguous between brace and printf "
228 "frontends; use XR_FMT(...) or XR_PRINTF(...)");
229 return Frontend::Auto;
230 }
231 else
232 {
233 static_assert(resolution != Resolution::None,
234 "LibXR::Logger: literal matches neither brace nor printf frontend");
235 return Frontend::Auto;
236 }
237}
238} // namespace Detail::LoggerLiteral
Logger 的字面量前端选择片段 Literal-frontend selection fragment of Logger
Definition literal.hpp:13
consteval bool UsesPrintfSyntax()
Returns whether one valid printf literal actually uses printf syntax.
Definition literal.hpp:61
consteval Resolution ResolveFrontend()
Selects the logger frontend for one literal plus one concrete argument list.
Definition literal.hpp:143
Frontend
Logger literal frontend selection mode.
Definition literal.hpp:19
@ Auto
select brace or printf automatically / 自动选择 brace 或 printf
@ Format
force brace-style frontend / 强制使用 brace 风格前端
@ Printf
force printf-style frontend / 强制使用 printf 风格前端
consteval bool FormatSourceValid()
Returns whether one brace-style source is source-level valid.
Definition literal.hpp:78
consteval bool FormatMatches()
Returns whether one argument list is accepted by the brace frontend, guarded by source-level validity...
Definition literal.hpp:107
consteval bool PrintfMatches()
Returns whether one argument list is accepted by the printf frontend, guarded by source-level validit...
Definition literal.hpp:125
consteval bool UsesFormatSyntax()
Returns whether one valid brace literal actually uses brace syntax.
Definition literal.hpp:44
Resolution
Result of resolving one logger literal against the available frontends.
Definition literal.hpp:31
@ Format
select brace-style frontend / 选择 brace 风格前端
@ None
matches neither frontend / 两个前端都不匹配
@ Printf
select printf-style frontend / 选择 printf 风格前端
consteval Frontend SelectFrontend()
Selects the final logger frontend after validating the resolution result.
Definition literal.hpp:198
consteval bool PrintfSourceValid()
Returns whether one printf-style source is source-level valid.
Definition literal.hpp:89