libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::Print::Writer Class Reference

运行期 writer,负责打包调用点参数并执行编译好的字节流 / Runtime writer that packs call-site arguments and executes the compiled byte stream More...

#include <writer.hpp>

Data Structures

class  ArgumentReader
 运行期参数字节块的顺序读取器 / Sequential reader for the packed runtime argument byte blob More...
 
class  CodeReader
 编译后记录流的顺序读取器 / Sequential reader for the compiled record stream More...
 
class  Executor
 按输出端共享重后端、按调用点 profile 裁剪操作码分发的字节码执行器 / Per-sink bytecode executor with shared heavy backends and per-call profile-pruned opcode dispatch More...
 
struct  Spec
 运行期对单个字段描述字节组的解码视图 / Runtime view of one decoded field specification byte group More...
 

Static Public Member Functions

template<typename Sink , typename Format , auto ArgumentOrder, typename... Args>
requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
static ErrorCode RunArgumentOrder (Sink &sink, const Format &, Args &&... args)
 执行一份编译格式;它的字段顺序与源参数顺序可以不同 / Run one compiled format whose field order and source argument order may differ
 

Static Private Member Functions

static constexpr bool HasFlag (uint8_t flags, uint8_t bit)
 判断某个已解码字段修饰位是否被设置 / Test whether one decoded field-spec bit is set
 
template<size_t N>
static constexpr size_t BoundedTextLength (const char(&text)[N]) noexcept
 返回一个 char 数组参数在边界内的 C 字符串长度 / Return the bounded C-string length stored inside one char array argument
 
template<typename T >
static constexpr std::string_view ToStringView (const T &text)
 将一个字符串类运行期参数归一化为 std::string_view / Normalize one string-like runtime argument into std::string_view
 
template<FormatPackKind pack, typename T >
static constexpr auto PackValue (T &&value)
 将一个运行期实参转换为某个编译参数槽要求的打包存储形态 / Convert one runtime argument into the packed storage shape required by one compiled argument slot
 
template<typename T >
static void StoreArgument (uint8_t *&out, const T &value)
 把一个已打包值复制进参数字节块,并推进写指针 / Copy one packed value into the argument byte blob and advance the cursor
 
template<auto ArgumentInfoList>
static consteval size_t PackedArgumentBytes ()
 返回一组编译参数元信息在运行期需要的打包字节数 / Return the runtime packed-byte size required by one compiled argument metadata list
 
template<auto ArgumentInfoList, auto ArgumentOrder, typename Tuple >
static void StoreArgumentsOrdered (uint8_t *&out, Tuple &tuple)
 按字段执行顺序把运行期参数打包成最终字节块 / Pack runtime arguments into the final byte blob in field execution order
 
template<std::unsigned_integral UInt, uint8_t Base>
static consteval size_t UnsignedDigitCapacity ()
 返回某个无符号整数在指定进制下所需的最大数字个数 / Return the maximum digit count required for one unsigned integer under the selected radix
 
template<uint8_t Base, bool UpperCase = false, size_t N, std::unsigned_integral UInt>
static size_t AppendUnsigned (char(&out)[N], UInt value)
 把一个无符号整数写进调用方提供的定长数字缓冲区 / Append one unsigned integer into a caller-provided fixed-size digit buffer
 
template<size_t N>
static size_t AppendSmallUnsigned (char(&out)[N], uint8_t value)
 以十进制形式追加一个较小的无符号整数 / Append one small unsigned integer in base 10
 
static constexpr size_t FieldPadding (uint8_t width, size_t payload_size)
 返回把某段载荷扩展到目标字段宽度所需的填充长度 / Return the padding width needed to expand one payload to the requested field width
 
static constexpr size_t IntegerPrecisionZeros (const Spec &spec, size_t digit_count)
 返回整数精度引入的额外前导零个数 / Return the extra leading-zero count introduced by integer precision
 
template<std::unsigned_integral UInt>
static constexpr std::string_view IntegerPrefix (FormatType type, const Spec &spec, UInt value)
 返回放在数字载荷之外的备用格式前缀 / Return the alternate-form prefix carried outside the digit payload
 
template<std::unsigned_integral UInt>
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 constexpr bool UsesFloatTextBackend (FormatType type)
 判断这个字段类型是否走共享的浮点文本输出路径 / Return whether this field type is printed by the shared float-text path
 
static constexpr bool FloatEnabled (FormatType type)
 判断这个浮点字段类型是否被当前功能开关启用 / Return whether this float field type is enabled by current feature switches
 
static constexpr uint8_t DefaultFloatPrecision ()
 返回格式串没有显式写精度时使用的默认浮点精度 / Return the default float precision used when the format string did not specify one
 
template<typename Float >
static bool ExceedsFixedIntegerDigits (Float value, uint8_t precision)
 判断定点形态的浮点输出是否会超出当前配置的整数位数上限 / Return whether fixed-shape float output would exceed the configured integer-digit limit
 
static bool AppendBufferChar (char *buffer, size_t capacity, size_t &size, char ch)
 向有界本地格式化缓冲区追加一个字符 / Append one character to a bounded local formatting buffer
 
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 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 target width
 
template<OutputSink Sink, FormatProfile Profile>
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
 
template<OutputSink Sink, auto ArgumentInfoList, auto ArgumentOrder, FormatProfile Profile, typename... Args>
static LIBXR_NOINLINE ErrorCode RunTaggedArgumentOrder (Sink &sink, const uint8_t *codes, Args &&... args)
 先打包转发后的运行期参数,再执行编译字节流 / Pack forwarded runtime arguments, then execute the compiled byte stream
 

