8namespace FieldSelection
16[[nodiscard]]
consteval FormatType SelectFormatType(
const Conversion& conversion,
17 FormatArgumentRule rule)
19 if (conversion.
length == Length::LongDouble)
21 if (conversion.
type == ValueKind::FloatFixed)
23 return FormatType::LongDoubleFixed;
25 if (conversion.
type == ValueKind::FloatScientific)
27 return FormatType::LongDoubleScientific;
29 if (conversion.
type == ValueKind::FloatGeneral)
31 return FormatType::LongDoubleGeneral;
35 if (conversion.
type == ValueKind::Signed)
37 return RuleUses64BitStorage(rule) ? FormatType::Signed64 : FormatType::Signed32;
39 if (conversion.
type == ValueKind::Unsigned)
41 return RuleUses64BitStorage(rule) ? FormatType::Unsigned64
42 : FormatType::Unsigned32;
44 if (conversion.
type == ValueKind::Binary)
46 return RuleUses64BitStorage(rule) ? FormatType::Binary64 : FormatType::Binary32;
48 if (conversion.
type == ValueKind::Octal)
50 return RuleUses64BitStorage(rule) ? FormatType::Octal64 : FormatType::Octal32;
52 if (conversion.
type == ValueKind::HexLower)
54 return RuleUses64BitStorage(rule) ? FormatType::HexLower64
55 : FormatType::HexLower32;
57 if (conversion.
type == ValueKind::HexUpper)
59 return RuleUses64BitStorage(rule) ? FormatType::HexUpper64
60 : FormatType::HexUpper32;
63 switch (conversion.
type)
65 case ValueKind::Pointer:
66 return FormatType::Pointer;
67 case ValueKind::Character:
68 return FormatType::Character;
69 case ValueKind::String:
70 return FormatType::String;
71 case ValueKind::FloatFixed:
72 return UsesDoubleFloatStorage() ? FormatType::DoubleFixed
73 : FormatType::FloatFixed;
74 case ValueKind::FloatScientific:
75 return UsesDoubleFloatStorage() ? FormatType::DoubleScientific
76 : FormatType::FloatScientific;
77 case ValueKind::FloatGeneral:
78 return UsesDoubleFloatStorage() ? FormatType::DoubleGeneral
79 : FormatType::FloatGeneral;
81 case ValueKind::Signed:
82 case ValueKind::Unsigned:
83 case ValueKind::Binary:
84 case ValueKind::Octal:
85 case ValueKind::HexLower:
86 case ValueKind::HexUpper:
87 return FormatType::End;
90 return FormatType::End;
99[[nodiscard]]
consteval FormatPackKind SelectPackKind(FormatType type)
103 case FormatType::Signed32:
104 return FormatPackKind::I32;
105 case FormatType::Signed64:
106 return FormatPackKind::I64;
107 case FormatType::Unsigned32:
108 case FormatType::Binary32:
109 case FormatType::Octal32:
110 case FormatType::HexLower32:
111 case FormatType::HexUpper32:
112 return FormatPackKind::U32;
113 case FormatType::Unsigned64:
114 case FormatType::Binary64:
115 case FormatType::Octal64:
116 case FormatType::HexLower64:
117 case FormatType::HexUpper64:
118 return FormatPackKind::U64;
119 case FormatType::Pointer:
120 return FormatPackKind::Pointer;
121 case FormatType::Character:
122 return FormatPackKind::Character;
123 case FormatType::String:
124 return FormatPackKind::StringView;
125 case FormatType::FloatFixed:
126 case FormatType::FloatScientific:
127 case FormatType::FloatGeneral:
128 return FormatPackKind::F32;
129 case FormatType::DoubleFixed:
130 case FormatType::DoubleScientific:
131 case FormatType::DoubleGeneral:
132 return FormatPackKind::F64;
133 case FormatType::LongDoubleFixed:
134 case FormatType::LongDoubleScientific:
135 case FormatType::LongDoubleGeneral:
136 return FormatPackKind::LongDouble;
137 case FormatType::End:
138 case FormatType::TextInline:
139 case FormatType::TextRef:
140 case FormatType::TextSpace:
141 return FormatPackKind::U32;
144 return FormatPackKind::U32;
153[[nodiscard]]
consteval FormatArgumentRule SelectArgumentRule(
const Conversion& conversion)
155 if (conversion.
type == ValueKind::Signed)
157 return RuleFromTable(signed_rules, conversion.
length);
160 if (IsUnsignedType(conversion.
type))
162 return RuleFromTable(unsigned_rules, conversion.
length);
165 switch (conversion.
type)
167 case ValueKind::Pointer:
168 return FormatArgumentRule::Pointer;
169 case ValueKind::Character:
170 return FormatArgumentRule::Character;
171 case ValueKind::String:
172 return FormatArgumentRule::String;
173 case ValueKind::FloatFixed:
174 case ValueKind::FloatScientific:
175 case ValueKind::FloatGeneral:
176 return (conversion.
length == Length::LongDouble)
177 ? FormatArgumentRule::LongDouble
178 : FormatArgumentRule::Float;
179 case ValueKind::None:
180 case ValueKind::Signed:
181 case ValueKind::Unsigned:
182 case ValueKind::Binary:
183 case ValueKind::Octal:
184 case ValueKind::HexLower:
185 case ValueKind::HexUpper:
189 return FormatArgumentRule::None;
199[[nodiscard]]
consteval Error ValidateConversion(
const Conversion& conversion)
201 if ((conversion.
type == ValueKind::FloatFixed ||
202 conversion.
type == ValueKind::FloatScientific ||
203 conversion.
type == ValueKind::FloatGeneral) &&
205 conversion.
precision > Config::max_float_precision)
207 return Error::FloatPrecisionLimitExceeded;
210 if ((conversion.
type == ValueKind::Signed || IsUnsignedType(conversion.
type)) &&
211 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
212 !Config::enable_integer_64bit)
214 return Error::InvalidLength;
226[[nodiscard]]
consteval FormatField BuildFormatField(
const Conversion& conversion)
228 auto rule = SelectArgumentRule(conversion);
229 auto type = SelectFormatType(conversion, rule);
232 .pack = SelectPackKind(type),
235 .width = conversion.
width,
printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
ValueKind type
semantic conversion category / 转换项归一化后的语义类别
constexpr uint8_t FlagsByte() const
将前端解析出的标志位打包成共享的 FormatFlag 字节 / Pack the parsed frontend flags into the shared FormatFlag byte
Length length
parsed length modifier / 已解析的长度修饰符
uint8_t width
parsed field width / 已解析的字段宽度
constexpr uint8_t PrecisionByte() const
返回共享精度字节;若未显式指定精度则为 0xFF / Return the shared precision byte, or 0xFF when precision is absent
uint8_t precision
parsed precision value / 已解析的精度值
bool has_precision
whether precision was explicitly provided / 是否显式提供了精度