libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
format_frontend_binding_float.hpp
1#pragma once
2
6namespace ArgumentResolution
7{
8
15[[nodiscard]] consteval ResolvedField ResolveFloatField(const ParsedField& parsed,
16 ArgumentKind kind)
17{
18 if (parsed.has_precision && parsed.precision > Config::max_float_precision)
19 {
20 return ResolvedField{.error = Error::FloatPrecisionLimitExceeded};
21 }
22
23 char presentation =
24 parsed.presentation == 0 ? DefaultFloatPresentation() : parsed.presentation;
25 if (presentation == 0)
26 {
27 return ResolvedField{.error = Error::ArgumentTypeMismatch};
28 }
29 bool upper_case =
30 presentation == 'F' || presentation == 'E' || presentation == 'G';
31
32 FormatType type = FormatType::End;
33 FormatPackKind pack = FormatPackKind::F32;
34
35 auto pick_type = [&](FormatType f32_type, FormatType f64_type,
36 FormatType ld_type) consteval -> bool {
37 switch (kind)
38 {
39 case ArgumentKind::Float32:
40 type = f32_type;
41 pack = FormatPackKind::F32;
42 return true;
43 case ArgumentKind::Float64:
44 type = Config::enable_float_double ? f64_type : f32_type;
45 pack = Config::enable_float_double ? FormatPackKind::F64 : FormatPackKind::F32;
46 return true;
47 case ArgumentKind::LongDouble:
48 if (!Config::enable_float_long_double)
49 {
50 return false;
51 }
52 type = ld_type;
53 pack = FormatPackKind::LongDouble;
54 return true;
55 default:
56 return false;
57 }
58 };
59
60 switch (presentation)
61 {
62 case 'f':
63 case 'F':
64 if (!Config::enable_float_fixed ||
65 !pick_type(FormatType::FloatFixed, FormatType::DoubleFixed,
66 FormatType::LongDoubleFixed))
67 {
68 return ResolvedField{.error = Error::ArgumentTypeMismatch};
69 }
70 break;
71 case 'e':
72 case 'E':
73 if (!Config::enable_float_scientific ||
74 !pick_type(FormatType::FloatScientific, FormatType::DoubleScientific,
75 FormatType::LongDoubleScientific))
76 {
77 return ResolvedField{.error = Error::ArgumentTypeMismatch};
78 }
79 break;
80 case 'g':
81 case 'G':
82 if (!Config::enable_float_general ||
83 !pick_type(FormatType::FloatGeneral, FormatType::DoubleGeneral,
84 FormatType::LongDoubleGeneral))
85 {
86 return ResolvedField{.error = Error::ArgumentTypeMismatch};
87 }
88 break;
89 default:
90 return ResolvedField{.error = Error::ArgumentTypeMismatch};
91 }
92
93 return ResolvedField{.field = MakeField(parsed, type, pack, upper_case)};
94}
95
102template <typename... Args>
103[[nodiscard]] consteval ResolvedField ResolveField(const ParsedField& parsed)
104{
105 constexpr auto argument_summaries = ClassifyArguments<Args...>();
106 if (parsed.arg_index >= argument_summaries.size())
107 {
108 return ResolvedField{.error = Error::MissingArgument};
109 }
110
111 auto argument = argument_summaries[parsed.arg_index];
112 switch (argument.kind)
113 {
114 case ArgumentKind::Bool:
115 return ResolveBoolField(parsed);
116 case ArgumentKind::Character:
117 return ResolveCharacterField(parsed);
118 case ArgumentKind::Signed:
119 return ResolveIntegerField(parsed, true, argument.uses_64bit_storage);
120 case ArgumentKind::Unsigned:
121 return ResolveIntegerField(parsed, false, argument.uses_64bit_storage);
122 case ArgumentKind::String:
123 return ResolveStringField(parsed);
124 case ArgumentKind::Pointer:
125 return ResolvePointerField(parsed);
126 case ArgumentKind::Float32:
127 case ArgumentKind::Float64:
128 case ArgumentKind::LongDouble:
129 return ResolveFloatField(parsed, argument.kind);
130 case ArgumentKind::Unsupported:
131 default:
132 return ResolvedField{.error = Error::UnsupportedArgumentType};
133 }
134}
135} // namespace ArgumentResolution
brace 前端共享的参数分类与字段形状构造辅助函数 / Shared brace-frontend argument classification and field-shape helpers
consteval ResolvedField ResolveIntegerField(const ParsedField &parsed, bool signed_decimal, bool uses_64bit_storage)
针对整数类参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for an integer-like argument
constexpr FormatField MakeField(const ParsedField &parsed, FormatType type, FormatPackKind pack, bool upper_case=false)
根据 brace 字段属性构造一条共享 FormatField 记录 / Build one shared FormatField record from parsed brace-field prop...
consteval ResolvedField ResolveBoolField(const ParsedField &parsed)
针对 bool 参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for a bool argument
consteval ResolvedField ResolvePointerField(const ParsedField &parsed)
针对指针类参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for a pointer-like argument
consteval auto ClassifyArguments()
为 brace 前端归类整组 C++ 参数类型 / Classify one full C++ argument list for the brace frontend
consteval ResolvedField ResolveField(const ParsedField &parsed)
先判断一个已解析 brace 字段指向哪类参数,再选择匹配的字段构造逻辑 / Check which argument family a parsed brace field points to,...
consteval ResolvedField ResolveCharacterField(const ParsedField &parsed)
针对字符参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for a character argument
consteval ResolvedField ResolveFloatField(const ParsedField &parsed, ArgumentKind kind)
针对 float、double 或 long double 参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for a float,...
consteval ResolvedField ResolveStringField(const ParsedField &parsed)
针对字符串类参数解析一个已解析的 brace 字段 / Resolve one parsed brace field for a string-like argument
constexpr char DefaultFloatPresentation()
在当前功能开关下选择前端默认浮点展示字符 / Choose the frontend default float presentation under current feature gates