Static Private Attributes

static constexpr uint8_t unspecified_precision = 0xFF
 为某个已编译参数列表生成栈上参数字节块 / Emit the stack argument byte blob for one compiled argument list
 
template<FormatPackKind K>
static constexpr bool dependent_false_v = false
 
static constexpr size_t float_buffer_capacity
 

Detailed Description

运行期 writer,负责打包调用点参数并执行编译好的字节流 / Runtime writer that packs call-site arguments and executes the compiled byte stream

Definition at line 120 of file writer.hpp.

Member Function Documentation

◆ AppendBufferChar()

bool LibXR::Print::Writer::AppendBufferChar ( char * buffer,
size_t capacity,
size_t & size,
char ch )
staticnodiscardprivate

向有界本地格式化缓冲区追加一个字符 / Append one character to a bounded local formatting buffer

Parameters
buffer目标缓冲区 / Destination buffer
capacity缓冲区总容量 / Total buffer capacity
size当前已保留长度;成功时会推进 / Current retained size; advanced on success
ch待追加字符 / Character to append
Returns
成功返回 true,否则返回 false / Returns true on success, otherwise false

Definition at line 40 of file writer_runtime.cpp.

41{
42 if (size >= capacity)
43 {
44 return false;
45 }
46 buffer[size++] = ch;
47 return true;
48}

◆ AppendBufferText()

bool LibXR::Print::Writer::AppendBufferText ( char * buffer,
size_t capacity,
size_t & size,
std::string_view text )
staticnodiscardprivate

向有界本地格式化缓冲区追加一段文本 / Append one text span to a bounded local formatting buffer

Parameters
buffer目标缓冲区 / Destination buffer
capacity缓冲区总容量 / Total buffer capacity
size当前已保留长度;成功时会推进 / Current retained size; advanced on success
text待追加文本片段 / Text span to append
Returns
成功返回 true,否则返回 false / Returns true on success, otherwise false

Definition at line 50 of file writer_runtime.cpp.

52{
53 if (size > capacity || text.size() > capacity - size)
54 {
55 return false;
56 }
57 std::memcpy(buffer + size, text.data(), text.size());
58 size += text.size();
59 return true;
60}

◆ AppendBufferU32ZeroPad()

bool LibXR::Print::Writer::AppendBufferU32ZeroPad ( char * buffer,
size_t capacity,
size_t & size,
uint32_t value,
uint8_t width )
staticnodiscardprivate

追加一个 uint32_t 十进制值,并在前面补零到目标宽度 / Append one uint32_t decimal value and pad leading zeros up to the target width

Parameters
buffer目标缓冲区 / Destination buffer
capacity缓冲区总容量 / Total buffer capacity
size当前已保留长度;成功时会推进 / Current retained size; advanced on success
value待追加的无符号值 / Unsigned value to append
width目标零填充宽度 / Target zero-padded width
Returns
成功返回 true,否则返回 false / Returns true on success, otherwise false

Definition at line 62 of file writer_runtime.cpp.

64{
66 size_t digit_count = AppendUnsigned<10>(digits, value);
67 size_t zero_count =
68 (width > digit_count) ? static_cast<size_t>(width) - digit_count : 0;
69
70 for (size_t i = 0; i < zero_count; ++i)
71 {
72 if (!AppendBufferChar(buffer, capacity, size, '0'))
73 {
74 return false;
75 }
76 }
77
78 return AppendBufferText(buffer, capacity, size, std::string_view(digits, digit_count));
79}
static consteval size_t UnsignedDigitCapacity()
返回某个无符号整数在指定进制下所需的最大数字个数 / Return the maximum digit count required for one unsigned integer under the...
Definition writer.hpp:10
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 size_t AppendUnsigned(char(&out)[N], UInt value)
把一个无符号整数写进调用方提供的定长数字缓冲区 / Append one unsigned integer into a caller-provided fixed-size digit buffer
Definition writer.hpp:38
static bool AppendBufferChar(char *buffer, size_t capacity, size_t &size, char ch)
向有界本地格式化缓冲区追加一个字符 / Append one character to a bounded local formatting buffer

◆ AppendSmallUnsigned()

template<size_t N>
size_t LibXR::Print::Writer::AppendSmallUnsigned ( char(&) out[N],
uint8_t value )
inlinestaticnodiscardprivate

以十进制形式追加一个较小的无符号整数 / Append one small unsigned integer in base 10

追加一个较小的十进制无符号整数 / Append one small decimal unsigned integer

Parameters
out目标数字缓冲区 / Destination digit buffer
value待编码的无符号值 / Unsigned value to encode
Returns
返回输出的数字个数 / Returns the emitted digit count

Definition at line 77 of file writer.hpp.

