mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::spirit: Consolidate entry to spirit through wrapper templates.
ircd::spirit: More aggressive inlining of interface templates; symbol visibility
This commit is contained in:
parent
99504180c0
commit
b59337eb78
6 changed files with 165 additions and 130 deletions
|
@ -55,26 +55,8 @@ __attribute__((visibility("default")))
|
|||
IRCD_EXCEPTION(ircd::error, error);
|
||||
IRCD_EXCEPTION(error, generator_error);
|
||||
IRCD_EXCEPTION(generator_error, buffer_overrun);
|
||||
|
||||
// parse.cc
|
||||
extern thread_local char rule_buffer[64];
|
||||
extern thread_local struct generator_state *generator_state;
|
||||
}}
|
||||
|
||||
namespace ircd
|
||||
__attribute__((visibility("default")))
|
||||
{
|
||||
template<class parent_error,
|
||||
class it = const char *,
|
||||
class... args>
|
||||
bool parse(args&&...);
|
||||
|
||||
template<bool truncation = false,
|
||||
class gen,
|
||||
class... attr>
|
||||
bool generate(mutable_buffer &out, gen&&, attr&&...);
|
||||
}
|
||||
|
||||
namespace ircd {
|
||||
namespace spirit
|
||||
__attribute__((visibility("hidden")))
|
||||
|
@ -180,6 +162,41 @@ namespace ircd::spirit::local
|
|||
using qi::_3;
|
||||
}
|
||||
|
||||
namespace ircd {
|
||||
namespace spirit
|
||||
__attribute__((visibility("default")))
|
||||
{
|
||||
// parse.cc
|
||||
extern thread_local char rule_buffer[64];
|
||||
extern thread_local struct generator_state *generator_state;
|
||||
}}
|
||||
|
||||
namespace ircd {
|
||||
namespace spirit
|
||||
__attribute__((visibility("internal")))
|
||||
{
|
||||
template<class gen,
|
||||
class... attr>
|
||||
bool parse(const char *&start, const char *const &stop, gen&&, attr&&...);
|
||||
|
||||
template<class parent_error,
|
||||
size_t error_show_max = 48,
|
||||
class gen,
|
||||
class... attr>
|
||||
bool parse(const char *&start, const char *const &stop, gen&&, attr&&...);
|
||||
|
||||
template<bool truncation = false,
|
||||
class gen,
|
||||
class... attr>
|
||||
bool generate(mutable_buffer &out, gen&&, attr&&...);
|
||||
}}
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
using spirit::generate;
|
||||
using spirit::parse;
|
||||
}
|
||||
|
||||
namespace ircd {
|
||||
namespace spirit
|
||||
__attribute__((visibility("default")))
|
||||
|
@ -245,7 +262,8 @@ ircd::spirit::expectation_failure<parent>::expectation_failure(const qi::expecta
|
|||
}
|
||||
{}
|
||||
|
||||
struct ircd::spirit::generator_state
|
||||
struct [[gnu::visibility("hidden")]]
|
||||
ircd::spirit::generator_state
|
||||
{
|
||||
/// Destination buffer (used like window_buffer).
|
||||
mutable_buffer &out;
|
||||
|
@ -269,25 +287,23 @@ struct ircd::spirit::generator_state
|
|||
template<bool truncation,
|
||||
class gen,
|
||||
class... attr>
|
||||
inline bool
|
||||
ircd::generate(mutable_buffer &out,
|
||||
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
|
||||
extern inline bool
|
||||
ircd::spirit::generate(mutable_buffer &out,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
|
||||
{
|
||||
using namespace ircd::spirit;
|
||||
namespace spirit = ircd::spirit;
|
||||
|
||||
const auto max(size(out));
|
||||
const auto start(data(out));
|
||||
struct spirit::generator_state state
|
||||
struct generator_state state
|
||||
{
|
||||
out
|
||||
};
|
||||
|
||||
const scope_restore _state
|
||||
{
|
||||
spirit::generator_state, &state
|
||||
generator_state, &state
|
||||
};
|
||||
|
||||
sink_type sink
|
||||
|
@ -317,7 +333,7 @@ ircd::generate(mutable_buffer &out,
|
|||
std::distance(start, begin(out))
|
||||
};
|
||||
|
||||
throw spirit::buffer_overrun
|
||||
throw buffer_overrun
|
||||
{
|
||||
"Insufficient buffer of %s; required at least %s",
|
||||
pretty(pbuf[0], iec(max)),
|
||||
|
@ -331,17 +347,37 @@ ircd::generate(mutable_buffer &out,
|
|||
}
|
||||
|
||||
template<class parent_error,
|
||||
class it,
|
||||
class... args>
|
||||
inline bool
|
||||
ircd::parse(args&&... a)
|
||||
size_t error_show_max,
|
||||
class gen,
|
||||
class... attr>
|
||||
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
|
||||
extern inline bool
|
||||
ircd::spirit::parse(const char *&start,
|
||||
const char *const &stop,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
try
|
||||
{
|
||||
return spirit::qi::parse(std::forward<args>(a)...);
|
||||
return qi::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
|
||||
}
|
||||
catch(const spirit::qi::expectation_failure<it> &e)
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw spirit::expectation_failure<parent_error>(e);
|
||||
throw expectation_failure<parent_error>
|
||||
{
|
||||
e, start, error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
[[using gnu: flatten, always_inline, gnu_inline, artificial]]
|
||||
extern inline bool
|
||||
ircd::spirit::parse(const char *&start,
|
||||
const char *const &stop,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
{
|
||||
return qi::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
|
||||
}
|
||||
|
||||
template<size_t idx,
|
||||
|
|
|
@ -398,7 +398,7 @@ ircd::fmt::snprintf::argument(const arg &val)
|
|||
fmt::spec spec;
|
||||
auto &start(begin(this->fmt));
|
||||
const auto stop(end(this->fmt));
|
||||
if(qi::parse(start, stop, parser, spec))
|
||||
if(ircd::parse<invalid_format>(start, stop, parser, spec))
|
||||
handle_specifier(this->out, idx++, spec, val);
|
||||
|
||||
string_view fmt
|
||||
|
|
36
ircd/http.cc
36
ircd/http.cc
|
@ -218,9 +218,25 @@ struct ircd::http::parser
|
|||
:grammar
|
||||
{
|
||||
static size_t content_length(const string_view &val);
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
bool operator()(const char *&start, const char *const &stop, gen&&, attr&&...) const;
|
||||
}
|
||||
const ircd::http::parser;
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
inline bool
|
||||
ircd::http::parser::operator()(const char *&start,
|
||||
const char *const &stop,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
const
|
||||
{
|
||||
return ircd::parse(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
|
||||
}
|
||||
|
||||
namespace ircd { namespace http
|
||||
__attribute__((visibility("default")))
|
||||
{
|
||||
|
@ -600,7 +616,7 @@ try
|
|||
const char *start(line::begin());
|
||||
const auto res
|
||||
{
|
||||
qi::parse(start, line::end(), grammar, this->size)
|
||||
parser(start, line::end(), grammar, this->size)
|
||||
};
|
||||
|
||||
assert(res == true);
|
||||
|
@ -753,7 +769,7 @@ try
|
|||
|
||||
const char *start(line.data());
|
||||
const char *const stop(line.data() + line.size());
|
||||
qi::parse(start, stop, grammar, *this);
|
||||
parser(start, stop, grammar, *this);
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
|
@ -769,7 +785,7 @@ ircd::http::line::response::response(const line &line)
|
|||
|
||||
const char *start(line.data());
|
||||
const char *const stop(line.data() + line.size());
|
||||
qi::parse(start, stop, grammar, *this);
|
||||
parser(start, stop, grammar, *this);
|
||||
}
|
||||
|
||||
ircd::http::line::request::request(const line &line)
|
||||
|
@ -782,7 +798,7 @@ try
|
|||
|
||||
const char *start(line.data());
|
||||
const char *const stop(line.data() + line.size());
|
||||
qi::parse(start, stop, grammar, *this);
|
||||
parser(start, stop, grammar, *this);
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
|
@ -825,7 +841,7 @@ ircd::http::line::line(parse::capstan &pc)
|
|||
string_view ret;
|
||||
pc([&ret](const char *&start, const char *const &stop)
|
||||
{
|
||||
if(!qi::parse(start, stop, grammar, ret))
|
||||
if(!parser(start, stop, grammar, ret))
|
||||
{
|
||||
ret = {};
|
||||
return false;
|
||||
|
@ -996,7 +1012,7 @@ const
|
|||
|
||||
const string_view &s(*this);
|
||||
const char *start(s.begin()), *const stop(s.end());
|
||||
qi::parse(start, stop, grammar);
|
||||
parser(start, stop, grammar);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1016,7 +1032,7 @@ ircd::http::parser::content_length(const string_view &str)
|
|||
const char *start(str.data());
|
||||
const bool parsed
|
||||
{
|
||||
qi::parse(start, start + str.size(), grammar, ret)
|
||||
http::parser(start, start + str.size(), grammar, ret)
|
||||
};
|
||||
|
||||
if(!parsed || ret >= 256_GiB)
|
||||
|
@ -1235,7 +1251,11 @@ ircd::http::status(const string_view &str)
|
|||
|
||||
short ret;
|
||||
const char *start(str.data());
|
||||
const bool parsed(qi::parse(start, start + str.size(), grammar, ret));
|
||||
const bool parsed
|
||||
{
|
||||
parser(start, start + str.size(), grammar, ret)
|
||||
};
|
||||
|
||||
if(!parsed || ret < 0 || ret >= 1000)
|
||||
throw ircd::error
|
||||
{
|
||||
|
|
140
ircd/json.cc
140
ircd/json.cc
|
@ -16,8 +16,6 @@ namespace ircd::json
|
|||
// Instantiations of the grammars
|
||||
struct parser extern const parser;
|
||||
struct printer extern const printer;
|
||||
|
||||
const size_t &error_show_max {48};
|
||||
}
|
||||
#pragma GCC visibility pop
|
||||
|
||||
|
@ -189,6 +187,14 @@ ircd::json::parser
|
|||
,"value"
|
||||
};
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
bool operator()(const char *&start, const char *const &stop, gen&&, attr&&...) const;
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
bool operator()(const char *const &start, const char *const &stop, gen&&, attr&&...) const;
|
||||
|
||||
parser()
|
||||
:parser::base_type{rule<>{}} // required by spirit
|
||||
{
|
||||
|
@ -460,8 +466,8 @@ noexcept
|
|||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
[[gnu::visibility("internal")]]
|
||||
void
|
||||
[[using gnu: always_inline, gnu_inline, artificial]]
|
||||
extern inline void
|
||||
ircd::json::printer::operator()(mutable_buffer &out,
|
||||
gen&& g,
|
||||
attr&&... a)
|
||||
|
@ -475,8 +481,8 @@ const
|
|||
}
|
||||
|
||||
template<class gen>
|
||||
[[gnu::visibility("internal")]]
|
||||
void
|
||||
[[using gnu: always_inline, gnu_inline, artificial]]
|
||||
extern inline void
|
||||
ircd::json::printer::operator()(mutable_buffer &out,
|
||||
gen&& g)
|
||||
const
|
||||
|
@ -491,8 +497,8 @@ const
|
|||
template<class it_a,
|
||||
class it_b,
|
||||
class closure>
|
||||
[[gnu::visibility("internal")]]
|
||||
inline void
|
||||
[[using gnu: always_inline, gnu_inline, artificial]]
|
||||
extern inline void
|
||||
ircd::json::printer::list_protocol(mutable_buffer &out,
|
||||
it_a it,
|
||||
const it_b &end,
|
||||
|
@ -503,14 +509,40 @@ ircd::json::printer::list_protocol(mutable_buffer &out,
|
|||
lambda(out, *it);
|
||||
for(++it; it != end; ++it)
|
||||
{
|
||||
static const auto &printer(json::printer);
|
||||
const auto &printer(json::printer);
|
||||
printer(out, printer.value_sep);
|
||||
lambda(out, *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[gnu::visibility("internal")]]
|
||||
template<class gen,
|
||||
class... attr>
|
||||
[[using gnu: always_inline, gnu_inline, artificial]]
|
||||
extern inline bool
|
||||
ircd::json::parser::operator()(const char *const &start_,
|
||||
const char *const &stop,
|
||||
gen&& g,
|
||||
attr&&...a)
|
||||
const
|
||||
{
|
||||
const char *start(start_);
|
||||
return operator()(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
|
||||
}
|
||||
|
||||
template<class gen,
|
||||
class... attr>
|
||||
[[using gnu: always_inline, gnu_inline, artificial]]
|
||||
extern inline bool
|
||||
ircd::json::parser::operator()(const char *&start,
|
||||
const char *const &stop,
|
||||
gen&& g,
|
||||
attr&&...a)
|
||||
const
|
||||
{
|
||||
return ircd::parse<parse_error>(start, stop, std::forward<gen>(g), std::forward<attr>(a)...);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::json::parser::throws_exceeded()
|
||||
{
|
||||
|
@ -2407,7 +2439,7 @@ const
|
|||
|
||||
ircd::json::vector::const_iterator
|
||||
ircd::json::vector::begin()
|
||||
const try
|
||||
const
|
||||
{
|
||||
const_iterator ret
|
||||
{
|
||||
|
@ -2415,16 +2447,9 @@ const try
|
|||
};
|
||||
|
||||
string_view &state(ret.state);
|
||||
qi::parse(ret.start, ret.stop, vector_begin_parse, state);
|
||||
parser(ret.start, ret.stop, vector_begin_parse, state);
|
||||
return ret;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, string_view::data(), error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// vector::const_iterator::const_iterator
|
||||
|
@ -2432,20 +2457,12 @@ catch(const qi::expectation_failure<const char *> &e)
|
|||
|
||||
ircd::json::vector::const_iterator &
|
||||
ircd::json::vector::const_iterator::operator++()
|
||||
try
|
||||
{
|
||||
this->state = {};
|
||||
string_view &state(this->state);
|
||||
qi::parse(start, stop, vector_next_parse, state);
|
||||
parser(start, stop, vector_next_parse, state);
|
||||
return *this;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, start, error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -2689,10 +2706,10 @@ const try
|
|||
string_view::begin(), string_view::end()
|
||||
};
|
||||
|
||||
qi::parse(ret.start, ret.stop, object_begin_parse, ret.state);
|
||||
parser(ret.start, ret.stop, object_begin_parse, ret.state);
|
||||
return ret;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
catch(const expectation_failure<parse_error> &e)
|
||||
{
|
||||
const auto type
|
||||
{
|
||||
|
@ -2702,13 +2719,11 @@ catch(const qi::expectation_failure<const char *> &e)
|
|||
if(type != type::OBJECT)
|
||||
throw type_error
|
||||
{
|
||||
"Expected JSON type OBJECT, not %s.", reflect(type)
|
||||
"Expected JSON type OBJECT, not %s.",
|
||||
reflect(type)
|
||||
};
|
||||
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, string_view::begin(), error_show_max
|
||||
};
|
||||
throw;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2717,21 +2732,13 @@ catch(const qi::expectation_failure<const char *> &e)
|
|||
|
||||
ircd::json::object::const_iterator &
|
||||
ircd::json::object::const_iterator::operator++()
|
||||
try
|
||||
{
|
||||
assert(start != stop);
|
||||
|
||||
state = {};
|
||||
qi::parse(start, stop, object_next_parse, state);
|
||||
parser(start, stop, object_next_parse, state);
|
||||
return *this;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, start, error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// object::member
|
||||
|
@ -3005,23 +3012,16 @@ const
|
|||
|
||||
ircd::json::array::const_iterator
|
||||
ircd::json::array::begin()
|
||||
const try
|
||||
const
|
||||
{
|
||||
const_iterator ret
|
||||
{
|
||||
string_view::begin(), string_view::end()
|
||||
};
|
||||
|
||||
qi::parse(ret.start, ret.stop, array_begin_parse, ret.state);
|
||||
parser(ret.start, ret.stop, array_begin_parse, ret.state);
|
||||
return ret;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, string_view::data(), error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::json::array::operator[](const size_t &i)
|
||||
|
@ -3087,21 +3087,13 @@ const
|
|||
|
||||
ircd::json::array::const_iterator &
|
||||
ircd::json::array::const_iterator::operator++()
|
||||
try
|
||||
{
|
||||
assert(start != stop);
|
||||
|
||||
state = string_view{};
|
||||
qi::parse(start, stop, array_next_parse, state);
|
||||
parser(start, stop, array_next_parse, state);
|
||||
return *this;
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, start, error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -4064,7 +4056,7 @@ ircd::json::valid(const string_view &s,
|
|||
noexcept try
|
||||
{
|
||||
const char *start(begin(s)), *const stop(end(s));
|
||||
return qi::parse(start, stop, validation);
|
||||
return parser(start, stop, validation);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -4074,23 +4066,15 @@ catch(...)
|
|||
|
||||
void
|
||||
ircd::json::valid(const string_view &s)
|
||||
try
|
||||
{
|
||||
const char *start(begin(s)), *const stop(end(s));
|
||||
const bool ret
|
||||
{
|
||||
qi::parse(start, stop, validation_expect)
|
||||
parser(start, stop, validation_expect)
|
||||
};
|
||||
|
||||
assert(ret);
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
throw expectation_failure<parse_error>
|
||||
{
|
||||
e, begin(s), error_show_max
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::json::valid_output(const string_view &sv,
|
||||
|
@ -4210,7 +4194,7 @@ ircd::json::type(const string_view &buf,
|
|||
{
|
||||
const bool ret
|
||||
{
|
||||
qi::parse(begin(buf), end(buf), type_parse_is[type])
|
||||
parser(begin(buf), end(buf), type_parse_is[type])
|
||||
};
|
||||
|
||||
return ret;
|
||||
|
@ -4223,7 +4207,7 @@ ircd::json::type(const string_view &buf,
|
|||
{
|
||||
const bool ret
|
||||
{
|
||||
qi::parse(begin(buf), end(buf), type_parse_is_strict[type])
|
||||
parser(begin(buf), end(buf), type_parse_is_strict[type])
|
||||
};
|
||||
|
||||
return ret;
|
||||
|
@ -4233,7 +4217,7 @@ enum ircd::json::type
|
|||
ircd::json::type(const string_view &buf)
|
||||
{
|
||||
enum type ret;
|
||||
if(!qi::parse(begin(buf), end(buf), type_parse, ret))
|
||||
if(!parser(begin(buf), end(buf), type_parse, ret))
|
||||
throw type_error
|
||||
{
|
||||
"Failed to derive JSON value type from input buffer."
|
||||
|
@ -4247,7 +4231,7 @@ ircd::json::type(const string_view &buf,
|
|||
std::nothrow_t)
|
||||
{
|
||||
enum type ret;
|
||||
if(!qi::parse(begin(buf), end(buf), type_parse, ret))
|
||||
if(!parser(begin(buf), end(buf), type_parse, ret))
|
||||
return STRING;
|
||||
|
||||
return ret;
|
||||
|
@ -4258,7 +4242,7 @@ ircd::json::type(const string_view &buf,
|
|||
strict_t)
|
||||
{
|
||||
enum type ret;
|
||||
if(!qi::parse(begin(buf), end(buf), type_parse_strict, ret))
|
||||
if(!parser(begin(buf), end(buf), type_parse_strict, ret))
|
||||
throw type_error
|
||||
{
|
||||
"Failed to derive JSON value type from input buffer."
|
||||
|
@ -4273,7 +4257,7 @@ ircd::json::type(const string_view &buf,
|
|||
std::nothrow_t)
|
||||
{
|
||||
enum type ret;
|
||||
if(!qi::parse(begin(buf), end(buf), type_parse_strict, ret))
|
||||
if(!parser(begin(buf), end(buf), type_parse_strict, ret))
|
||||
return STRING;
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -422,7 +422,7 @@ try
|
|||
parse::head
|
||||
};
|
||||
|
||||
qi::parse(start, stop, grammar, *this);
|
||||
ircd::parse(start, stop, grammar, *this);
|
||||
}
|
||||
catch(const qi::expectation_failure<const char *> &e)
|
||||
{
|
||||
|
|
|
@ -388,12 +388,7 @@ ircd::m::vm::fetch::state(const event &event,
|
|||
try
|
||||
{
|
||||
const event::prev prev{event};
|
||||
const size_t prev_miss
|
||||
{
|
||||
prev.prev_events_count() - prev.prev_events_exist()
|
||||
};
|
||||
|
||||
if(!prev_miss)
|
||||
if(prev.prev_exist())
|
||||
return;
|
||||
|
||||
const auto &[sounding_depth, sounding_idx]
|
||||
|
|
Loading…
Reference in a new issue