I've made a Decimal class and want to use the fmt library.
I read that the way to define a type to the formatter is to specialize fmt::formatter
.
But, there is no information in the docs on how to call into the existing common infrastructure. The formatting codes for field alignment and overall width and fill character, for example: that should be common code that works across any type.
How do I write a formatter specialization without re-implementing the entire specification from scratch?
I'd like to start by making my type compatible with the floating-point formatting specifiers, so when a type is changed from double
to decimal it will continue to work the same; but then add additional features specific to the type.
template <int S, int F>
struct fmt::formatter<Decimal<S,F>> {
constexpr auto parse(format_parse_context& ctx) {
[[maybe_unused]] auto it = ctx.begin(), end = ctx.end();
// dummy stub. just take the whole thing
it = std::find(ctx.begin(),end, '}');
return it;
}
template <typename FormatContext>
auto format(const Dec& x, FormatContext& ctx) {
constexpr size_t bufsize = 64;
char buf[bufsize];
const auto end = x.to_chars (buf, buf+bufsize, false);
const std::string_view sv { buf, size_t(end-buf) };
return std::copy(sv.begin(),sv.end(),ctx.out());
}
};
{fmt} doesn't yet provide facilities for parsing standard format specifiers. Internally it uses fmt::detail::parse_format_specs
. It needs to be cleaned up a bit and moved to the public API for reuse.