83{
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;
87}
88
94[[nodiscard]] constexpr size_t ComputeBufferCapacity()
95{
96 size_t capacity = 4;
97 if constexpr (Config::enable_float_fixed || Config::enable_float_scientific ||
98 Config::enable_float_general)
99 {
100 capacity = FloatTextLimit<float>();
101 }
102 if constexpr (Config::enable_float_double)
103 {
104 constexpr size_t double_limit = FloatTextLimit<double>();
105 capacity = capacity > double_limit ? capacity : double_limit;
106 }
107 if constexpr (Config::enable_float_long_double)
108 {
109 constexpr size_t long_double_limit = FloatTextLimit<long double>();
110 capacity = capacity > long_double_limit ? capacity : long_double_limit;
111 }
112 return capacity;
113}
114} // namespace Detail::WriterFloatLimit
115
120class Writer
121{
122 public:
145 template <typename Sink, typename Format, auto ArgumentOrder, typename... Args>
146 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
147 [[nodiscard]] static ErrorCode RunArgumentOrder(Sink& sink, const Format&,
148 Args&&... args)
149 {
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");
154 static_assert(
155 Built::template Matches<Args...>(),
156 "LibXR::Print::Writer::RunArgumentOrder: format arguments do not match");
157
158 return RunTaggedArgumentOrder<Sink, Built::ArgumentList(), ArgumentOrder,
159 Built::Profile()>(sink, Built::Codes().data(),
160 std::forward<Args>(args)...);
161 }
162
163 private:
168 static constexpr uint8_t unspecified_precision = 0xFF;
169 template <FormatPackKind K>
170 static constexpr bool dependent_false_v = false;
171 static constexpr size_t float_buffer_capacity =
172 Detail::WriterFloatLimit::ComputeBufferCapacity();
173
178 [[nodiscard]] static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
179 {
180 return (flags & bit) != 0;
181 }
182
187 struct Spec
188 {
189 uint8_t flags = 0;
190 char fill = ' ';
191 uint8_t width = 0;
192 uint8_t precision = unspecified_precision;
194
200 [[nodiscard]] constexpr bool LeftAlign() const
201 {
202 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::LeftAlign));
203 }
204
211 [[nodiscard]] constexpr bool ForceSign() const
212 {
213 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::ForceSign));
214 }
215
221 [[nodiscard]] constexpr bool CenterAlign() const
222 {
223 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::CenterAlign));
224 }
225
232 [[nodiscard]] constexpr bool SpaceSign() const
233 {
234 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::SpaceSign));
235 }
236
242 [[nodiscard]] constexpr bool Alternate() const
243 {
244 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::Alternate));
245 }
246
252 [[nodiscard]] constexpr bool ZeroPad() const
253 {
254 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::ZeroPad));
255 }
256
262 [[nodiscard]] constexpr bool UpperCase() const
263 {
264 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::UpperCase));
265 }
266
272 [[nodiscard]] constexpr bool HasPrecision() const
273 {
274 return precision != unspecified_precision;
275 }
276 };
277
285 template <size_t N>
286 [[nodiscard]] static constexpr size_t BoundedTextLength(const char (&text)[N]) noexcept;
287
295 template <typename T>
296 [[nodiscard]] static constexpr std::string_view ToStringView(const T& text);
297
306 template <FormatPackKind pack, typename T>
307 [[nodiscard]] static constexpr auto PackValue(T&& value);
308
316 template <typename T>
317 static void StoreArgument(uint8_t*& out, const T& value);
318
325 template <auto ArgumentInfoList>
326 [[nodiscard]] static consteval size_t PackedArgumentBytes();
327
339 template <auto ArgumentInfoList, auto ArgumentOrder, typename Tuple>
340 static void StoreArgumentsOrdered(uint8_t*& out, Tuple& tuple);
341
358 template <std::unsigned_integral UInt, uint8_t Base>
359 [[nodiscard]] static consteval size_t UnsignedDigitCapacity();
360
373 template <uint8_t Base, bool UpperCase = false, size_t N, std::unsigned_integral UInt>
374 [[nodiscard]] static size_t AppendUnsigned(char (&out)[N], UInt value);
375
383 template <size_t N>
384 [[nodiscard]] static size_t AppendSmallUnsigned(char (&out)[N], uint8_t value);
385
393 [[nodiscard]] static constexpr size_t FieldPadding(uint8_t width, size_t payload_size);
394
402 [[nodiscard]] static constexpr size_t IntegerPrecisionZeros(const Spec& spec,
403 size_t digit_count);
404
414 template <std::unsigned_integral UInt>
415 [[nodiscard]] static constexpr std::string_view IntegerPrefix(FormatType type,
416 const Spec& spec,
417 UInt value);
418
436 template <std::unsigned_integral UInt>
437 [[nodiscard]] static size_t ApplyAlternateOctal(char* digits, size_t digit_count,
438 const Spec& spec, UInt value);
439
447 [[nodiscard]] static constexpr bool UsesFloatTextBackend(FormatType type);
448
456 [[nodiscard]] static constexpr bool FloatEnabled(FormatType type);
462 [[nodiscard]] static constexpr uint8_t DefaultFloatPrecision();
473 template <typename Float>
474 [[nodiscard]] static bool ExceedsFixedIntegerDigits(Float value, uint8_t precision);
475
486 [[nodiscard]] static bool AppendBufferChar(char* buffer, size_t capacity, size_t& size,
487 char ch);
488
499 [[nodiscard]] static bool AppendBufferText(char* buffer, size_t capacity, size_t& size,
500 std::string_view text);
501
513 [[nodiscard]] static bool AppendBufferU32ZeroPad(char* buffer, size_t capacity,
514 size_t& size, uint32_t value,
515 uint8_t width);
516
517#if LIBXR_PRINT_ENABLE_FLOAT
523 template <typename Float>
524 struct DecimalScale;
525
531 template <typename Float>
532 struct ScientificDigits;
533
541 template <typename Float>
542 [[nodiscard]] static Float Power10(int exponent);
543
553 template <typename Float>
554 [[nodiscard]] static Float RoundDecimal(Float value, uint8_t precision);
555
564 template <typename Float>
565 [[nodiscard]] static ScientificDigits<Float> RoundScientificDigits(Float value,
566 uint8_t precision);
567
575 template <typename Float>
576 [[nodiscard]] static DecimalScale<Float> NormalizeDecimal(Float value);
577
586 template <typename Float>
587 [[nodiscard]] static uint8_t ExtractDigit(Float& value, Float scale);
588
597 [[nodiscard]] static size_t TrimGeneralText(char* text, size_t size);
598
610 template <typename Float>
611 [[nodiscard]] static bool FormatFixedText(Float value, uint8_t precision,
612 bool alternate, char* out, size_t& out_size);
613
623 [[nodiscard]] static bool AppendExponentText(char* out, size_t& out_size, int exponent,
624 bool upper_case);
625
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);
642
655 template <typename Float>
656 [[nodiscard]] static bool FormatFloatText(FormatType type, const Spec& spec,
657 Float value, char* out, size_t& out_size);
658#endif
659
660 class CodeReader;
661 class ArgumentReader;
662
663 template <OutputSink Sink>
664 class Executor;
665
677 template <OutputSink Sink, FormatProfile Profile>
678 [[nodiscard]] static LIBXR_NOINLINE ErrorCode Execute(Sink& sink, const uint8_t* codes,
679 const uint8_t* args)
680 {
681 return Executor<Sink>(sink, codes, args).template Run<Profile>();
682 }
683
698 template <OutputSink Sink, auto ArgumentInfoList, auto ArgumentOrder,
699 FormatProfile Profile, typename... Args>
700 [[nodiscard]] static LIBXR_NOINLINE ErrorCode
701 RunTaggedArgumentOrder(Sink& sink, const uint8_t* codes, Args&&... args)
702 {
703 if constexpr (ArgumentInfoList.size() == 0)
704 {
705 return Execute<Sink, Profile>(sink, codes, nullptr);
706 }
707 else
708 {
709 constexpr size_t packed_arg_bytes = PackedArgumentBytes<ArgumentInfoList>();
710 uint8_t packed[packed_arg_bytes];
711 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
712 auto* cursor = packed;
713 StoreArgumentsOrdered<ArgumentInfoList, ArgumentOrder>(cursor, tuple);
714 return Execute<Sink, Profile>(sink, codes, packed);
715 }
716 }
717};
718
719// These implementation headers form an ordered dependency chain.
720// clang-format off
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"
728#endif
729#include "writer/writer_reader.hpp"
730#include "writer/writer_executor.hpp"
731// clang-format on
732} // namespace LibXR::Print
@ Format
force brace-style frontend / 强制使用 brace 风格前端
ErrorCode
定义错误码枚举

