0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-30 02:32:43 +01:00

ircd::json: Workaround buffer_sink action.

This commit is contained in:
Jason Volk 2020-05-25 21:59:38 -07:00
parent 53b304cb7a
commit f2f3e9a8a5

View file

@ -210,6 +210,16 @@ ircd::json::printer
:karma::grammar<char *, unused_type>
{
using it = char *;
using prop_mask = mpl_::int_
<
karma::generator_properties::no_properties
| karma::generator_properties::buffering
| karma::generator_properties::counting
| karma::generator_properties::tracking
| karma::generator_properties::disabling
>;
using sink_type = karma::detail::output_iterator<it, prop_mask, unused_type>;
static thread_local mutable_buffer *sink_buffer;
template<class T = unused_type,
class... A>
@ -454,6 +464,43 @@ noexcept
}
}
thread_local
decltype(ircd::json::printer::sink_buffer)
ircd::json::printer::sink_buffer;
template<>
[[gnu::visibility("internal")]]
inline bool
boost::spirit::karma::detail::buffer_sink::copy(ircd::json::printer::sink_type &sink,
size_t maxwidth)
const
{
assert(ircd::json::printer::sink_buffer);
return true;
}
template<>
[[gnu::visibility("internal")]]
inline bool
boost::spirit::karma::detail::buffer_sink::copy_rest(ircd::json::printer::sink_type &sink,
size_t start_at)
const
{
assert(ircd::json::printer::sink_buffer);
assert(false);
return true;
}
template<>
[[gnu::visibility("internal")]]
inline void
boost::spirit::karma::detail::buffer_sink::output(const char &value)
{
assert(ircd::json::printer::sink_buffer);
auto &buf(*ircd::json::printer::sink_buffer);
ircd::consume(buf, ircd::copy(buf, value));
}
template<class gen,
class... attr>
[[gnu::visibility("internal")]]
@ -463,16 +510,6 @@ ircd::json::printer::operator()(mutable_buffer &out,
attr&&... a)
const
{
const auto maxwidth
{
karma::maxwidth(size(out))
};
const auto gg
{
maxwidth[std::forward<gen>(g)]
};
const auto throws{[&out]
{
throw print_panic
@ -484,9 +521,30 @@ const
};
}};
const auto maxwidth
{
karma::maxwidth(size(out))
};
const auto gg
{
maxwidth[std::forward<gen>(g)]
};
assert(!sink_buffer);
const scope_restore set_sink_buffer
{
sink_buffer, &out
};
sink_type sink
{
begin(out)
};
const auto ret
{
karma::generate(begin(out), gg | eps[throws], std::forward<attr>(a)...)
karma::generate(sink, gg | eps[throws], std::forward<attr>(a)...)
};
return ret;
@ -499,16 +557,6 @@ ircd::json::printer::operator()(mutable_buffer &out,
gen&& g)
const
{
const auto maxwidth
{
karma::maxwidth(size(out))
};
const auto gg
{
maxwidth[std::forward<gen>(g)]
};
const auto throws{[&out]
{
throw print_panic
@ -519,9 +567,30 @@ const
};
}};
const auto maxwidth
{
karma::maxwidth(size(out))
};
const auto gg
{
maxwidth[std::forward<gen>(g)]
};
assert(!sink_buffer);
const scope_restore set_sink_buffer
{
sink_buffer, &out
};
sink_type sink
{
begin(out)
};
const auto ret
{
karma::generate(begin(out), gg | eps[throws])
karma::generate(sink, gg | eps[throws])
};
return ret;