Sometimes, I need to effectively call fmt::format
in a nested manner. e.g.
fmt::format("{}", fmt::format("{}", arg));
The real situation is more complicated than this, of course.
I'd like a view for the nested calls so that it doesn't allocate a string, do the formatting, and then allocate another one for the outer call.
Does such a thing exist?
You can do something like this
template <typename Format, typename Args>
struct nested_format_t {
Format format;
Args args;
};
template <typename... Args>
auto nested_format(fmt::format_string<Args...> format, Args&&... args) {
return nested_format_t{format, std::tuple{std::forward<Args>(args)...}};
}
template <typename Format, typename Args>
struct fmt::formatter<nested_format_t<Format, Args>> {
template <class ParseContext>
constexpr ParseContext::iterator parse(ParseContext& ctx) {
auto it = ctx.begin();
if (it != ctx.end() && *it != '}') {
throw "Invalid format found";
}
return it;
}
template <class FmtContext>
constexpr FmtContext::iterator format(
const nested_format_t<Format, Args>& nested, FmtContext& ctx) const {
auto it = ctx.out();
std::apply(
[&](auto&&... args) {
fmt::vformat_to(it, nested.format,
fmt::make_format_args(args...));
},
nested.args);
return it;
}
};
int main() {
int x = 6;
int y = 4;
fmt::println("foo: {} {}", x, nested_format("bar {0}", y));
}