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;
100[[nodiscard]]
consteval FormatPackKind SelectPackKind(FormatType type)
104 case FormatType::Signed32:
105 return FormatPackKind::I32;
106 case FormatType::Signed64:
107 return FormatPackKind::I64;
108 case FormatType::Unsigned32:
109 case FormatType::Binary32:
110 case FormatType::Octal32:
111 case FormatType::HexLower32:
112 case FormatType::HexUpper32:
113 return FormatPackKind::U32;
114 case FormatType::Unsigned64:
115 case FormatType::Binary64:
116 case FormatType::Octal64:
117 case FormatType::HexLower64:
118 case FormatType::HexUpper64:
119 return FormatPackKind::U64;
120 case FormatType::Pointer:
121 return FormatPackKind::Pointer;
122 case FormatType::Character:
123 return FormatPackKind::Character;
124 case FormatType::String:
125 return FormatPackKind::StringView;
126 case FormatType::FloatFixed:
127 case FormatType::FloatScientific:
128 case FormatType::FloatGeneral:
129 return FormatPackKind::F32;
130 case FormatType::DoubleFixed:
131 case FormatType::DoubleScientific:
132 case FormatType::DoubleGeneral:
133 return FormatPackKind::F64;
134 case FormatType::LongDoubleFixed:
135 case FormatType::LongDoubleScientific:
136 case FormatType::LongDoubleGeneral:
137 return FormatPackKind::LongDouble;
138 case FormatType::End:
139 case FormatType::TextInline:
140 case FormatType::TextRef:
141 case FormatType::TextSpace:
143 return FormatPackKind::U32;
147 return FormatPackKind::U32;
157[[nodiscard]]
consteval FormatArgumentRule SelectArgumentRule(
160 if (conversion.
type == ValueKind::Signed)
162 return RuleFromTable(signed_rules, conversion.
length);
165 if (IsUnsignedType(conversion.
type))
167 return RuleFromTable(unsigned_rules, conversion.
length);
170 switch (conversion.
type)
172 case ValueKind::Pointer:
173 return FormatArgumentRule::Pointer;
174 case ValueKind::Character:
175 return FormatArgumentRule::Character;
176 case ValueKind::String:
177 return FormatArgumentRule::String;
178 case ValueKind::FloatFixed:
179 case ValueKind::FloatScientific:
180 case ValueKind::FloatGeneral:
181 return (conversion.
length == Length::LongDouble) ? FormatArgumentRule::LongDouble
182 : FormatArgumentRule::Float;
183 case ValueKind::None:
184 case ValueKind::Signed:
185 case ValueKind::Unsigned:
186 case ValueKind::Binary:
187 case ValueKind::Octal:
188 case ValueKind::HexLower:
189 case ValueKind::HexUpper:
193 return FormatArgumentRule::None;
204[[nodiscard]]
consteval Error ValidateConversion(
const Conversion& conversion)
206 if ((conversion.
type == ValueKind::FloatFixed ||
207 conversion.
type == ValueKind::FloatScientific ||
208 conversion.
type == ValueKind::FloatGeneral) &&
211 return Error::FloatPrecisionLimitExceeded;
214 if ((conversion.
type == ValueKind::Signed || IsUnsignedType(conversion.
type)) &&
215 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
216 !Config::enable_integer_64bit)
218 return Error::InvalidLength;
231[[nodiscard]]
consteval FormatField BuildFormatField(
const Conversion& conversion)
233 auto rule = SelectArgumentRule(conversion);
234 auto type = SelectFormatType(conversion, rule);
237 .pack = SelectPackKind(type),
240 .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 / 是否显式提供了精度