libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
writer_executor_value.hpp
1#pragma once
2
14template <OutputSink Sink, FormatProfile Profile>
15template <std::signed_integral Int>
16char Writer::Executor<Sink, Profile>::ResolveSignChar(Int value, const Spec& spec)
17{
18 if (value < 0)
19 {
20 return '-';
21 }
22 if (spec.ForceSign())
23 {
24 return '+';
25 }
26 if (spec.SpaceSign())
27 {
28 return ' ';
29 }
30 return '\0';
31}
32
40template <OutputSink Sink, FormatProfile Profile>
41template <typename T>
43{
44 if (std::signbit(value))
45 {
46 return '-';
47 }
48 if (spec.ForceSign())
49 {
50 return '+';
51 }
52 if (spec.SpaceSign())
53 {
54 return ' ';
55 }
56 return '\0';
57}
58
66template <OutputSink Sink, FormatProfile Profile>
67template <std::signed_integral Int>
68ErrorCode Writer::Executor<Sink, Profile>::WriteSigned(const Spec& spec, Int value)
69{
70 using UInt = std::make_unsigned_t<Int>;
71 char digit_buffer[UnsignedDigitCapacity<UInt, 10>()];
72 UInt bits = static_cast<UInt>(value);
73 UInt magnitude = (value < 0) ? (UInt{0} - bits) : bits;
74 size_t digit_count = AppendUnsigned<10>(digit_buffer, magnitude);
75
76 std::string_view digits(digit_buffer, digit_count);
77 if (value == 0 && spec.precision == 0)
78 {
79 digits = {};
80 }
81
82 return WriteIntegerField(ResolveSignChar(value, spec), {}, digits, spec);
83}
84
96template <OutputSink Sink, FormatProfile Profile>
97template <uint8_t Base, bool UpperCase, bool InlineAlternateOctal,
98 std::unsigned_integral UInt>
100 const Spec& spec,
101 UInt value)
102{
103 char digit_buffer[UnsignedDigitCapacity<UInt, Base>() +
104 (InlineAlternateOctal ? 1U : 0U)];
105 size_t digit_count = AppendUnsigned<Base, UpperCase>(digit_buffer, value);
106
107 if constexpr (InlineAlternateOctal)
108 {
109 digit_count = ApplyAlternateOctal(digit_buffer, digit_count, spec, value);
110 }
111 else if (value == 0 && spec.precision == 0)
112 {
113 digit_count = 0;
114 }
115
116 return WriteIntegerField('\0', prefix, std::string_view(digit_buffer, digit_count),
117 spec);
118}
119
133template <OutputSink Sink, FormatProfile Profile>
134template <FormatType Type, std::unsigned_integral UInt>
135ErrorCode Writer::Executor<Sink, Profile>::WriteUnsigned(const Spec& spec, UInt value)
136{
137 auto prefix = IntegerPrefix(Type, spec, value);
138
139 if constexpr (Type == FormatType::Unsigned32 || Type == FormatType::Unsigned64)
140 {
141 return WriteUnsignedDigits<10>(prefix, spec, value);
142 }
143 if constexpr (Type == FormatType::Binary32 || Type == FormatType::Binary64)
144 {
145 return WriteUnsignedDigits<2>(prefix, spec, value);
146 }
147 if constexpr (Type == FormatType::Octal32 || Type == FormatType::Octal64)
148 {
149 return WriteUnsignedDigits<8, false, true>(prefix, spec, value);
150 }
151 if constexpr (Type == FormatType::HexLower32 || Type == FormatType::HexLower64)
152 {
153 return WriteUnsignedDigits<16>(prefix, spec, value);
154 }
155 if constexpr (Type == FormatType::HexUpper32 || Type == FormatType::HexUpper64)
156 {
157 return WriteUnsignedDigits<16, true>(prefix, spec, value);
158 }
159
160 return ErrorCode::ARG_ERR;
161}
162
169template <OutputSink Sink, FormatProfile Profile>
171 uintptr_t value)
172{
173 char digit_buffer[UnsignedDigitCapacity<uintptr_t, 16>()];
174 size_t digit_count = AppendUnsigned<16>(digit_buffer, value);
175 Spec actual = spec;
176
177 if (!actual.HasPrecision() || actual.precision == 0)
178 {
179 actual.precision = 1;
180 }
181
182 return WriteIntegerField('\0', "0x", std::string_view(digit_buffer, digit_count),
183 actual);
184}
185
192template <OutputSink Sink, FormatProfile Profile>
193ErrorCode Writer::Executor<Sink, Profile>::WriteCharacter(const Spec& spec, char ch)
194{
195 return WriteTextField(std::string_view(&ch, 1), spec);
196}
197
204template <OutputSink Sink, FormatProfile Profile>
206 std::string_view text)
207{
208 auto view = text;
209 if (spec.HasPrecision() && spec.precision < view.size())
210 {
211 view = view.substr(0, spec.precision);
212 }
213
214 return WriteTextField(view, spec);
215}
216
225template <OutputSink Sink, FormatProfile Profile>
226template <typename T>
228 const Spec& spec, T value)
229{
230 if (!UsesFloatTextBackend(type))
231 {
232 return ErrorCode::ARG_ERR;
233 }
234
235 char sign_char = ResolveFloatSignChar(value, spec);
236 T magnitude = std::signbit(value) ? -static_cast<T>(value) : static_cast<T>(value);
237 uint8_t precision = spec.HasPrecision() ? spec.precision : DefaultFloatPrecision();
238 if (type == FormatType::FloatFixed || type == FormatType::DoubleFixed ||
239 type == FormatType::LongDoubleFixed)
240 {
241 if (ExceedsFixedIntegerDigits(magnitude, precision))
242 {
243 return ErrorCode::OUT_OF_RANGE;
244 }
245 }
246 else if (type == FormatType::FloatGeneral || type == FormatType::DoubleGeneral ||
247 type == FormatType::LongDoubleGeneral)
248 {
249 uint8_t significant = precision == 0 ? 1 : precision;
250 int exponent = (magnitude == 0) ? 0 : NormalizeDecimal(magnitude).exponent;
251 if (!(exponent < -4 || exponent >= significant))
252 {
253 int fractional_precision = static_cast<int>(significant) - (exponent + 1);
254 if (fractional_precision < 0)
255 {
256 fractional_precision = 0;
257 }
258 if (ExceedsFixedIntegerDigits(magnitude,
259 static_cast<uint8_t>(fractional_precision)))
260 {
261 return ErrorCode::OUT_OF_RANGE;
262 }
263 }
264 }
265 char output_buffer[float_buffer_capacity];
266 size_t output_size = 0;
267 if (!FormatFloatText(type, spec, magnitude, output_buffer, output_size))
268 {
269 return ErrorCode::NO_BUFF;
270 }
271
272 return WriteFloatField(sign_char, std::string_view(output_buffer, output_size), spec);
273}
274
280template <OutputSink Sink, FormatProfile Profile>
282{
283 char digit_buffer[UnsignedDigitCapacity<uint32_t, 10>()];
284 size_t digit_count = AppendUnsigned<10>(digit_buffer, value);
285 return WriteRaw(std::string_view(digit_buffer, digit_count));
286}
287
294template <OutputSink Sink, FormatProfile Profile>
296 uint32_t value)
297{
298 char digit_buffer[UnsignedDigitCapacity<uint32_t, 10>()];
299 size_t digit_count = AppendUnsigned<10>(digit_buffer, value);
300 size_t zeros = FieldPadding(width, digit_count);
301 if (auto ec = WritePadding('0', zeros); ec != ErrorCode::OK)
302 {
303 return ec;
304 }
305 return WriteRaw(std::string_view(digit_buffer, digit_count));
306}
307
313template <OutputSink Sink, FormatProfile Profile>
315{
316 return WriteRaw(text);
317}
318
325template <OutputSink Sink, FormatProfile Profile>
327 float value)
328{
329 char sign_char = std::signbit(value) ? '-' : '\0';
330 float magnitude = std::signbit(value) ? -value : value;
331 if (ExceedsFixedIntegerDigits(magnitude, precision))
332 {
333 return ErrorCode::OUT_OF_RANGE;
334 }
335 char output_buffer[float_buffer_capacity];
336 size_t output_size = 0;
337 if (!FormatF32FixedPrecText(magnitude, precision, output_buffer, output_size))
338 {
339 return ErrorCode::NO_BUFF;
340 }
341
342 if (sign_char != '\0')
343 {
344 if (auto ec = WriteRaw(std::string_view(&sign_char, 1)); ec != ErrorCode::OK)
345 {
346 return ec;
347 }
348 }
349
350 return WriteRaw(std::string_view(output_buffer, output_size));
351}
352
359template <OutputSink Sink, FormatProfile Profile>
361 double value)
362{
363 return WriteFloat(FormatType::DoubleFixed, Spec{.precision = precision}, value);
364}
ErrorCode WriteF64FixedPrec(uint8_t precision, double value)
单个带显式精度的定点 double 快路径。 / Fast path for one fixed double with explicit precision.
ErrorCode WriteSigned(const Spec &spec, Int value)
通过共享整数字段路径写出一个有符号整数值 / Write one signed integer value through the shared integer-field path
ErrorCode WriteString(const Spec &spec, std::string_view text)
写出一个字符串字段值,并在需要时应用精度截断 / Write one string field value, including precision truncation when present
static char ResolveFloatSignChar(T value, const Spec &spec)
为一个浮点载荷确定最终可见的符号字符 / Resolve the visible sign character for one float payload
static char ResolveSignChar(Int value, const Spec &spec)
执行器的具体运行期数值写出函数 / Concrete runtime value writers for the executor
ErrorCode WriteUnsignedDigits(std::string_view prefix, const Spec &spec, UInt value)
按编译期进制/大小写/八进制备用格式参数复用无符号数字载荷写出逻辑 / Reuse the unsigned-digit payload writer with compile-time radix,...
ErrorCode WriteU32ZeroPadWidth(uint8_t width, uint32_t value)
单个零填充 uint32_t 十进制字段的快路径。 / Fast path for one zero-padded uint32_t decimal field.
ErrorCode WriteF32FixedPrec(uint8_t precision, float value)
单个带显式精度的定点 float 快路径。 / Fast path for one fixed float with explicit precision.
ErrorCode WriteStringRaw(std::string_view text)
单个原始字符串参数的快路径。 / Fast path for one raw string argument.
ErrorCode WriteFloat(FormatType type, const Spec &spec, T value)
通过共享浮点文本后端写出一个浮点语义值 / Write one float semantic value through the shared float-text backend
ErrorCode WriteCharacter(const Spec &spec, char ch)
写出一个字符字段值 / Write one character field value
ErrorCode WritePointer(const Spec &spec, uintptr_t value)
按规范指针字段策略写出一个指针值 / Write one pointer value using the canonical pointer field policy
ErrorCode WriteUnsigned(const Spec &spec, UInt value)
通过共享整数字段路径写出一个无符号整数语义值 / Write one unsigned integer semantic value through the shared integer-field p...
ErrorCode WriteU32Dec(uint32_t value)
单个原始 uint32_t 十进制字段的快路径。 / Fast path for one raw uint32_t decimal field.