14template <OutputSink Sink, FormatProfile Profile>
15template <std::
signed_
integral Int>
40template <OutputSink Sink, FormatProfile Profile>
44 if (std::signbit(value))
66template <OutputSink Sink, FormatProfile Profile>
67template <std::
signed_
integral Int>
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);
76 std::string_view digits(digit_buffer, digit_count);
77 if (value == 0 && spec.precision == 0)
82 return WriteIntegerField(ResolveSignChar(value, spec), {}, digits, spec);
96template <OutputSink Sink, FormatProfile Profile>
97template <uint8_t Base,
bool UpperCase,
bool InlineAlternateOctal,
98 std::unsigned_integral UInt>
103 char digit_buffer[UnsignedDigitCapacity<UInt, Base>() +
104 (InlineAlternateOctal ? 1U : 0U)];
105 size_t digit_count = AppendUnsigned<Base, UpperCase>(digit_buffer, value);
107 if constexpr (InlineAlternateOctal)
109 digit_count = ApplyAlternateOctal(digit_buffer, digit_count, spec, value);
111 else if (value == 0 && spec.precision == 0)
116 return WriteIntegerField(
'\0', prefix, std::string_view(digit_buffer, digit_count),
133template <OutputSink Sink, FormatProfile Profile>
134template <FormatType Type, std::
unsigned_
integral UInt>
137 auto prefix = IntegerPrefix(Type, spec, value);
139 if constexpr (Type == FormatType::Unsigned32 || Type == FormatType::Unsigned64)
141 return WriteUnsignedDigits<10>(prefix, spec, value);
143 if constexpr (Type == FormatType::Binary32 || Type == FormatType::Binary64)
145 return WriteUnsignedDigits<2>(prefix, spec, value);
147 if constexpr (Type == FormatType::Octal32 || Type == FormatType::Octal64)
149 return WriteUnsignedDigits<8, false, true>(prefix, spec, value);
151 if constexpr (Type == FormatType::HexLower32 || Type == FormatType::HexLower64)
153 return WriteUnsignedDigits<16>(prefix, spec, value);
155 if constexpr (Type == FormatType::HexUpper32 || Type == FormatType::HexUpper64)
157 return WriteUnsignedDigits<16, true>(prefix, spec, value);
160 return ErrorCode::ARG_ERR;
169template <OutputSink Sink, FormatProfile Profile>
173 char digit_buffer[UnsignedDigitCapacity<uintptr_t, 16>()];
174 size_t digit_count = AppendUnsigned<16>(digit_buffer, value);
177 if (!actual.HasPrecision() || actual.precision == 0)
179 actual.precision = 1;
182 return WriteIntegerField(
'\0',
"0x", std::string_view(digit_buffer, digit_count),
192template <OutputSink Sink, FormatProfile Profile>
195 return WriteTextField(std::string_view(&ch, 1), spec);
204template <OutputSink Sink, FormatProfile Profile>
206 std::string_view text)
209 if (spec.HasPrecision() && spec.precision < view.size())
211 view = view.substr(0, spec.precision);
214 return WriteTextField(view, spec);
225template <OutputSink Sink, FormatProfile Profile>
228 const Spec& spec, T value)
230 if (!UsesFloatTextBackend(type))
232 return ErrorCode::ARG_ERR;
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)
241 if (ExceedsFixedIntegerDigits(magnitude, precision))
243 return ErrorCode::OUT_OF_RANGE;
246 else if (type == FormatType::FloatGeneral || type == FormatType::DoubleGeneral ||
247 type == FormatType::LongDoubleGeneral)
249 uint8_t significant = precision == 0 ? 1 : precision;
250 int exponent = (magnitude == 0) ? 0 : NormalizeDecimal(magnitude).exponent;
251 if (!(exponent < -4 || exponent >= significant))
253 int fractional_precision =
static_cast<int>(significant) - (exponent + 1);
254 if (fractional_precision < 0)
256 fractional_precision = 0;
258 if (ExceedsFixedIntegerDigits(magnitude,
259 static_cast<uint8_t
>(fractional_precision)))
261 return ErrorCode::OUT_OF_RANGE;
265 char output_buffer[float_buffer_capacity];
266 size_t output_size = 0;
267 if (!FormatFloatText(type, spec, magnitude, output_buffer, output_size))
269 return ErrorCode::NO_BUFF;
272 return WriteFloatField(sign_char, std::string_view(output_buffer, output_size), spec);
280template <OutputSink Sink, FormatProfile Profile>
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));
294template <OutputSink Sink, FormatProfile Profile>
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)
305 return WriteRaw(std::string_view(digit_buffer, digit_count));
313template <OutputSink Sink, FormatProfile Profile>
316 return WriteRaw(text);
325template <OutputSink Sink, FormatProfile Profile>
329 char sign_char = std::signbit(value) ?
'-' :
'\0';
330 float magnitude = std::signbit(value) ? -value : value;
331 if (ExceedsFixedIntegerDigits(magnitude, precision))
333 return ErrorCode::OUT_OF_RANGE;
335 char output_buffer[float_buffer_capacity];
336 size_t output_size = 0;
337 if (!FormatF32FixedPrecText(magnitude, precision, output_buffer, output_size))
339 return ErrorCode::NO_BUFF;
342 if (sign_char !=
'\0')
344 if (
auto ec = WriteRaw(std::string_view(&sign_char, 1)); ec != ErrorCode::OK)
350 return WriteRaw(std::string_view(output_buffer, output_size));
359template <OutputSink Sink, FormatProfile Profile>
363 return WriteFloat(FormatType::DoubleFixed, Spec{.precision = precision}, value);
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.