◆ AppendUnsigned()

template<uint8_t Base, bool UpperCase, size_t N, std::unsigned_integral UInt>
size_t LibXR::Print::Writer::AppendUnsigned ( char(&) out[N],
UInt value )
staticnodiscardprivate

把一个无符号整数写进调用方提供的定长数字缓冲区 / Append one unsigned integer into a caller-provided fixed-size digit buffer

将一个无符号整数写入调用方提供的定长数字缓冲区 / Append one unsigned integer into a caller-provided fixed-size digit buffer

Template Parameters
Base整数进制 / Integer radix
UpperCase十六进制数字是否使用大写字母 / Whether hexadecimal digits should use uppercase letters
N目标缓冲区长度 / Destination buffer size
UInt无符号整数类型 / Unsigned integer type
Parameters
out目标数字缓冲区 / Destination digit buffer
value待编码的无符号值 / Unsigned value to encode
Returns
返回输出的数字个数 / Returns the emitted digit count

Definition at line 38 of file writer.hpp.

51{
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);
56}
57
64template <typename Float>
65[[nodiscard]] constexpr size_t ScientificTextLimit()
66{
67 constexpr size_t decimal_point =
68 (Config::max_float_precision != 0 || Config::enable_alternate) ? 1U : 0U;

◆ ApplyAlternateOctal()

template<std::unsigned_integral UInt>
size_t LibXR::Print::Writer::ApplyAlternateOctal ( char * digits,
size_t digit_count,
const Spec & spec,
UInt value )
staticnodiscardprivate

直接在已生成的数字载荷上应用 %#o 的特殊规则 / Apply %#o special rules directly onto the generated digit payload

直接在已生成数字上应用 %#o 的特殊规则 / Apply the special %#o payload rules directly onto the generated digits

Octal alternate form differs from hex: it is represented by a leading zero in the digit payload itself, not by a detached prefix string. This helper also preserves the required single 0 when %#.0o formats zero. 八进制备用格式与十六进制不同:它通过数字载荷本体前导一个 0 来表示, 而不是额外分离出的前缀字符串。本函数也负责在 %#.0o 格式化零值时保留 必需的单个 0。

Template Parameters
UInt无符号整数类型 / Unsigned integer type
Parameters
digits可修改的数字缓冲区 / Mutable digit buffer
digit_count当前数字个数 / Current digit count
spec解码后的字段规格 / Decoded field spec
value当前要输出的无符号值 / Unsigned value being emitted
Returns
返回更新后的数字个数 / Returns the updated digit count
Template Parameters
UInt无符号整数类型 / Unsigned integer type
Parameters
digits可修改的数字缓冲区 / Mutable digit buffer
digit_count当前数字个数 / Current digit count
spec解码后的字段规格 / Decoded field spec
value当前要输出的无符号值 / Unsigned value being emitted
Returns
返回更新后的数字个数 / Returns the updated digit count

Definition at line 151 of file writer.hpp.

152 : argument reorder list must match the "
153 "compiled field count");
154 static_assert(
155 Built::template Matches<Args...>(),
156 "LibXR::Print::Writer::RunArgumentOrder: format arguments do not match");
157
158 return RunTaggedArgumentOrder<Sink, Built::ArgumentList(), ArgumentOrder,
159 Built::Profile()>(sink, Built::Codes().data(),
160 std::forward<Args>(args)...);
161 }
162
163 private:
168 static constexpr uint8_t unspecified_precision = 0xFF;
169 template <FormatPackKind K>
170 static constexpr bool dependent_false_v = false;
171 static constexpr size_t float_buffer_capacity =
172 Detail::WriterFloatLimit::ComputeBufferCapacity();
173
178 [[nodiscard]] static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
179 {
180 return (flags & bit) != 0;
181 }
static ErrorCode RunArgumentOrder(Sink &sink, const Format &, Args &&... args)
执行一份编译格式;它的字段顺序与源参数顺序可以不同 / Run one compiled format whose field order and source argument order may d...
Definition writer.hpp:147

