9#include "format_surface.hpp"
50template <
typename Sink,
typename Format,
typename... Args>
51 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
52[[nodiscard]]
inline ErrorCode Write(Sink& sink,
const Format& format, Args&&... args)
54 using Built = std::remove_cvref_t<Format>;
55 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
56 sink, format, std::forward<Args>(args)...);
71template <OutputSink Sink,
typename Format,
typename... Args>
72[[nodiscard]]
inline ErrorCode FormatTo(Sink& sink,
const Format& format, Args&&... args)
74 return Write(sink, format, std::forward<Args>(args)...);
88template <Text Source, OutputSink Sink,
typename... Args>
89[[nodiscard]]
inline ErrorCode FormatTo(Sink& sink, Args&&... args)
92 return FormatTo(sink, format, std::forward<Args>(args)...);
106template <Text Source, OutputSink Sink,
typename... Args>
107[[nodiscard]]
inline ErrorCode PrintfTo(Sink& sink, Args&&... args)
110 return FormatTo(sink, format, std::forward<Args>(args)...);
146[[nodiscard]]
inline int FormatIntoBuffer(
char* buffer,
size_t capacity,
147 const auto& format,
auto&&... args)
151 char* buffer =
nullptr;
152 size_t retain_limit = 0;
153 size_t retained_size = 0;
154 size_t total_size = 0;
156 [[nodiscard]]
ErrorCode Write(std::string_view chunk)
158 total_size += chunk.size();
160 if (buffer ==
nullptr || retained_size >= retain_limit)
162 return ErrorCode::OK;
165 size_t writable = retain_limit - retained_size;
166 size_t copy_size = chunk.size() < writable ? chunk.size() : writable;
169 std::memcpy(buffer + retained_size, chunk.data(), copy_size);
170 retained_size += copy_size;
172 return ErrorCode::OK;
178 .retain_limit = capacity > 0 ? capacity - 1 : 0,
180 auto ec = Write(sink, format, std::forward<
decltype(args)>(args)...);
183 if (capacity > 0 && buffer !=
nullptr)
190 if (capacity > 0 && buffer !=
nullptr)
192 buffer[sink.retained_size] =
'\0';
195 if (sink.total_size >
static_cast<size_t>(std::numeric_limits<int>::max()))
200 return static_cast<int>(sink.total_size);
217template <Text Source,
typename... Args>
218[[nodiscard]]
inline int FormatIntoBuffer(
char* buffer,
size_t capacity, Args&&... args)
221 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
238template <Text Source,
typename... Args>
239[[nodiscard]]
inline int PrintfIntoBuffer(
char* buffer,
size_t capacity, Args&&... args)
242 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
265[[nodiscard]]
inline int SNPrintf(
char* buffer,
size_t capacity,
const auto& format,
268 return FormatIntoBuffer(buffer, capacity, format,
269 std::forward<
decltype(args)>(args)...);
286template <Text Source,
typename... Args>
287[[nodiscard]]
inline int SNPrintf(
char* buffer,
size_t capacity, Args&&... args)
290 return SNPrintf(buffer, capacity, format, std::forward<Args>(args)...);
static consteval Compiled< Source > Build()
在编译期解析并校验 printf 格式串 / Parse and validate a printf format at compile time
@ Format
force brace-style frontend / 强制使用 brace 风格前端
@ OK
操作成功 | Operation successful