mirror of
https://github.com/matrix-construct/construct
synced 2025-02-18 01:30:12 +01:00
ircd::spirit: Abstract common generator call into template.
This commit is contained in:
parent
93ee6a9f04
commit
b698f80067
3 changed files with 123 additions and 102 deletions
|
@ -62,6 +62,13 @@ __attribute__((visibility("default")))
|
|||
class it = const char *,
|
||||
class... args>
|
||||
bool parse(args&&...);
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
bool generate(mutable_buffer &out, gen&&, attr&&...);
|
||||
|
||||
template<class gen>
|
||||
bool generate(mutable_buffer &out, gen&&);
|
||||
}
|
||||
|
||||
namespace ircd {
|
||||
|
@ -139,6 +146,16 @@ __attribute__((visibility("hidden")))
|
|||
using karma::buffer;
|
||||
using karma::skip;
|
||||
|
||||
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<char *, prop_mask, unused_type>;
|
||||
|
||||
template<size_t idx,
|
||||
class semantic_context>
|
||||
auto &
|
||||
|
@ -162,6 +179,7 @@ namespace ircd {
|
|||
namespace spirit
|
||||
__attribute__((visibility("default")))
|
||||
{
|
||||
extern thread_local mutable_buffer *sink_buffer;
|
||||
}}
|
||||
|
||||
struct ircd::spirit::substring_view
|
||||
|
@ -223,6 +241,70 @@ ircd::spirit::expectation_failure<parent>::expectation_failure(const qi::expecta
|
|||
}
|
||||
{}
|
||||
|
||||
template<class gen>
|
||||
inline bool
|
||||
ircd::generate(mutable_buffer &out,
|
||||
gen&& g)
|
||||
{
|
||||
using namespace ircd::spirit;
|
||||
|
||||
assert(!sink_buffer);
|
||||
const scope_restore _sink_buffer
|
||||
{
|
||||
sink_buffer, &out
|
||||
};
|
||||
|
||||
sink_type sink
|
||||
{
|
||||
begin(out)
|
||||
};
|
||||
|
||||
const auto gg
|
||||
{
|
||||
karma::maxwidth(size(out))[std::forward<gen>(g)]
|
||||
};
|
||||
|
||||
const auto ret
|
||||
{
|
||||
karma::generate(sink, gg)
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
inline bool
|
||||
ircd::generate(mutable_buffer &out,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
{
|
||||
using namespace ircd::spirit;
|
||||
|
||||
assert(!sink_buffer);
|
||||
const scope_restore _sink_buffer
|
||||
{
|
||||
sink_buffer, &out
|
||||
};
|
||||
|
||||
sink_type sink
|
||||
{
|
||||
begin(out)
|
||||
};
|
||||
|
||||
const auto gg
|
||||
{
|
||||
karma::maxwidth(size(out))[std::forward<gen>(g)]
|
||||
};
|
||||
|
||||
const auto ret
|
||||
{
|
||||
karma::generate(sink, gg, std::forward<attr>(a)...)
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class parent_error,
|
||||
class it,
|
||||
class... args>
|
||||
|
@ -253,4 +335,37 @@ ircd::spirit::attr_at(semantic_context&& c)
|
|||
return boost::fusion::at_c<idx>(c.attributes);
|
||||
}
|
||||
|
||||
template<>
|
||||
[[gnu::visibility("internal")]]
|
||||
inline bool
|
||||
boost::spirit::karma::detail::buffer_sink::copy(ircd::spirit::sink_type &sink,
|
||||
size_t maxwidth)
|
||||
const
|
||||
{
|
||||
assert(ircd::spirit::sink_buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
[[gnu::visibility("internal")]]
|
||||
inline bool
|
||||
boost::spirit::karma::detail::buffer_sink::copy_rest(ircd::spirit::sink_type &sink,
|
||||
size_t start_at)
|
||||
const
|
||||
{
|
||||
assert(ircd::spirit::sink_buffer);
|
||||
assert(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
[[gnu::visibility("internal")]]
|
||||
inline void
|
||||
boost::spirit::karma::detail::buffer_sink::output(const char &value)
|
||||
{
|
||||
assert(ircd::spirit::sink_buffer);
|
||||
auto &buf(*ircd::spirit::sink_buffer);
|
||||
ircd::consume(buf, ircd::copy(buf, value));
|
||||
}
|
||||
|
||||
#endif // HAVE_IRCD_SPIRIT_H
|
||||
|
|
103
ircd/json.cc
103
ircd/json.cc
|
@ -210,16 +210,6 @@ 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>
|
||||
|
@ -468,43 +458,6 @@ 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")]]
|
||||
|
@ -525,33 +478,7 @@ 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(sink, gg | eps[throws], std::forward<attr>(a)...)
|
||||
};
|
||||
|
||||
return ret;
|
||||
return ircd::generate(out, std::forward<gen>(g) | eps[throws], std::forward<attr>(a)...);
|
||||
}
|
||||
|
||||
template<class gen>
|
||||
|
@ -571,33 +498,7 @@ 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(sink, gg | eps[throws])
|
||||
};
|
||||
|
||||
return ret;
|
||||
return ircd::generate(out, std::forward<gen>(g) | eps[throws]);
|
||||
}
|
||||
|
||||
template<class it_a,
|
||||
|
|
|
@ -23,9 +23,14 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
decltype(ircd::spirit::rulebuf) thread_local
|
||||
thread_local
|
||||
decltype(ircd::spirit::rulebuf)
|
||||
ircd::spirit::rulebuf;
|
||||
|
||||
thread_local
|
||||
decltype(ircd::spirit::sink_buffer)
|
||||
ircd::spirit::sink_buffer;
|
||||
|
||||
//
|
||||
// Museum of historical comments
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue