9namespace FieldSelection
20[[nodiscard]]
consteval FormatType SelectFormatType(
const Conversion& conversion,
21 FormatArgumentRule rule)
23 if (conversion.
length == Length::LongDouble)
25 if (conversion.
type == ValueKind::FloatFixed)
27 return FormatType::LongDoubleFixed;
29 if (conversion.
type == ValueKind::FloatScientific)
31 return FormatType::LongDoubleScientific;
33 if (conversion.
type == ValueKind::FloatGeneral)
35 return FormatType::LongDoubleGeneral;
39 if (conversion.
type == ValueKind::Signed)
41 return RuleUses64BitStorage(rule) ? FormatType::Signed64 : FormatType::Signed32;
43 if (conversion.
type == ValueKind::Unsigned)
45 return RuleUses64BitStorage(rule) ? FormatType::Unsigned64 : FormatType::Unsigned32;
47 if (conversion.
type == ValueKind::Binary)
49 return RuleUses64BitStorage(rule) ? FormatType::Binary64 : FormatType::Binary32;
51 if (conversion.
type == ValueKind::Octal)
53 return RuleUses64BitStorage(rule) ? FormatType::Octal64 : FormatType::Octal32;
55 if (conversion.
type == ValueKind::HexLower)
57 return RuleUses64BitStorage(rule) ? FormatType::HexLower64 : FormatType::HexLower32;
59 if (conversion.
type == ValueKind::HexUpper)
61 return RuleUses64BitStorage(rule) ? FormatType::HexUpper64 : FormatType::HexUpper32;
64 switch (conversion.
type)
66 case ValueKind::Pointer:
67 return FormatType::Pointer;
68 case ValueKind::Character:
69 return FormatType::Character;
70 case ValueKind::String:
71 return FormatType::String;
72 case ValueKind::FloatFixed:
73 return UsesDoubleFloatStorage() ? FormatType::DoubleFixed : 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;
98inline void InvalidPackKindType() noexcept {}
107[[nodiscard]]
consteval FormatPackKind SelectPackKind(FormatType type)
111 case FormatType::Signed32:
112 return FormatPackKind::I32;
113 case FormatType::Signed64:
114 return FormatPackKind::I64;
115 case FormatType::Unsigned32:
116 case FormatType::Binary32:
117 case FormatType::Octal32:
118 case FormatType::HexLower32:
119 case FormatType::HexUpper32:
120 return FormatPackKind::U32;
121 case FormatType::Unsigned64:
122 case FormatType::Binary64:
123 case FormatType::Octal64:
124 case FormatType::HexLower64:
125 case FormatType::HexUpper64:
126 return FormatPackKind::U64;
127 case FormatType::Pointer:
128 return FormatPackKind::Pointer;
129 case FormatType::Character:
130 return FormatPackKind::Character;
131 case FormatType::String:
132 return FormatPackKind::StringView;
133 case FormatType::FloatFixed:
134 case FormatType::FloatScientific:
135 case FormatType::FloatGeneral:
136 return FormatPackKind::F32;
137 case FormatType::DoubleFixed:
138 case FormatType::DoubleScientific:
139 case FormatType::DoubleGeneral:
140 return FormatPackKind::F64;
141 case FormatType::LongDoubleFixed:
142 case FormatType::LongDoubleScientific:
143 case FormatType::LongDoubleGeneral:
144 return FormatPackKind::LongDouble;
145 case FormatType::End:
146 case FormatType::TextInline:
147 case FormatType::TextRef:
148 case FormatType::TextSpace:
149 InvalidPackKindType();
150 return FormatPackKind::U32;
153 InvalidPackKindType();
154 return FormatPackKind::U32;
164[[nodiscard]]
consteval FormatArgumentRule SelectArgumentRule(
167 if (conversion.
type == ValueKind::Signed)
169 return RuleFromTable(signed_rules, conversion.
length);
172 if (IsUnsignedType(conversion.
type))
174 return RuleFromTable(unsigned_rules, conversion.
length);
177 switch (conversion.
type)
179 case ValueKind::Pointer:
180 return FormatArgumentRule::Pointer;
181 case ValueKind::Character:
182 return FormatArgumentRule::Character;
183 case ValueKind::String:
184 return FormatArgumentRule::String;
185 case ValueKind::FloatFixed:
186 case ValueKind::FloatScientific:
187 case ValueKind::FloatGeneral:
188 return (conversion.
length == Length::LongDouble) ? FormatArgumentRule::LongDouble
189 : FormatArgumentRule::Float;
190 case ValueKind::None:
191 case ValueKind::Signed:
192 case ValueKind::Unsigned:
193 case ValueKind::Binary:
194 case ValueKind::Octal:
195 case ValueKind::HexLower:
196 case ValueKind::HexUpper:
200 return FormatArgumentRule::None;
211[[nodiscard]]
consteval Error ValidateConversion(
const Conversion& conversion)
213 if ((conversion.
type == ValueKind::FloatFixed ||
214 conversion.
type == ValueKind::FloatScientific ||
215 conversion.
type == ValueKind::FloatGeneral) &&
218 return Error::FloatPrecisionLimitExceeded;
221 if ((conversion.
type == ValueKind::Signed || IsUnsignedType(conversion.
type)) &&
222 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
223 !Config::enable_integer_64bit)
225 return Error::InvalidLength;
238[[nodiscard]]
consteval FormatField BuildFormatField(
const Conversion& conversion)
240 auto rule = SelectArgumentRule(conversion);
241 auto type = SelectFormatType(conversion, rule);
244 .pack = SelectPackKind(type),
247 .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