libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
format_surface.hpp
1#pragma once
2
3#include <cstddef>
4#include <tuple>
5#include <type_traits>
6#include <utility>
7
8#include "format/format_frontend_detail.hpp"
9#include "writer.hpp"
10
11namespace LibXR
12{
13template <Print::Text Source>
14class Format
15{
16 private:
18 inline static constexpr auto source_analysis =
20
21 static_assert(source_analysis.error != SourceError::NumberOverflow,
22 "LibXR::Format: index, width, or precision is too large");
23 static_assert(source_analysis.error != SourceError::UnexpectedEnd,
24 "LibXR::Format: unexpected end of format string");
25 static_assert(
26 source_analysis.error != SourceError::EmbeddedNul,
27 "LibXR::Format: embedded NUL bytes are not supported in the format literal");
28 static_assert(source_analysis.error != SourceError::UnmatchedBrace,
29 "LibXR::Format: unmatched brace in format string");
30 static_assert(source_analysis.error != SourceError::MixedIndexing,
31 "LibXR::Format: automatic and manual argument indexing cannot be mixed");
32 static_assert(
33 source_analysis.error != SourceError::ManualIndexingDisabled,
34 "LibXR::Format: explicit argument indexing is disabled in the current profile");
35 static_assert(source_analysis.error != SourceError::DynamicField,
36 "LibXR::Format: dynamic width and precision are not supported");
37 static_assert(source_analysis.error != SourceError::InvalidArgumentIndex,
38 "LibXR::Format: invalid argument index");
39 static_assert(source_analysis.error != SourceError::InvalidSpecifier,
40 "LibXR::Format: invalid format specifier");
41 static_assert(source_analysis.error != SourceError::InvalidPresentation,
42 "LibXR::Format: invalid presentation type");
43
44 public:
50
57 template <typename... Args>
59
66 template <typename... Args>
67 struct Compiled
68 {
69 private:
70 using Frontend = Compiler<Args...>;
71 inline static constexpr auto result = Print::FormatCompiler<Frontend>::Compile();
72
73 static_assert(source_analysis.error != SourceError::None ||
74 sizeof...(Args) == source_analysis.required_argument_count,
75 "LibXR::Format: call-site argument count does not match the "
76 "referenced replacement fields");
77 static_assert(result.compile_error != Error::NumberOverflow,
78 "LibXR::Format: index, width, or precision is too large");
79 static_assert(result.compile_error != Error::FloatPrecisionLimitExceeded,
80 "LibXR::Format: float precision exceeds the configured print limit");
81 static_assert(result.compile_error != Error::UnexpectedEnd,
82 "LibXR::Format: unexpected end of format string");
83 static_assert(
84 result.compile_error != Error::EmbeddedNul,
85 "LibXR::Format: embedded NUL bytes are not supported in the format literal");
86 static_assert(result.compile_error != Error::UnmatchedBrace,
87 "LibXR::Format: unmatched brace in format string");
88 static_assert(
89 result.compile_error != Error::MixedIndexing,
90 "LibXR::Format: automatic and manual argument indexing cannot be mixed");
91 static_assert(
92 result.compile_error != Error::ManualIndexingDisabled,
93 "LibXR::Format: explicit argument indexing is disabled in the current profile");
94 static_assert(result.compile_error != Error::DynamicField,
95 "LibXR::Format: dynamic width and precision are not supported");
96 static_assert(result.compile_error != Error::InvalidArgumentIndex,
97 "LibXR::Format: invalid argument index");
98 static_assert(result.compile_error != Error::InvalidSpecifier,
99 "LibXR::Format: invalid format specifier");
100 static_assert(result.compile_error != Error::InvalidPresentation,
101 "LibXR::Format: invalid presentation type");
102 static_assert(result.compile_error != Error::MissingArgument,
103 "LibXR::Format: referenced argument index is out of range");
104 static_assert(
105 result.compile_error != Error::ArgumentTypeMismatch,
106 "LibXR::Format: format options are incompatible with the selected argument type");
107 static_assert(result.compile_error != Error::UnsupportedArgumentType,
108 "LibXR::Format: unsupported C++ argument type");
109 static_assert(result.compile_error != Error::TextOffsetOverflow,
110 "LibXR::Format: text pool offset is too large");
111 static_assert(result.compile_error != Error::TextSizeOverflow,
112 "LibXR::Format: text span is too large");
113
114 public:
119 inline static constexpr auto codes = result.codes;
124 inline static constexpr Print::FormatProfile profile = result.profile;
125
130 [[nodiscard]] static constexpr auto ArgumentList() { return result.arg_info; }
131
136 [[nodiscard]] static constexpr auto ArgumentOrder()
137 {
138 return source_analysis.argument_order;
139 }
140
145 [[nodiscard]] static constexpr const auto& Codes() { return codes; }
146
151 [[nodiscard]] static constexpr Print::FormatProfile Profile() { return profile; }
152
161 template <typename... Actual>
162 [[nodiscard]] static consteval bool Matches()
163 {
164 return std::is_same_v<std::tuple<std::remove_cvref_t<Actual>...>,
165 std::tuple<Args...>>;
166 }
167 };
168
175 [[nodiscard]] static constexpr size_t ArgumentCount()
176 {
177 return source_analysis.required_argument_count;
178 }
179
187 template <typename... Args>
188 [[nodiscard]] static consteval bool Matches()
189 {
190 if constexpr (sizeof...(Args) != source_analysis.required_argument_count)
191 {
192 return false;
193 }
194 else
195 {
196 using Frontend = Compiler<std::remove_cvref_t<Args>...>;
197 return Print::FormatCompiler<Frontend>::Compile().compile_error == Error::None;
198 }
199 }
200
211 template <Print::OutputSink Sink, typename... Args>
212 [[nodiscard]] ErrorCode WriteTo(Sink& sink, Args&&... args) const
213 {
214 using Built = Compiled<std::remove_cvref_t<Args>...>;
215 return Print::Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
216 sink, Built{}, std::forward<Args>(args)...);
217 }
218};
219} // namespace LibXR
220
221namespace LibXR::Print
222{
234template <Text Source, OutputSink Sink, typename... Args>
235[[nodiscard]] inline ErrorCode Write(Sink& sink, const LibXR::Format<Source>&,
236 Args&&... args)
237{
238 using Built =
239 typename LibXR::Format<Source>::template Compiled<std::remove_cvref_t<Args>...>;
240 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
241 sink, Built{}, std::forward<Args>(args)...);
242}
243} // namespace LibXR::Print
ErrorCode WriteTo(Sink &sink, Args &&... args) const
将当前格式写入一个输出端,并且只返回 sink 状态 / Write this format into one sink and return only the sink status
static constexpr size_t ArgumentCount()
返回当前源串会寻址的调用点参数个数 / Returns the required call-site argument count addressed by this source.
static consteval bool Matches()
判断这条源格式串能否和 Args... 一起通过编译。 / Returns whether this source string can be compiled with Args....
将一条 brace 风格源字面量绑定到一组具体 C++ 参数类型上的前端适配器 / Frontend adapter that binds one brace-style source literal ...
static consteval auto Compile()
把一个前端编译成最终字节流、参数表和 writer 摘要。 / Compiles one frontend into the final byte stream, argument table,...
接收编译格式输出的写入端 / Output endpoint accepted by compiled format writers
Error
brace 风格 format 前端的编译期失败类别。 / Compile-time failure categories for the brace-style format frontend.
consteval auto Analyze()
对单条 brace 风格字面量执行仅源串分析 / Run source-only analysis for one brace-style literal
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
一条 brace 风格源串绑定到具体调用点参数后的编译结果 / One brace-style source bound to a concrete call-site argument list
static consteval bool Matches()
判断另一组 C++ 参数类型是否与当前格式绑定时的参数列表完全一致。 / Returns whether another C++ argument list is exactly the one thi...
static constexpr auto ArgumentList()
返回运行期参数打包时要按字段顺序读取的参数列表。 / Returns the field-ordered argument list the runtime packer will follow.
static constexpr Print::FormatProfile profile
返回当前格式需要哪些 writer 分支的编译期摘要。 / Returns the compile-time summary of which writer branches this format n...
static constexpr Print::FormatProfile Profile()
返回当前编译格式携带的 writer 分支摘要。 / Returns the writer-branch summary carried by this compiled format.
static constexpr auto ArgumentOrder()
返回每个字段对应的是第几个源参数。 / Returns, for each field, which source argument index it refers to.
static constexpr const auto & Codes()
返回与 codes 相同的最终字节流。 / Returns the same final byte stream as codes.
static constexpr auto codes
返回运行期 writer 最终会执行的字节流。 / Returns the final byte stream that the runtime writer will execute.