◆ BoundedTextLength()

template<size_t N>
size_t LibXR::Print::Writer::BoundedTextLength ( const char(&) text[N])
staticnodiscardconstexprprivatenoexcept

返回一个 char 数组参数在边界内的 C 字符串长度 / Return the bounded C-string length stored inside one char array argument

Writer 的运行期参数归一化与打包辅助函数 / Runtime argument normalization and packing helpers for Writer.

Template Parameters
N数组长度 / Array extent
Parameters
textchar 数组参数 / Char array argument
Returns
返回边界内首个 NUL 的位置 / Returns the first in-range NUL position

返回一个 char 数组参数在边界内的 C 字符串长度 / Return the bounded C-string length inside one char array argument

Template Parameters
N数组长度 / Array extent
Parameters
textchar 数组参数 / Char array argument
Returns
返回边界内首个 NUL 的位置 / Returns the first in-range NUL position
Note
这条路径要求数组边界内必须存在结尾 NUL;否则内部 ASSERT 会触发 / This path requires a terminating NUL inside the array bound; otherwise the internal ASSERT fires

Definition at line 20 of file writer.hpp.

23{
24namespace Detail::WriterFloatLimit
25{
32[[nodiscard]] constexpr size_t DecimalDigitCount(size_t value)
33{
34 size_t digits = 1;

◆ DefaultFloatPrecision()

static constexpr uint8_t LibXR::Print::Writer::DefaultFloatPrecision ( )
staticnodiscardconstexprprivate

返回格式串没有显式写精度时使用的默认浮点精度 / Return the default float precision used when the format string did not specify one

Returns
返回默认浮点精度 / Returns the default float precision

◆ ExceedsFixedIntegerDigits()

template<typename Float >
static bool LibXR::Print::Writer::ExceedsFixedIntegerDigits ( Float value,
uint8_t precision )
staticnodiscardprivate

判断定点形态的浮点输出是否会超出当前配置的整数位数上限 / Return whether fixed-shape float output would exceed the configured integer-digit limit

Template Parameters
Float浮点类型 / Float type
Parameters
value待检查的浮点绝对值 / Float magnitude to test
precision请求的小数精度 / Requested fractional precision
Returns
若定点输出的整数部分会超出配置上限则返回 true,否则返回 false / Returns true when the fixed-form integer part would exceed the configured limit, otherwise false

◆ Execute()

template<OutputSink Sink, FormatProfile Profile>
static LIBXR_NOINLINE ErrorCode LibXR::Print::Writer::Execute ( Sink & sink,
const uint8_t * codes,
const uint8_t * args )
inlinestaticnodiscardprivate

使用一份已打包参数字节块执行一段编译字节流 / Execute one compiled byte stream against one already packed argument blob

Template Parameters
Sink输出端类型,需满足 OutputSink / Sink type satisfying OutputSink
Profile编译期 writer 摘要 / Compile-time writer profile
Parameters
sink输出端 / Destination sink
codes指向编译字节流的指针 / Pointer to the compiled byte stream
args指向已打包参数字节块的指针;无参数时可为空 / Pointer to the packed argument blob, or null when no arguments exist
Returns
执行器运行结果 / Returns the executor result

Definition at line 678 of file writer.hpp.

680 {
681 return Executor<Sink>(sink, codes, args).template Run<Profile>();
682 }

◆ FieldPadding()

size_t LibXR::Print::Writer::FieldPadding ( uint8_t width,
size_t payload_size )
staticnodiscardconstexprprivate

返回把某段载荷扩展到目标字段宽度所需的填充长度 / Return the padding width needed to expand one payload to the requested field width

返回某个载荷尺寸对应的字段宽度填充量 / Return the field-width padding needed for one payload size

Parameters
width请求的字段宽度 / Requested field width
payload_size填充前的可见载荷长度 / Visible payload size before padding
Returns
返回需要补上的填充个数 / Returns the required padding count

Definition at line 89 of file writer.hpp.

◆ FloatEnabled()

static constexpr bool LibXR::Print::Writer::FloatEnabled ( FormatType type)
staticnodiscardconstexprprivate

判断这个浮点字段类型是否被当前功能开关启用 / Return whether this float field type is enabled by current feature switches

Parameters
type运行期浮点字段类型 / Runtime float field type
Returns
当前功能开关允许该浮点字段类型时返回 true,否则返回 false / Returns true when this float field type is enabled, otherwise false

◆ HasFlag()

static constexpr bool LibXR::Print::Writer::HasFlag ( uint8_t flags,
uint8_t bit )
inlinestaticnodiscardconstexprprivate

判断某个已解码字段修饰位是否被设置 / Test whether one decoded field-spec bit is set

Definition at line 178 of file writer.hpp.

179 {
180 return (flags & bit) != 0;
181 }

◆ IntegerPrecisionZeros()

size_t LibXR::Print::Writer::IntegerPrecisionZeros ( const Spec & spec,
size_t digit_count )
staticnodiscardconstexprprivate

返回整数精度引入的额外前导零个数 / Return the extra leading-zero count introduced by integer precision

返回整数精度要求引入的额外前导零个数 / Return the extra leading zeros introduced by integer precision

Parameters
spec解码后的字段规格 / Decoded field spec
digit_count当前已有的数字个数 / Existing digit count
Returns
返回额外前导零个数 / Returns the extra leading-zero count

Definition at line 101 of file writer.hpp.

103 {
104 constexpr size_t double_limit = FloatTextLimit<double>();
105 capacity = capacity > double_limit ? capacity : double_limit;
106 }

◆ IntegerPrefix()

template<std::unsigned_integral UInt>
std::string_view LibXR::Print::Writer::IntegerPrefix ( FormatType type,
const Spec & spec,
UInt value )
staticnodiscardconstexprprivate

返回放在数字载荷之外的备用格式前缀 / Return the alternate-form prefix carried outside the digit payload

返回备用格式下脱离数字主体输出的整数前缀 / Return the detached integer prefix emitted by alternate formatting

Template Parameters
UInt无符号整数类型 / Unsigned integer type
Parameters
type运行期字段类型 / Runtime field type
spec解码后的字段规格 / Decoded field spec
value当前要输出的无符号值 / Unsigned value being emitted
Returns
返回分离在数字之外的备用格式前缀 / Returns the detached alternate-form prefix
Template Parameters
UInt无符号整数类型 / Unsigned integer type
Parameters
type运行期字段类型 / Runtime field type
spec解码后的字段规格 / Decoded field spec
value当前要输出的无符号值 / Unsigned value being emitted
Returns
返回分离在数字主体之外的整数前缀 / Returns the detached integer prefix

Definition at line 118 of file writer.hpp.

121{
122 public:

◆ PackedArgumentBytes()

template<auto ArgumentInfoList>
size_t LibXR::Print::Writer::PackedArgumentBytes ( )
staticnodiscardconstevalprivate

返回一组编译参数元信息在运行期需要的打包字节数 / Return the runtime packed-byte size required by one compiled argument metadata list

返回一个编译期参数列表所需的参数打包字节数 / Return the packed-byte size required by one compiled argument list

Template Parameters
ArgumentInfoList编译期参数元信息列表 / Compile-time argument metadata list
Returns
返回运行期打包总字节数 / Returns the packed runtime byte size
Template Parameters
ArgumentInfoList编译期参数元信息列表 / Compile-time argument metadata list
Returns
返回该参数列表在运行期打包后需要的总字节数 / Returns the packed runtime byte size for this argument list

Definition at line 211 of file writer.hpp.

212 {
213 return Writer::HasFlag(flags, static_cast<uint8_t>(FormatFlag::ForceSign));
214 }
215
static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
判断某个已解码字段修饰位是否被设置 / Test whether one decoded field-spec bit is set
Definition writer.hpp:178

◆ PackValue()

template<FormatPackKind pack, typename T >
auto LibXR::Print::Writer::PackValue ( T && value)
staticnodiscardconstexprprivate

将一个运行期实参转换为某个编译参数槽要求的打包存储形态 / Convert one runtime argument into the packed storage shape required by one compiled argument slot

将一个已匹配的 C++ 实参归一化为某个编译参数槽要求的运行期打包存储类型 / Normalize one matched C++ argument into the packed runtime storage kind required by one compiled argument slot

Template Parameters
pack目标打包存储类型 / Target packed storage kind
T运行期实参类型 / Runtime argument type
Parameters
value运行期实参值 / Runtime argument value
Returns
返回该参数槽对应的打包值 / Returns the packed value for that slot
Template Parameters
pack目标打包存储类型 / Target packed storage kind
T运行期实参类型 / Runtime argument type
Parameters
value运行期实参值 / Runtime argument value
Returns
返回该参数槽需要的归一化打包值 / Returns the normalized packed value for this slot

Definition at line 88 of file writer.hpp.

95{
96 size_t capacity = 4;
97 if constexpr (Config::enable_float_fixed || Config::enable_float_scientific ||
98 Config::enable_float_general)
99 {
100 capacity = FloatTextLimit<float>();
101 }
102 if constexpr (Config::enable_float_double)
103 {
104 constexpr size_t double_limit = FloatTextLimit<double>();
105 capacity = capacity > double_limit ? capacity : double_limit;
106 }
107 if constexpr (Config::enable_float_long_double)
108 {
109 constexpr size_t long_double_limit = FloatTextLimit<long double>();
110 capacity = capacity > long_double_limit ? capacity : long_double_limit;
111 }
112 return capacity;
113}
114} // namespace Detail::WriterFloatLimit
115
120class Writer
121{
122 public:
145 template <typename Sink, typename Format, auto ArgumentOrder, typename... Args>
146 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
147 [[nodiscard]] static ErrorCode RunArgumentOrder(Sink& sink, const Format&,
148 Args&&... args)
149 {
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");
154 static_assert(
155 Built::template Matches<Args...>(),
156 "LibXR::Print::Writer::RunArgumentOrder: format arguments do not match");
157
158 return RunTaggedArgumentOrder<Sink, Built::ArgumentList(), ArgumentOrder,
159 Built::Profile()>(sink, Built::Codes().data(),
160 std::forward<Args>(args)...);
161 }
162
163 private:
168 static constexpr uint8_t unspecified_precision = 0xFF;
169 template <FormatPackKind K>
170 static constexpr bool dependent_false_v = false;
171 static constexpr size_t float_buffer_capacity =
172 Detail::WriterFloatLimit::ComputeBufferCapacity();
173
178 [[nodiscard]] static constexpr bool HasFlag(uint8_t flags, uint8_t bit)
179 {
180 return (flags & bit) != 0;
181 }
182

◆ RunArgumentOrder()

template<typename Sink , typename Format , auto ArgumentOrder, typename... Args>
requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
static ErrorCode LibXR::Print::Writer::RunArgumentOrder ( Sink & sink,
const Format & ,
Args &&... args )
inlinestaticnodiscard

执行一份编译格式;它的字段顺序与源参数顺序可以不同 / Run one compiled format whose field order and source argument order may differ

Template Parameters
Sink输出端类型,需满足 OutputSink / Sink type satisfying OutputSink
Format编译格式类型 / Compiled format type
ArgumentOrder按字段顺序排列的源参数索引表 / Source-argument index list ordered by emitted fields
Args调用点实参类型列表 / Call-site argument types
Parameters
sink输出端 / Destination sink
format编译格式对象,仅用于约束与类型推导 / Compiled format object, used only for constraints and type deduction
args调用点实参 / Call-site arguments

This path is used by formats such as {1} {0}: fields are still executed in source order, but the runtime argument pack must be built in another order. 这条路径用于 {1} {0} 这种格式:字段仍然按源串顺序执行, 但运行期参数包要按另一种顺序构造。

Note
这条接口不重新解析源格式串;它直接执行编译好的字节流 / This function does not re-parse the source format string; it executes the compiled byte stream directly
Returns
运行期 writer 执行状态 / Returns the runtime writer status

Definition at line 147 of file writer.hpp.

149 {
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");
154 static_assert(
155 Built::template Matches<Args...>(),
156 "LibXR::Print::Writer::RunArgumentOrder: format arguments do not match");
157
158 return RunTaggedArgumentOrder<Sink, Built::ArgumentList(), ArgumentOrder,
159 Built::Profile()>(sink, Built::Codes().data(),
160 std::forward<Args>(args)...);
161 }
static LIBXR_NOINLINE ErrorCode RunTaggedArgumentOrder(Sink &sink, const uint8_t *codes, Args &&... args)
先打包转发后的运行期参数,再执行编译字节流 / Pack forwarded runtime arguments, then execute the compiled byte stream
Definition writer.hpp:701

◆ RunTaggedArgumentOrder()

template<OutputSink Sink, auto ArgumentInfoList, auto ArgumentOrder, FormatProfile Profile, typename... Args>
static LIBXR_NOINLINE ErrorCode LibXR::Print::Writer::RunTaggedArgumentOrder ( Sink & sink,
const uint8_t * codes,
Args &&... args )
inlinestaticnodiscardprivate

先打包转发后的运行期参数,再执行编译字节流 / Pack forwarded runtime arguments, then execute the compiled byte stream

Template Parameters
Sink输出端类型,需满足 OutputSink / Sink type satisfying OutputSink
ArgumentInfoList编译期参数元信息列表 / Compile-time argument metadata list
ArgumentOrder按字段顺序排列的源参数索引表 / Source-argument index list ordered by emitted fields
Profile编译期 writer 摘要 / Compile-time writer profile
Args转发后的运行期实参类型列表 / Forwarded runtime argument types
Parameters
sink输出端 / Destination sink
codes指向编译字节流的指针 / Pointer to the compiled byte stream
args转发后的运行期实参 / Forwarded runtime arguments
Returns
执行器运行结果 / Returns the executor result

Definition at line 701 of file writer.hpp.

702 {
703 if constexpr (ArgumentInfoList.size() == 0)
704 {
705 return Execute<Sink, Profile>(sink, codes, nullptr);
706 }
707 else
708 {
709 constexpr size_t packed_arg_bytes = PackedArgumentBytes<ArgumentInfoList>();
710 uint8_t packed[packed_arg_bytes];
711 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
712 auto* cursor = packed;
714 return Execute<Sink, Profile>(sink, codes, packed);
715 }
716 }
static consteval size_t PackedArgumentBytes()
返回一组编译参数元信息在运行期需要的打包字节数 / Return the runtime packed-byte size required by one compiled argument metad...
Definition writer.hpp:211
static void StoreArgumentsOrdered(uint8_t *&out, Tuple &tuple)
按字段执行顺序把运行期参数打包成最终字节块 / Pack runtime arguments into the final byte blob in field execution order
Definition writer.hpp:234
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
Definition writer.hpp:678

◆ StoreArgument()

template<typename T >
void LibXR::Print::Writer::StoreArgument ( uint8_t *& out,
const T & value )
staticprivate

把一个已打包值复制进参数字节块,并推进写指针 / Copy one packed value into the argument byte blob and advance the cursor

把一个已打包参数值复制进字节块,并推进写指针 / Copy one packed argument value into the byte blob and advance the cursor

Template Parameters
T已打包值类型 / Packed value type
Parameters
out当前写指针 / Current write cursor
value待写入的已打包值 / Packed value to store
Template Parameters
T已打包值类型 / Packed value type
Parameters
out当前写指针;会前进 sizeof(T) / Current write cursor; advanced by sizeof(T)
value待写入的已打包值 / Packed value to store

Definition at line 197 of file writer.hpp.

201 {

◆ StoreArgumentsOrdered()

template<auto ArgumentInfoList, auto ArgumentOrder, typename Tuple >
void LibXR::Print::Writer::StoreArgumentsOrdered ( uint8_t *& out,
Tuple & tuple )
staticprivate

按字段执行顺序把运行期参数打包成最终字节块 / Pack runtime arguments into the final byte blob in field execution order

Template Parameters
ArgumentInfoList编译期参数元信息列表 / Compile-time argument metadata list
ArgumentOrder按字段顺序排列的源参数索引表 / Source-argument index list ordered by emitted fields
Tuple保存转发后运行期实参的 tuple 类型 / Tuple type holding forwarded runtime arguments
Parameters
out当前写指针 / Current write cursor
tuple转发后的运行期实参集合 / Forwarded runtime arguments
Template Parameters
ArgumentInfoList编译期参数元信息列表 / Compile-time argument metadata list
ArgumentOrder每个输出字段对应的源参数索引表 / Source-argument index per emitted field
Tuple持有转发后运行期实参的 tuple 类型 / Tuple type holding forwarded runtime arguments
Parameters
out当前写指针;会随着写入推进 / Current write cursor; advanced as values are stored
tuple转发后的运行期实参集合 / Forwarded runtime arguments

Definition at line 234 of file writer.hpp.

◆ ToStringView()

template<typename T >
std::string_view LibXR::Print::Writer::ToStringView ( const T & text)
staticnodiscardconstexprprivate

将一个字符串类运行期参数归一化为 std::string_view / Normalize one string-like runtime argument into std::string_view

Template Parameters
T运行期实参类型 / Runtime argument type
Parameters
text运行期实参值 / Runtime argument value
Returns
返回归一化后的文本视图 / Returns the normalized text view
Template Parameters
T运行期实参类型 / Runtime argument type
Parameters
text运行期实参值 / Runtime argument value
Returns
返回归一化后的文本视图 / Returns the normalized text view
Note
空 C 字符串指针会被归一化为字面量 "(null)" / Null C-string pointers are normalized to the literal "(null)"

Definition at line 46 of file writer.hpp.

51{
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);
56}
57
64template <typename Float>
65[[nodiscard]] constexpr size_t ScientificTextLimit()
66{
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 +
72 exponent_digits;
73}
74

◆ UnsignedDigitCapacity()

template<std::unsigned_integral UInt, uint8_t Base>
size_t LibXR::Print::Writer::UnsignedDigitCapacity ( )
staticnodiscardconstevalprivate

返回某个无符号整数在指定进制下所需的最大数字个数 / Return the maximum digit count required for one unsigned integer under the selected radix

运行期 writer 后端共享的整数文本辅助函数 / Shared integer-text helpers for the runtime writer backend

This helper intentionally uses a short exact integer division loop instead of a floating-point approximation. It is consteval, so it can only be used in immediate compile-time contexts such as array extents and static_assert, and therefore adds no runtime cost. 本辅助函数有意使用一个简短且精确的整数除法循环,而不是浮点近似公式。 它被声明为 consteval,只能用于数组长度、static_assert 等立即编译期 场景,因此不会引入任何运行期开销。

Template Parameters
UInt无符号整数类型 / Unsigned integer type
Base整数进制 / Integer radix
Returns
返回该整型在所选进制下的最大数字个数 / Returns the maximum digit count under the selected radix

Definition at line 10 of file writer.hpp.

23{

◆ UsesFloatTextBackend()

static constexpr bool LibXR::Print::Writer::UsesFloatTextBackend ( FormatType type)
staticnodiscardconstexprprivate

判断这个字段类型是否走共享的浮点文本输出路径 / Return whether this field type is printed by the shared float-text path

Parameters
type运行期字段类型 / Runtime field type
Returns
该类型走共享浮点文本后端时返回 true,否则返回 false / Returns true when this type uses the shared float-text backend, otherwise false

Field Documentation

◆ dependent_false_v

template<FormatPackKind K>
bool LibXR::Print::Writer::dependent_false_v = false
staticconstexprprivate

Definition at line 170 of file writer.hpp.

◆ float_buffer_capacity

size_t LibXR::Print::Writer::float_buffer_capacity
staticconstexprprivate
Initial value:
=
Detail::WriterFloatLimit::ComputeBufferCapacity()

Definition at line 171 of file writer.hpp.

◆ unspecified_precision

uint8_t LibXR::Print::Writer::unspecified_precision = 0xFF
staticconstexprprivate

为某个已编译参数列表生成栈上参数字节块 / Emit the stack argument byte blob for one compiled argument list

Definition at line 168 of file writer.hpp.


The documentation for this class was generated from the following files: