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_frontend_detail.hpp"
9#include "writer.hpp"
10
11namespace LibXR
12{
13template <Print::Text Source>
14class Format
15{
16 private:
17 using SourceError = Print::Detail::FormatFrontend::Error;
18 inline static constexpr auto source_analysis =
19 Print::Detail::FormatFrontend::Analyze<Source>();
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(source_analysis.error != SourceError::EmbeddedNul,
26 "LibXR::Format: embedded NUL bytes are not supported in the format literal");
27 static_assert(source_analysis.error != SourceError::UnmatchedBrace,
28 "LibXR::Format: unmatched brace in format string");
29 static_assert(source_analysis.error != SourceError::MixedIndexing,
30 "LibXR::Format: automatic and manual argument indexing cannot be mixed");
31 static_assert(source_analysis.error != SourceError::ManualIndexingDisabled,
32 "LibXR::Format: explicit argument indexing is disabled in the current profile");
33 static_assert(source_analysis.error != SourceError::DynamicField,
34 "LibXR::Format: dynamic width and precision are not supported");
35 static_assert(source_analysis.error != SourceError::InvalidArgumentIndex,
36 "LibXR::Format: invalid argument index");
37 static_assert(source_analysis.error != SourceError::InvalidSpecifier,
38 "LibXR::Format: invalid format specifier");
39 static_assert(source_analysis.error != SourceError::InvalidPresentation,
40 "LibXR::Format: invalid presentation type");
41
42 public:
47 using Error = Print::Detail::FormatFrontend::Error;
48
53 template <typename... Args>
55
60 template <typename... Args>
61 struct Compiled
62 {
63 private:
64 using Frontend = Compiler<Args...>;
65 inline static constexpr auto result = Print::FormatCompiler<Frontend>::Compile();
66
67 static_assert(source_analysis.error != SourceError::None ||
68 sizeof...(Args) == source_analysis.required_argument_count,
69 "LibXR::Format: call-site argument count does not match the "
70 "referenced replacement fields");
71 static_assert(result.compile_error != Error::NumberOverflow,
72 "LibXR::Format: index, width, or precision is too large");
73 static_assert(result.compile_error != Error::UnexpectedEnd,
74 "LibXR::Format: unexpected end of format string");
75 static_assert(result.compile_error != Error::EmbeddedNul,
76 "LibXR::Format: embedded NUL bytes are not supported in the format literal");
77 static_assert(result.compile_error != Error::UnmatchedBrace,
78 "LibXR::Format: unmatched brace in format string");
79 static_assert(result.compile_error != Error::MixedIndexing,
80 "LibXR::Format: automatic and manual argument indexing cannot be mixed");
81 static_assert(result.compile_error != Error::ManualIndexingDisabled,
82 "LibXR::Format: explicit argument indexing is disabled in the current profile");
83 static_assert(result.compile_error != Error::DynamicField,
84 "LibXR::Format: dynamic width and precision are not supported");
85 static_assert(result.compile_error != Error::InvalidArgumentIndex,
86 "LibXR::Format: invalid argument index");
87 static_assert(result.compile_error != Error::InvalidSpecifier,
88 "LibXR::Format: invalid format specifier");
89 static_assert(result.compile_error != Error::InvalidPresentation,
90 "LibXR::Format: invalid presentation type");
91 static_assert(result.compile_error != Error::MissingArgument,
92 "LibXR::Format: referenced argument index is out of range");
93 static_assert(result.compile_error != Error::ArgumentTypeMismatch,
94 "LibXR::Format: format options are incompatible with the selected argument type");
95 static_assert(result.compile_error != Error::UnsupportedArgumentType,
96 "LibXR::Format: unsupported C++ argument type");
97 static_assert(result.compile_error != Error::TextOffsetOverflow,
98 "LibXR::Format: text pool offset is too large");
99 static_assert(result.compile_error != Error::TextSizeOverflow,
100 "LibXR::Format: text span is too large");
101
102 public:
104 inline static constexpr auto codes = result.codes;
106 inline static constexpr Print::FormatProfile profile = result.profile;
107
109 [[nodiscard]] static constexpr auto ArgumentList()
110 {
111 return result.arg_info;
112 }
113
115 [[nodiscard]] static constexpr auto ArgumentOrder()
116 {
117 return source_analysis.argument_order;
118 }
119
121 [[nodiscard]] static constexpr const auto& Codes()
122 {
123 return codes;
124 }
125
127 [[nodiscard]] static constexpr Print::FormatProfile Profile()
128 {
129 return profile;
130 }
131
133 template <typename... Actual>
134 [[nodiscard]] static consteval bool Matches()
135 {
136 return std::is_same_v<std::tuple<std::remove_cvref_t<Actual>...>,
137 std::tuple<Args...>>;
138 }
139 };
140
142 [[nodiscard]] static constexpr size_t ArgumentCount()
143 {
144 return source_analysis.required_argument_count;
145 }
146
148 template <typename... Args>
149 [[nodiscard]] static consteval bool Matches()
150 {
151 if constexpr (sizeof...(Args) != source_analysis.required_argument_count)
152 {
153 return false;
154 }
155 else
156 {
157 using Frontend = Compiler<std::remove_cvref_t<Args>...>;
158 return Print::FormatCompiler<Frontend>::Compile().compile_error == Error::None;
159 }
160 }
161
163 template <Print::OutputSink Sink, typename... Args>
164 [[nodiscard]] ErrorCode WriteTo(Sink& sink, Args&&... args) const
165 {
166 using Built = Compiled<std::remove_cvref_t<Args>...>;
167 return Print::Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
168 sink, Built{}, std::forward<Args>(args)...);
169 }
170};
171} // namespace LibXR
172
173namespace LibXR::Print
174{
180template <Text Source, OutputSink Sink, typename... Args>
181[[nodiscard]] inline ErrorCode Write(Sink& sink, const LibXR::Format<Source>&,
182 Args&&... args)
183{
184 using Built =
185 typename LibXR::Format<Source>::template Compiled<std::remove_cvref_t<Args>...>;
186 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
187 sink, Built{}, std::forward<Args>(args)...);
188}
189} // namespace LibXR::Print
ErrorCode WriteTo(Sink &sink, Args &&... args) const
Writes this format into one sink and returns only the sink status. / 将当前格式写入一个输出端,并且只返回 sink 状态
static constexpr size_t ArgumentCount()
Returns the required call-site argument count addressed by this source. / 返回当前源串会寻址的调用点参数个数
static consteval bool Matches()
Returns true when Args... are accepted by this brace frontend. / 判断 Args... 是否能被当前 brace 前端接受
Frontend adapter that binds one brace-style source literal to one concrete C++ argument list.
static consteval auto Compile()
Compiles the frontend into one final compiled format.
接收编译格式输出的写入端。
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
One brace-style source bound to a concrete call-site argument list.
static consteval bool Matches()
Returns true when Actual... exactly match this bound compiled surface. / 判断 Actual....
static constexpr auto ArgumentList()
Ordered field metadata used by runtime argument packing. / 按字段顺序排列、供运行期参数打包使用的元信息
static constexpr Print::FormatProfile profile
Compile-time executor profile used to specialize the runtime bytecode interpreter....
static constexpr Print::FormatProfile Profile()
Returns the compile-time executor profile. / 返回编译期执行器配置
static constexpr auto ArgumentOrder()
Field-ordered source argument references, including duplicates and reordering. / 按字段顺序排列的源参数引用,可包含重复与...
static constexpr const auto & Codes()
Final compiled bytes consumed directly by the runtime writer. / 供运行期 writer 直接消费的最终编译字节块
static constexpr auto codes
Final runtime byte block kept by the compiled surface. / 编译格式表面保留的最终运行期字节块