diff --git a/ircd/json.cc b/ircd/json.cc index 91215e804..1877a89cb 100644 --- a/ircd/json.cc +++ b/ircd/json.cc @@ -360,10 +360,17 @@ struct ircd::json::printer { template - bool operator()(mutable_buffer &out, gen&&, attr&&...) const; + bool operator()(std::nothrow_t, mutable_buffer &out, gen&&, attr&&...) const; template - bool operator()(mutable_buffer &out, gen&&) const; + bool operator()(std::nothrow_t, mutable_buffer &out, gen&&) const; + + template + void operator()(mutable_buffer &out, gen&&, attr&&...) const; + + template + void operator()(mutable_buffer &out, gen&&) const; template -bool +inline void +__attribute__((always_inline)) ircd::json::printer::operator()(mutable_buffer &out, gen&& g, attr&&... a) const { - const auto maxwidth - { - karma::maxwidth(size(out)) - }; - - const auto gg - { - maxwidth[std::forward(g)] - }; - - const auto throws{[&out] - { + if(unlikely(!operator()(std::nothrow, out, std::forward(g), std::forward(a)...))) throw print_panic { "Failed to print attributes '%s' generator '%s' (%zd bytes in buffer)", @@ -399,44 +396,63 @@ const demangle(), size(out) }; - }}; - - return karma::generate(begin(out), gg | eps[throws], std::forward(a)...); } template -bool +inline void +__attribute__((always_inline)) ircd::json::printer::operator()(mutable_buffer &out, gen&& g) const { - const auto maxwidth - { - karma::maxwidth(size(out)) - }; - - const auto gg - { - maxwidth[std::forward(g)] - }; - - const auto throws{[&out] - { + if(unlikely(!operator()(std::nothrow, out, std::forward(g)))) throw print_panic { "Failed to print generator '%s' (%zd bytes in buffer)", demangle(), size(out) }; - }}; +} - return karma::generate(begin(out), gg | eps[throws]); +template +inline bool +__attribute__((always_inline)) +ircd::json::printer::operator()(std::nothrow_t, + mutable_buffer &out, + gen&& g, + attr&&... a) +const +{ + const auto generator + { + karma::maxwidth(size(out))[std::forward(g)] + }; + + return karma::generate(begin(out), generator, std::forward(a)...); +} + +template +inline bool +__attribute__((always_inline)) +ircd::json::printer::operator()(std::nothrow_t, + mutable_buffer &out, + gen&& g) +const +{ + const auto generator + { + karma::maxwidth(size(out))[std::forward(g)] + }; + + return karma::generate(begin(out), generator); } template -void +inline void +__attribute__((always_inline)) ircd::json::printer::list_protocol(mutable_buffer &buffer, it_a it, const it_b &end, @@ -447,7 +463,8 @@ ircd::json::printer::list_protocol(mutable_buffer &buffer, lambda(buffer, *it); for(++it; it != end; ++it) { - json::printer(buffer, json::printer.value_sep); + static const auto &printer(json::printer); + printer(buffer, printer.value_sep); lambda(buffer, *it); } } @@ -1534,7 +1551,7 @@ ircd::json::stack::member::member(object &po, }; mutable_buffer buf{tmp}; - if(!printer(buf, rule, name)) + if(!printer(std::nothrow, buf, rule, name)) throw error { "member name overflow: max size is under %zu", sizeof(tmp)