15template <OutputSink Sink>
16template <std::
signed_
integral Int>
34#if LIBXR_PRINT_ENABLE_FLOAT
43template <OutputSink Sink>
47 if (std::isnan(value))
53 return spec.ForceSign() ?
'+' : spec.SpaceSign() ?
' ' :
'\0';
55 if (std::signbit(value))
79template <OutputSink Sink>
80template <std::
signed_
integral Int>
83 using UInt = std::make_unsigned_t<Int>;
84 char digit_buffer[UnsignedDigitCapacity<UInt, 10>()];
85 UInt bits =
static_cast<UInt
>(value);
86 UInt magnitude = (value < 0) ? (UInt{0} - bits) : bits;
87 size_t digit_count = AppendUnsigned<10>(digit_buffer, magnitude);
89 std::string_view digits(digit_buffer, digit_count);
90 if (value == 0 && spec.precision == 0)
95 return WriteIntegerField(ResolveSignChar(value, spec), {}, digits, spec);
112template <OutputSink Sink>
113template <uint8_t Base,
bool UpperCase,
bool PrependOctalZero,
114 std::unsigned_integral UInt>
116 const Spec& spec, UInt value)
118 char digit_buffer[UnsignedDigitCapacity<UInt, Base>() + (PrependOctalZero ? 1U : 0U)];
119 size_t digit_count = AppendUnsigned<Base, UpperCase>(digit_buffer, value);
121 if constexpr (PrependOctalZero)
123 digit_count = ApplyAlternateOctal(digit_buffer, digit_count, spec, value);
125 else if (value == 0 && spec.precision == 0)
130 return WriteIntegerField(
'\0', prefix, std::string_view(digit_buffer, digit_count),
148template <OutputSink Sink>
149template <FormatType Type, std::
unsigned_
integral UInt>
152 auto prefix = IntegerPrefix(Type, spec, value);
154 if constexpr (Type == FormatType::Unsigned32 || Type == FormatType::Unsigned64)
156 return WriteUnsignedDigits<10>(prefix, spec, value);
158 if constexpr (Type == FormatType::Binary32 || Type == FormatType::Binary64)
160 return WriteUnsignedDigits<2>(prefix, spec, value);
162 if constexpr (Type == FormatType::Octal32 || Type == FormatType::Octal64)
164 return WriteUnsignedDigits<8, false, true>(prefix, spec, value);
166 if constexpr (Type == FormatType::HexLower32 || Type == FormatType::HexLower64)
168 return WriteUnsignedDigits<16>(prefix, spec, value);
170 if constexpr (Type == FormatType::HexUpper32 || Type == FormatType::HexUpper64)
172 return WriteUnsignedDigits<16, true>(prefix, spec, value);
175 return ErrorCode::ARG_ERR;
185template <OutputSink Sink>
188 char digit_buffer[UnsignedDigitCapacity<uintptr_t, 16>()];
189 size_t digit_count = AppendUnsigned<16>(digit_buffer, value);
192 if (!actual.HasPrecision() || actual.precision == 0)
194 actual.precision = 1;
197 return WriteIntegerField(
'\0',
"0x", std::string_view(digit_buffer, digit_count),
207template <OutputSink Sink>
210 return WriteTextField(std::string_view(&ch, 1), spec);
220template <OutputSink Sink>
224 if (spec.HasPrecision() && spec.precision < view.size())
226 view = view.substr(0, spec.precision);
229 return WriteTextField(view, spec);
241#if LIBXR_PRINT_ENABLE_FLOAT
242template <OutputSink Sink>
246 if (!UsesFloatTextBackend(type))
248 return ErrorCode::ARG_ERR;
252 if (!std::isfinite(value))
254 actual.flags &=
static_cast<uint8_t
>(~static_cast<uint8_t>(FormatFlag::ZeroPad));
257 char sign_char = ResolveFloatSignChar(value, actual);
258 T magnitude = std::signbit(value) ? -
static_cast<T
>(value) : static_cast<T>(value);
259 uint8_t precision = actual.HasPrecision() ? actual.precision : DefaultFloatPrecision();
260 if (type == FormatType::FloatFixed || type == FormatType::DoubleFixed ||
261 type == FormatType::LongDoubleFixed)
263 if (ExceedsFixedIntegerDigits(magnitude, precision))
265 return ErrorCode::OUT_OF_RANGE;
268 else if (type == FormatType::FloatGeneral || type == FormatType::DoubleGeneral ||
269 type == FormatType::LongDoubleGeneral)
271 uint8_t significant = precision == 0 ? 1 : precision;
273 RoundScientificDigits(magnitude,
static_cast<uint8_t
>(significant - 1)).exponent;
274 if (!(exponent < -4 || exponent >= significant))
276 int fractional_precision =
static_cast<int>(significant) - (exponent + 1);
277 if (fractional_precision < 0)
279 fractional_precision = 0;
281 if (ExceedsFixedIntegerDigits(magnitude,
282 static_cast<uint8_t
>(fractional_precision)))
284 return ErrorCode::OUT_OF_RANGE;
288 char output_buffer[float_buffer_capacity];
289 size_t output_size = 0;
290 if (!FormatFloatText(type, actual, magnitude, output_buffer, output_size))
292 return ErrorCode::NO_BUFF;
295 return WriteFloatField(sign_char, std::string_view(output_buffer, output_size), actual);
305template <OutputSink Sink>
308 char digit_buffer[UnsignedDigitCapacity<uint32_t, 10>()];
309 size_t digit_count = AppendUnsigned<10>(digit_buffer, value);
310 return WriteRaw(std::string_view(digit_buffer, digit_count));
319template <OutputSink Sink>
322 using UInt = std::make_unsigned_t<int32_t>;
323 char digit_buffer[UnsignedDigitCapacity<UInt, 10>()];
324 UInt bits =
static_cast<UInt
>(value);
325 UInt magnitude = (value < 0) ? (UInt{0} - bits) : bits;
326 size_t digit_count = AppendUnsigned<10>(digit_buffer, magnitude);
330 if (
auto ec = WriteRaw(
"-"); ec != ErrorCode::OK)
336 return WriteRaw(std::string_view(digit_buffer, digit_count));
347template <OutputSink Sink>
348template <u
int8_t Base,
bool UpperCase>
351 char digit_buffer[UnsignedDigitCapacity<uint32_t, Base>()];
352 size_t digit_count = AppendUnsigned<Base, UpperCase>(digit_buffer, value);
353 return WriteRaw(std::string_view(digit_buffer, digit_count));
363template <OutputSink Sink>
366 char digit_buffer[UnsignedDigitCapacity<uint32_t, 10>()];
367 size_t digit_count = AppendUnsigned<10>(digit_buffer, value);
368 size_t zeros = FieldPadding(width, digit_count);
369 if (
auto ec = WritePadding(
'0', zeros); ec != ErrorCode::OK)
373 return WriteRaw(std::string_view(digit_buffer, digit_count));
381template <OutputSink Sink>
384 return WriteRaw(text);
392template <OutputSink Sink>
395 return WriteRaw(std::string_view(&ch, 1));
按输出端共享重后端、按调用点 profile 裁剪操作码分发的字节码执行器 / Per-sink bytecode executor with shared heavy backends and per...
ErrorCode WriteI32Dec(int32_t value)
单个原始 int32_t 十进制字段的快路径。 / Fast path for one raw int32_t decimal field.
ErrorCode WriteUnsignedDigits(std::string_view prefix, const Spec &spec, UInt value)
按编译期进制/大小写/八进制备用格式参数复用无符号数字载荷写出逻辑 / Reuse the unsigned-digit payload writer with compile-time radix,...
static char ResolveSignChar(Int value, const Spec &spec)
执行器的具体运行期数值写出函数 / Concrete runtime value writers for the executor
ErrorCode WriteStringRaw(std::string_view text)
单个原始字符串参数的快路径。 / Fast path for one raw string argument.
ErrorCode WriteU32Base(uint32_t value)
单个原始 uint32_t 非十进制字段的快路径。 / Fast path for one raw uint32_t non-decimal field.
ErrorCode WritePointer(const Spec &spec, uintptr_t value)
按规范指针字段策略写出一个指针值 / Write one pointer value using the canonical pointer field policy
ErrorCode WriteString(const Spec &spec, std::string_view text)
写出一个字符串字段值,并在需要时应用精度截断 / Write one string field value, including precision truncation when present
ErrorCode DispatchUnsigned(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.
ErrorCode WriteCharacterRaw(char ch)
单个原始字符参数的快路径。 / Fast path for one raw character argument.
ErrorCode WriteCharacter(const Spec &spec, char ch)
写出一个字符字段值 / Write one character field value
ErrorCode WriteSigned(const Spec &spec, Int value)
通过共享整数字段路径写出一个有符号整数值 / Write one signed integer value through the shared integer-field path
ErrorCode WriteU32ZeroPadWidth(uint8_t width, uint32_t value)
单个零填充 uint32_t 十进制字段的快路径。 / Fast path for one zero-padded uint32_t decimal field.