libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
literal.hpp
1
13{
17enum class Frontend : uint8_t
18{
19 Auto,
20 Format,
21 Printf,
22};
23
29enum class Resolution : uint8_t
30{
31 None,
32 Format,
33 Printf,
34 Ambiguous,
36};
37
42template <Print::Text Source>
43[[nodiscard]] consteval bool UsesFormatSyntax()
44{
45 for (size_t i = 0; i < Source.Size(); ++i)
46 {
47 if (Source.data[i] == '{' || Source.data[i] == '}')
48 {
49 return true;
50 }
51 }
52 return false;
53}
54
59template <Print::Text Source>
60[[nodiscard]] consteval bool UsesPrintfSyntax()
61{
62 for (size_t i = 0; i < Source.Size(); ++i)
63 {
64 if (Source.data[i] == '%')
65 {
66 return true;
67 }
68 }
69 return false;
70}
71
76template <Print::Text Source>
77[[nodiscard]] consteval bool FormatSourceValid()
78{
79 return Print::Detail::FormatFrontend::Analyze<Source>().error ==
80 Print::Detail::FormatFrontend::Error::None;
81}
82
87template <Print::Text Source>
88[[nodiscard]] consteval bool PrintfSourceValid()
89{
90 return Print::Detail::PrintfCompile::Analyze<Source>().error ==
91 Print::Printf::Error::None;
92}
93
105template <Print::Text Source, typename... Args>
106[[nodiscard]] consteval bool FormatMatches()
107{
108 if constexpr (!FormatSourceValid<Source>())
109 {
110 return false;
111 }
112 else
113 {
114 return LibXR::Format<Source>::template Matches<Args...>();
115 }
116}
117
123template <Print::Text Source, typename... Args>
124[[nodiscard]] consteval bool PrintfMatches()
125{
126 if constexpr (!PrintfSourceValid<Source>())
127 {
128 return false;
129 }
130 else
131 {
132 return Print::Printf::template Matches<Source, Args...>();
133 }
134}
135
141template <Frontend Forced, Print::Text Source, typename... Args>
142[[nodiscard]] consteval Resolution ResolveFrontend()
143{
144 constexpr bool format_match = FormatMatches<Source, Args...>();
145 constexpr bool printf_match = PrintfMatches<Source, Args...>();
146
147 if constexpr (Forced == Frontend::Format)
148 {
149 return format_match ? Resolution::Format : Resolution::None;
150 }
151 else if constexpr (Forced == Frontend::Printf)
152 {
153 return printf_match ? Resolution::Printf : Resolution::None;
154 }
155 else if constexpr (format_match && !printf_match)
156 {
157 return Resolution::Format;
158 }
159 else if constexpr (!format_match && printf_match)
160 {
161 return Resolution::Printf;
162 }
163 else if constexpr (!format_match && !printf_match)
164 {
165 return Resolution::None;
166 }
167 else
168 {
169 constexpr bool format_uses_syntax = UsesFormatSyntax<Source>();
170 constexpr bool printf_uses_syntax = UsesPrintfSyntax<Source>();
171
172 if constexpr (format_uses_syntax && !printf_uses_syntax)
173 {
174 return Resolution::Format;
175 }
176 else if constexpr (!format_uses_syntax && printf_uses_syntax)
177 {
178 return Resolution::Printf;
179 }
180 else if constexpr (!format_uses_syntax && !printf_uses_syntax)
181 {
182 return Resolution::Format;
183 }
184 else
185 {
187 }
188 }
189}
190
196template <Frontend Forced, Print::Text Source, typename... Args>
197[[nodiscard]] consteval Frontend SelectFrontend()
198{
199 constexpr auto resolution = ResolveFrontend<Forced, Source, Args...>();
200
201 if constexpr (Forced == Frontend::Format)
202 {
203 static_assert(
204 resolution == Resolution::Format,
205 "LibXR::Logger: XR_FMT(...) literal is not accepted by the brace frontend");
206 return Frontend::Format;
207 }
208 else if constexpr (Forced == Frontend::Printf)
209 {
210 static_assert(
211 resolution == Resolution::Printf,
212 "LibXR::Logger: XR_PRINTF(...) literal is not accepted by the printf frontend");
213 return Frontend::Printf;
214 }
215 else if constexpr (resolution == Resolution::Format)
216 {
217 return Frontend::Format;
218 }
219 else if constexpr (resolution == Resolution::Printf)
220 {
221 return Frontend::Printf;
222 }
223 else if constexpr (resolution == Resolution::Ambiguous)
224 {
225 static_assert(resolution != Resolution::Ambiguous,
226 "LibXR::Logger: literal is ambiguous between brace and printf "
227 "frontends; use XR_FMT(...) or XR_PRINTF(...)");
228 return Frontend::Auto;
229 }
230 else
231 {
232 static_assert(resolution != Resolution::None,
233 "LibXR::Logger: literal matches neither brace nor printf frontend");
234 return Frontend::Auto;
235 }
236}
237} // namespace Detail::LoggerLiteral
Logger 的字面量前端选择片段 Literal-frontend selection fragment of Logger
Definition literal.hpp:13
consteval bool UsesPrintfSyntax()
判断一条合法 printf 字面量是否真的使用了 printf 语法。 Returns whether one valid printf literal actually uses printf syn...
Definition literal.hpp:60
consteval Resolution ResolveFrontend()
为一条 logger 字面量及一组具体参数选择前端。 Selects the logger frontend for one literal plus one concrete argument lis...
Definition literal.hpp:142
Frontend
Logger 字面量前端选择模式 / Logger literal frontend selection mode.
Definition literal.hpp:18
@ Auto
自动选择 brace 或 printf / select brace or printf automatically
@ Format
强制使用 brace 风格前端 / force brace-style frontend
@ Printf
强制使用 printf 风格前端 / force printf-style frontend
consteval bool FormatSourceValid()
判断一条 brace 风格源串在源级上是否合法。 Returns whether one brace-style source is source-level valid.
Definition literal.hpp:77
consteval bool FormatMatches()
判断一组参数是否能被 brace 前端接受;会先做源级合法性保护。 Returns whether one argument list is accepted by the brace frontend...
Definition literal.hpp:106
consteval bool PrintfMatches()
判断一组参数是否能被 printf 前端接受;会先做源级合法性保护。 Returns whether one argument list is accepted by the printf fronte...
Definition literal.hpp:124
consteval bool UsesFormatSyntax()
判断一条合法 brace 字面量是否真的使用了 brace 语法。 Returns whether one valid brace literal actually uses brace syntax.
Definition literal.hpp:43
Resolution
将一条 logger 字面量与可用前端进行解析后的结果。 Result of resolving one logger literal against the available frontends.
Definition literal.hpp:30
@ Format
选择 brace 风格前端 / select brace-style frontend
@ None
两个前端都不匹配 / matches neither frontend
@ Printf
选择 printf 风格前端 / select printf-style frontend
consteval Frontend SelectFrontend()
在校验解析结果后,选择最终 logger 前端。 Selects the final logger frontend after validating the resolution result.
Definition literal.hpp:197
consteval bool PrintfSourceValid()
判断一条 printf 风格源串在源级上是否合法。 Returns whether one printf-style source is source-level valid.
Definition literal.hpp:88