libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <type_traits>
6
7#include "format_argument.hpp"
8
9namespace LibXR::Print
10{
15template <size_t N>
16struct Text
17{
19 char data[N]{};
20
25 constexpr Text(const char (&text)[N])
26 {
27 for (size_t i = 0; i < N; ++i)
28 {
29 data[i] = text[i];
30 }
31 }
32
34 [[nodiscard]] constexpr size_t Size() const { return N - 1; }
36 [[nodiscard]] constexpr const char* Data() const { return data; }
37};
38
43class Printf
44{
45 public:
50 enum class Length : uint8_t
51 {
52 Default,
53 Char,
54 Short,
55 Long,
56 LongLong,
57 IntMax,
58 Size,
59 PtrDiff,
61 };
62
83
84 template <Text Source>
85 class Compiler;
86
87 template <Text Source>
88 struct Compiled;
89
94 template <Text Source>
95 [[nodiscard]] static consteval Compiled<Source> Build()
96 {
97 return {};
98 }
99
104 template <Text Source, typename... Args>
105 [[nodiscard]] static consteval bool Matches()
106 {
107 return Compiled<Source>::template Matches<Args...>();
108 }
109};
110} // namespace LibXR::Print
111
112#include "printf_frontend_detail.hpp"
113namespace LibXR::Print
114{
115template <Text Source>
117{
118 private:
119 using Frontend = typename Printf::template Compiler<Source>;
120 inline static constexpr auto source_analysis = Detail::PrintfCompile::Analyze<Source>();
121 inline static constexpr auto result = FormatCompiler<Frontend>::Compile();
122
123 static_assert(result.compile_error != Printf::Error::NumberOverflow,
124 "LibXR::Print::Printf: numeric field is too large");
125 static_assert(result.compile_error != Printf::Error::UnexpectedEnd,
126 "LibXR::Print::Printf: unexpected end of format string");
127 static_assert(result.compile_error != Printf::Error::EmbeddedNul,
128 "LibXR::Print::Printf: embedded NUL bytes are not supported in the format literal");
129 static_assert(result.compile_error != Printf::Error::MixedIndexing,
130 "LibXR::Print::Printf: positional and sequential arguments cannot be mixed");
131 static_assert(result.compile_error != Printf::Error::PositionalArgumentDisabled,
132 "LibXR::Print::Printf: positional argument indexing is disabled in the current profile");
133 static_assert(result.compile_error != Printf::Error::DynamicField,
134 "LibXR::Print::Printf: dynamic width and precision are not supported");
135 static_assert(result.compile_error != Printf::Error::InvalidArgumentIndex,
136 "LibXR::Print::Printf: invalid positional argument index");
137 static_assert(result.compile_error != Printf::Error::InvalidSpecifier,
138 "LibXR::Print::Printf: invalid format specifier");
139 static_assert(result.compile_error != Printf::Error::InvalidLength,
140 "LibXR::Print::Printf: invalid length modifier");
141 static_assert(result.compile_error != Printf::Error::ConflictingArgument,
142 "LibXR::Print::Printf: one positional argument is reused with incompatible conversions");
143 static_assert(result.compile_error != Printf::Error::TextOffsetOverflow,
144 "LibXR::Print::Printf: text pool offset is too large");
145 static_assert(result.compile_error != Printf::Error::TextSizeOverflow,
146 "LibXR::Print::Printf: text span is too large");
147 static_assert(source_analysis.error != Printf::Error::ConflictingArgument,
148 "LibXR::Print::Printf: one positional argument is reused with incompatible conversions");
149
150 public:
152 inline static constexpr auto codes = result.codes;
154 inline static constexpr FormatProfile profile = result.profile;
155
157 [[nodiscard]] static constexpr auto ArgumentList()
158 {
159 return result.arg_info;
160 }
161
163 [[nodiscard]] static constexpr auto ArgumentOrder()
164 {
165 return source_analysis.order;
166 }
167
169 [[nodiscard]] static constexpr auto SourceArgumentList()
170 {
171 return source_analysis.args;
172 }
173
175 [[nodiscard]] static constexpr const auto& Codes()
176 {
177 return codes;
178 }
179
181 [[nodiscard]] static constexpr FormatProfile Profile()
182 {
183 return profile;
184 }
185
187 template <typename... Args>
188 [[nodiscard]] static consteval bool Matches()
189 {
190 return Detail::FormatArgument::template Matches<Args...>(SourceArgumentList());
191 }
192};
193} // namespace LibXR::Print
static consteval auto Compile()
Compiles the frontend into one final compiled format.
Compile-time printf frontend that parses and lowers one source string.
Printf-style frontend that emits the internal format representation.
Definition printf.hpp:44
Length
Supported printf length modifiers after normalization.
Definition printf.hpp:51
@ LongLong
ll / long long 长度修饰
@ IntMax
j / intmax_t 长度修饰
@ PtrDiff
t / ptrdiff_t 长度修饰
@ Short
h / short 长度修饰
@ Size
z / size_t 长度修饰
@ LongDouble
L / long double 长度修饰
@ Default
no length modifier / 无长度修饰符
@ Long
l / long 长度修饰
@ Char
hh / char 长度修饰
Error
Compile-time parse/build failure categories surfaced through static_assert.
Definition printf.hpp:68
@ TextOffsetOverflow
referenced text offset no longer fits in uint16_t / 文本池偏移超出 uint16_t
@ UnexpectedEnd
format string ended in the middle of one conversion / 格式串在转换项中途结束
@ TextSizeOverflow
referenced text size no longer fits in uint16_t / 文本长度超出 uint16_t
@ InvalidArgumentIndex
positional argument index is invalid / 位置参数索引非法
@ NumberOverflow
width / precision literal does not fit in its field / 宽度或精度字面量超出字段范围
@ None
success / 成功
@ MixedIndexing
positional and sequential arguments were mixed / 混用了位置参数与顺序参数
@ InvalidLength
length modifier is incompatible with the conversion / 长度修饰符与转换说明不兼容
@ EmbeddedNul
format literal contains an embedded NUL byte / 格式串字面量内部包含嵌入式 NUL 字节
@ InvalidSpecifier
unsupported or disabled conversion specifier / 转换说明符无效或被禁用
@ PositionalArgumentDisabled
positional n$ indexing is disabled by configuration / 位置参数 n$ 索引已被配置关闭
@ ConflictingArgument
one positional argument was reused with incompatible rules / 同一位置参数被不兼容的规则重复使用
static consteval Compiled< Source > Build()
Parses and validates a printf format at compile time.
Definition printf.hpp:95
static consteval bool Matches()
Returns true when Args... exactly match the enabled conversions.
Definition printf.hpp:105
static consteval bool Matches()
Returns true when Args... exactly match this compiled format. / 判断 Args... 是否与当前编译格式完全匹配
Definition printf.hpp:188
static constexpr auto codes
Final runtime byte block kept by the compiled surface. / 编译格式表面保留的最终运行期字节块
Definition printf.hpp:152
static constexpr FormatProfile Profile()
Returns the compile-time executor profile. / 返回编译期执行器配置
Definition printf.hpp:181
static constexpr auto ArgumentOrder()
Field-ordered source argument references, including duplicates and reordering. / 按字段顺序排列的源参数引用,可包含重复与...
Definition printf.hpp:163
static constexpr FormatProfile profile
Compile-time executor profile used to specialize the runtime bytecode interpreter....
Definition printf.hpp:154
static constexpr auto SourceArgumentList()
Source-ordered argument metadata used only by compile-time type matching. / 按源参数顺序排列、仅供编译期类型匹配使用的元信息
Definition printf.hpp:169
static constexpr auto ArgumentList()
Field-ordered argument metadata used by runtime argument packing. / 按字段顺序排列、供运行期参数打包使用的元信息表
Definition printf.hpp:157
static constexpr const auto & Codes()
Final compiled bytes consumed directly by the runtime writer. / 供运行期 writer 直接消费的最终编译字节块
Definition printf.hpp:175
Structural literal wrapper used as the NTTP source for printf formats.
Definition printf.hpp:17
char data[N]
Literal bytes including the terminating zero byte. / 含结尾零字节的字面量字节序列
Definition printf.hpp:19
constexpr Text(const char(&text)[N])
Copies the string literal into the structural NTTP object.
Definition printf.hpp:25
constexpr const char * Data() const
Returns the literal bytes including the terminating zero byte. / 返回含结尾零字节的字面量指针
Definition printf.hpp:36
constexpr size_t Size() const
Returns the format length without the terminating zero byte. / 返回不含结尾零字节的格式串长度
Definition printf.hpp:34