17#include "../libxr_def.hpp"
18#include "format_argument.hpp"
19#include "format_protocol.hpp"
20#include "print_contract.hpp"
24namespace Detail::WriterFloatLimit
32[[nodiscard]]
constexpr size_t DecimalDigitCount(
size_t value)
49template <
typename Float>
50[[nodiscard]]
constexpr size_t FixedTextLimit()
52 constexpr size_t decimal_point =
53 (Config::max_float_precision != 0 || Config::enable_alternate) ? 1U : 0U;
54 return Config::max_float_integer_digits + decimal_point +
55 static_cast<size_t>(Config::max_float_precision);
64template <
typename Float>
65[[nodiscard]]
constexpr size_t ScientificTextLimit()
67 constexpr size_t decimal_point =
68 (Config::max_float_precision != 0 || Config::enable_alternate) ? 1U : 0U;
69 constexpr size_t exponent_digits =
70 DecimalDigitCount(
static_cast<size_t>(std::numeric_limits<Float>::max_exponent10));
71 return 1U + decimal_point +
static_cast<size_t>(Config::max_float_precision) + 2U +
81template <
typename Float>
82[[nodiscard]]
constexpr size_t FloatTextLimit()
84 constexpr size_t fixed_limit = FixedTextLimit<Float>();
85 constexpr size_t scientific_limit = ScientificTextLimit<Float>();
86 return fixed_limit > scientific_limit ? fixed_limit : scientific_limit;
94[[nodiscard]]
constexpr size_t ComputeBufferCapacity()
97 if constexpr (Config::enable_float_fixed || Config::enable_float_scientific ||
98 Config::enable_float_general)
100 capacity = FloatTextLimit<float>();
102 if constexpr (Config::enable_float_double)
104 constexpr size_t double_limit = FloatTextLimit<double>();
105 capacity = capacity > double_limit ? capacity : double_limit;
107 if constexpr (Config::enable_float_long_double)
109 constexpr size_t long_double_limit = FloatTextLimit<long double>();
110 capacity = capacity > long_double_limit ? capacity : long_double_limit;
145 template <
typename Sink,
typename Format,
auto ArgumentOrder,
typename... Args>
150 using Built = std::remove_cvref_t<Format>;
151 static_assert(ArgumentOrder.size() == Built::ArgumentList().size(),
152 "LibXR::Print::Writer: argument reorder list must match the "
153 "compiled field count");
155 Built::template Matches<Args...>(),
156 "LibXR::Print::Writer::RunArgumentOrder: format arguments do not match");
159 Built::Profile()>(sink, Built::Codes().data(),
160 std::forward<Args>(args)...);
169 template <FormatPackKind K>
170 static constexpr bool dependent_false_v =
false;
171 static constexpr size_t float_buffer_capacity =
172 Detail::WriterFloatLimit::ComputeBufferCapacity();
178 [[nodiscard]]
static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
180 return (flags & bit) != 0;
286 [[nodiscard]]
static constexpr size_t BoundedTextLength(
const char (&text)[N])
noexcept;
295 template <
typename T>
296 [[nodiscard]]
static constexpr std::string_view
ToStringView(
const T& text);
306 template <FormatPackKind pack,
typename T>
307 [[nodiscard]]
static constexpr auto PackValue(T&& value);
316 template <
typename T>
325 template <auto ArgumentInfoList>
339 template <auto ArgumentInfoList, auto ArgumentOrder,
typename Tuple>
358 template <std::
unsigned_
integral UInt, u
int8_t Base>
373 template <u
int8_t Base,
bool UpperCase = false,
size_t N, std::
unsigned_
integral UInt>
374 [[nodiscard]]
static size_t AppendUnsigned(
char (&out)[N], UInt value);
393 [[nodiscard]]
static constexpr size_t FieldPadding(uint8_t width,
size_t payload_size);
414 template <std::
unsigned_
integral UInt>
415 [[nodiscard]]
static constexpr std::string_view
IntegerPrefix(FormatType type,
436 template <std::
unsigned_
integral UInt>
438 const Spec& spec, UInt value);
473 template <
typename Float>
486 [[nodiscard]]
static bool AppendBufferChar(
char* buffer,
size_t capacity,
size_t& size,
499 [[nodiscard]]
static bool AppendBufferText(
char* buffer,
size_t capacity,
size_t& size,
500 std::string_view text);
514 size_t& size, uint32_t value,
517#if LIBXR_PRINT_ENABLE_FLOAT
523 template <
typename Float>
531 template <
typename Float>
532 struct ScientificDigits;
541 template <
typename Float>
542 [[nodiscard]]
static Float Power10(
int exponent);
553 template <
typename Float>
554 [[nodiscard]]
static Float RoundDecimal(Float value, uint8_t precision);
564 template <
typename Float>
565 [[nodiscard]]
static ScientificDigits<Float> RoundScientificDigits(Float value,
575 template <
typename Float>
576 [[nodiscard]]
static DecimalScale<Float> NormalizeDecimal(Float value);
586 template <
typename Float>
587 [[nodiscard]]
static uint8_t ExtractDigit(Float& value, Float scale);
597 [[nodiscard]]
static size_t TrimGeneralText(
char* text,
size_t size);
610 template <
typename Float>
611 [[nodiscard]]
static bool FormatFixedText(Float value, uint8_t precision,
612 bool alternate,
char* out,
size_t& out_size);
623 [[nodiscard]]
static bool AppendExponentText(
char* out,
size_t& out_size,
int exponent,
638 template <
typename Float>
639 [[nodiscard]]
static bool FormatScientificText(Float value, uint8_t precision,
640 bool alternate,
bool upper_case,
641 char* out,
size_t& out_size);
655 template <
typename Float>
656 [[nodiscard]]
static bool FormatFloatText(FormatType type,
const Spec& spec,
657 Float value,
char* out,
size_t& out_size);
663 template <OutputSink Sink>
677 template <OutputSink Sink, FormatProfile Profile>
698 template <
OutputSink Sink,
auto ArgumentInfoList,
auto ArgumentOrder,
699 FormatProfile Profile,
typename... Args>
700 [[nodiscard]]
static LIBXR_NOINLINE
ErrorCode
703 if constexpr (ArgumentInfoList.size() == 0)
710 uint8_t packed[packed_arg_bytes];
711 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
712 auto* cursor = packed;
721#include "writer/writer_argument.hpp"
722#include "writer/writer_integer.hpp"
723#if LIBXR_PRINT_ENABLE_FLOAT
724#include "writer/writer_float_runtime.hpp"
725#include "writer/writer_float_math.hpp"
726#include "writer/writer_float_fixed.hpp"
727#include "writer/writer_float_general.hpp"
729#include "writer/writer_reader.hpp"
730#include "writer/writer_executor.hpp"
运行期参数字节块的顺序读取器 / Sequential reader for the packed runtime argument byte blob
编译后记录流的顺序读取器 / Sequential reader for the compiled record stream
按输出端共享重后端、按调用点 profile 裁剪操作码分发的字节码执行器 / Per-sink bytecode executor with shared heavy backends and per...
运行期 writer,负责打包调用点参数并执行编译好的字节流 / Runtime writer that packs call-site arguments and executes the compi...
static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
判断某个已解码字段修饰位是否被设置 / Test whether one decoded field-spec bit is set
static constexpr size_t IntegerPrecisionZeros(const Spec &spec, size_t digit_count)
返回整数精度引入的额外前导零个数 / Return the extra leading-zero count introduced by integer precision
static ErrorCode RunArgumentOrder(Sink &sink, const Format &, Args &&... args)
执行一份编译格式;它的字段顺序与源参数顺序可以不同 / Run one compiled format whose field order and source argument order may d...
static consteval size_t PackedArgumentBytes()
返回一组编译参数元信息在运行期需要的打包字节数 / Return the runtime packed-byte size required by one compiled argument metad...
static size_t AppendSmallUnsigned(char(&out)[N], uint8_t value)
以十进制形式追加一个较小的无符号整数 / Append one small unsigned integer in base 10
static constexpr std::string_view IntegerPrefix(FormatType type, const Spec &spec, UInt value)
返回放在数字载荷之外的备用格式前缀 / Return the alternate-form prefix carried outside the digit payload
static constexpr bool UsesFloatTextBackend(FormatType type)
判断这个字段类型是否走共享的浮点文本输出路径 / Return whether this field type is printed by the shared float-text path
static constexpr auto PackValue(T &&value)
将一个运行期实参转换为某个编译参数槽要求的打包存储形态 / Convert one runtime argument into the packed storage shape required by ...
static constexpr size_t FieldPadding(uint8_t width, size_t payload_size)
返回把某段载荷扩展到目标字段宽度所需的填充长度 / Return the padding width needed to expand one payload to the requested fiel...
static constexpr std::string_view ToStringView(const T &text)
将一个字符串类运行期参数归一化为 std::string_view / Normalize one string-like runtime argument into std::string_view
static consteval size_t UnsignedDigitCapacity()
返回某个无符号整数在指定进制下所需的最大数字个数 / Return the maximum digit count required for one unsigned integer under the...
static LIBXR_NOINLINE ErrorCode RunTaggedArgumentOrder(Sink &sink, const uint8_t *codes, Args &&... args)
先打包转发后的运行期参数,再执行编译字节流 / Pack forwarded runtime arguments, then execute the compiled byte stream
static bool AppendBufferText(char *buffer, size_t capacity, size_t &size, std::string_view text)
向有界本地格式化缓冲区追加一段文本 / Append one text span to a bounded local formatting buffer
static constexpr uint8_t DefaultFloatPrecision()
返回格式串没有显式写精度时使用的默认浮点精度 / Return the default float precision used when the format string did not speci...
static constexpr bool FloatEnabled(FormatType type)
判断这个浮点字段类型是否被当前功能开关启用 / Return whether this float field type is enabled by current feature switches
static bool AppendBufferU32ZeroPad(char *buffer, size_t capacity, size_t &size, uint32_t value, uint8_t width)
追加一个 uint32_t 十进制值,并在前面补零到目标宽度 / Append one uint32_t decimal value and pad leading zeros up to the ta...
static size_t ApplyAlternateOctal(char *digits, size_t digit_count, const Spec &spec, UInt value)
直接在已生成的数字载荷上应用 %#o 的特殊规则 / Apply %#o special rules directly onto the generated digit payload
static void StoreArgument(uint8_t *&out, const T &value)
把一个已打包值复制进参数字节块,并推进写指针 / Copy one packed value into the argument byte blob and advance the cursor
static size_t AppendUnsigned(char(&out)[N], UInt value)
把一个无符号整数写进调用方提供的定长数字缓冲区 / Append one unsigned integer into a caller-provided fixed-size digit buffer
static void StoreArgumentsOrdered(uint8_t *&out, Tuple &tuple)
按字段执行顺序把运行期参数打包成最终字节块 / Pack runtime arguments into the final byte blob in field execution order
static bool ExceedsFixedIntegerDigits(Float value, uint8_t precision)
判断定点形态的浮点输出是否会超出当前配置的整数位数上限 / Return whether fixed-shape float output would exceed the configured int...
static constexpr size_t BoundedTextLength(const char(&text)[N]) noexcept
返回一个 char 数组参数在边界内的 C 字符串长度 / Return the bounded C-string length stored inside one char array argumen...
static constexpr uint8_t unspecified_precision
为某个已编译参数列表生成栈上参数字节块 / Emit the stack argument byte blob for one compiled argument list
static LIBXR_NOINLINE ErrorCode Execute(Sink &sink, const uint8_t *codes, const uint8_t *args)
使用一份已打包参数字节块执行一段编译字节流 / Execute one compiled byte stream against one already packed argument blob
static bool AppendBufferChar(char *buffer, size_t capacity, size_t &size, char ch)
向有界本地格式化缓冲区追加一个字符 / Append one character to a bounded local formatting buffer
接收编译格式输出的写入端 / Output endpoint accepted by compiled format writers
运行期对单个字段描述字节组的解码视图 / Runtime view of one decoded field specification byte group
constexpr bool ZeroPad() const
判断是否请求了零填充 / Return whether zero-padding is requested
constexpr bool UpperCase() const
判断是否请求了大写输出 / Return whether uppercase output is requested
constexpr bool SpaceSign() const
判断是否请求了正值前补空格的符号策略 / Return whether space-sign output for positive values is requested
constexpr bool LeftAlign() const
判断是否请求了左对齐 / Return whether left alignment is requested
constexpr bool HasPrecision() const
判断是否显式指定了精度 / Return whether precision was explicitly specified
uint8_t width
field width, or zero when absent / 字段宽度,未指定时为 0
constexpr bool Alternate() const
判断是否请求了备用格式 / Return whether alternate form is requested
constexpr bool ForceSign() const
判断是否请求了显式正号输出 / Return whether explicit plus-sign output is requested
constexpr bool CenterAlign() const
判断是否请求了居中对齐 / Return whether center alignment is requested
char fill
field fill character / 字段填充字符
uint8_t flags
FormatFlag bitset / 字段修饰位集合