9#include "format_surface.hpp"
49template <
typename Sink,
typename Format,
typename... Args>
50 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
51[[nodiscard]]
inline ErrorCode Write(Sink& sink,
const Format& format, Args&&... args)
53 using Built = std::remove_cvref_t<Format>;
54 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
55 sink, format, std::forward<Args>(args)...);
70template <OutputSink Sink,
typename Format,
typename... Args>
71[[nodiscard]]
inline ErrorCode FormatTo(Sink& sink,
const Format& format, Args&&... args)
73 return Write(sink, format, std::forward<Args>(args)...);
87template <Text Source, OutputSink Sink,
typename... Args>
88[[nodiscard]]
inline ErrorCode FormatTo(Sink& sink, Args&&... args)
91 return FormatTo(sink, format, std::forward<Args>(args)...);
105template <Text Source, OutputSink Sink,
typename... Args>
106[[nodiscard]]
inline ErrorCode PrintfTo(Sink& sink, Args&&... args)
109 return FormatTo(sink, format, std::forward<Args>(args)...);
145[[nodiscard]]
inline int FormatIntoBuffer(
char* buffer,
size_t capacity,
146 const auto& format,
auto&&... args)
150 char* buffer =
nullptr;
151 size_t retain_limit = 0;
152 size_t retained_size = 0;
153 size_t total_size = 0;
155 [[nodiscard]]
ErrorCode Write(std::string_view chunk)
157 total_size += chunk.size();
159 if (buffer ==
nullptr || retained_size >= retain_limit)
161 return ErrorCode::OK;
164 size_t writable = retain_limit - retained_size;
165 size_t copy_size = chunk.size() < writable ? chunk.size() : writable;
168 std::memcpy(buffer + retained_size, chunk.data(), copy_size);
169 retained_size += copy_size;
171 return ErrorCode::OK;
177 .retain_limit = capacity > 0 ? capacity - 1 : 0,
179 auto ec = Write(sink, format, std::forward<
decltype(args)>(args)...);
182 if (capacity > 0 && buffer !=
nullptr)
189 if (capacity > 0 && buffer !=
nullptr)
191 buffer[sink.retained_size] =
'\0';
194 if (sink.total_size >
static_cast<size_t>(std::numeric_limits<int>::max()))
199 return static_cast<int>(sink.total_size);
216template <Text Source,
typename... Args>
217[[nodiscard]]
inline int FormatIntoBuffer(
char* buffer,
size_t capacity, Args&&... args)
220 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
237template <Text Source,
typename... Args>
238[[nodiscard]]
inline int PrintfIntoBuffer(
char* buffer,
size_t capacity, Args&&... args)
241 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
264[[nodiscard]]
inline int SNPrintf(
char* buffer,
size_t capacity,
const auto& format,
267 return FormatIntoBuffer(buffer, capacity, format,
268 std::forward<
decltype(args)>(args)...);
285template <Text Source,
typename... Args>
286[[nodiscard]]
inline int SNPrintf(
char* buffer,
size_t capacity, Args&&... args)
289 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
强制使用 brace 风格前端 / force brace-style frontend
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful