Refactoring of parameter garammars

* signature changed from void() to void(engine::api::Parameters&)
* performance increase due to use "static const GrammarT" and avoid
  construction and destruction of grammars during parsing
* removed code duplication in inherited grammars
* rule unlimited changed to qi::lit
* added rule size_t_
* parser accepts "&geometries=" and "&overview=" and fails at "foo"
  instead of "&geometries=foo" and &overview=foo
* added expectations checks for derived grammars
* changed rules qi::list(".") to character rules '.'
This commit is contained in:
Michael Krasnyk
2016-04-20 20:40:17 +02:00
parent 82372bb2ab
commit dac2f93383
11 changed files with 298 additions and 290 deletions
+22 -29
View File
@@ -19,28 +19,28 @@ namespace api
namespace detail
{
template <typename T>
using is_grammar_t = std::integral_constant<bool,
std::is_base_of<BaseParametersGrammar, T>::value ||
std::is_same<TileParametersGrammar, T>::value>;
using is_grammar_t = std::integral_constant<bool, std::is_same<RouteParametersGrammar<>, T>::value ||
std::is_same<TableParametersGrammar<>, T>::value || std::is_same<NearestParametersGrammar<>, T>::value ||
std::is_same<TripParametersGrammar<>, T>::value || std::is_same<MatchParametersGrammar<>, T>::value ||
std::is_same<TileParametersGrammar<>, T>::value>;
template <typename ParameterT,
typename GrammarT,
template <typename ParameterT, typename GrammarT,
typename std::enable_if<detail::is_parameter_t<ParameterT>::value, int>::type = 0,
typename std::enable_if<detail::is_grammar_t<GrammarT>::value, int>::type = 0>
boost::optional<ParameterT> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<ParameterT> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
using It = std::decay<decltype(iter)>::type;
GrammarT grammar;
static const GrammarT grammar;
try
{
const auto ok = boost::spirit::qi::parse(iter, end, grammar);
ParameterT parameters;
const auto ok = boost::spirit::qi::parse(iter, end, grammar(boost::phoenix::ref(parameters)));
// return move(a.b) is needed to move b out of a and then return the rvalue by implicit move
if (ok && iter == end)
return std::move(grammar.parameters);
return std::move(parameters);
}
catch (const qi::expectation_failure<It> &failure)
{
@@ -54,46 +54,39 @@ boost::optional<ParameterT> parseParameters(std::string::iterator &iter,
} // ns detail
template <>
boost::optional<engine::api::RouteParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::RouteParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::RouteParameters, RouteParametersGrammar>(iter, end);
return detail::parseParameters<engine::api::RouteParameters, RouteParametersGrammar<>>(iter, end);
}
template <>
boost::optional<engine::api::TableParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::TableParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::TableParameters, TableParametersGrammar>(iter, end);
return detail::parseParameters<engine::api::TableParameters, TableParametersGrammar<>>(iter, end);
}
template <>
boost::optional<engine::api::NearestParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::NearestParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::NearestParameters, NearestParametersGrammar>(iter,
end);
return detail::parseParameters<engine::api::NearestParameters, NearestParametersGrammar<>>(iter, end);
}
template <>
boost::optional<engine::api::TripParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::TripParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::TripParameters, TripParametersGrammar>(iter, end);
return detail::parseParameters<engine::api::TripParameters, TripParametersGrammar<>>(iter, end);
}
template <>
boost::optional<engine::api::MatchParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::MatchParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar>(iter, end);
return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar<>>(iter, end);
}
template <>
boost::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter,
const std::string::iterator end)
boost::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end)
{
return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar>(iter, end);
return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar<>>(iter, end);
}
} // ns api