update boost
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
#include <boost/spirit/home/x3/core/parser.hpp>
|
||||
#include <boost/spirit/home/x3/core/skip_over.hpp>
|
||||
#include <boost/spirit/home/x3/directive/expect.hpp>
|
||||
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
|
||||
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
|
||||
@@ -20,6 +19,8 @@
|
||||
#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
template <typename ID>
|
||||
@@ -32,6 +33,9 @@ namespace boost { namespace spirit { namespace x3
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename ID>
|
||||
struct rule_id {};
|
||||
|
||||
// we use this so we can detect if the default parse_rule
|
||||
// is the being called.
|
||||
struct default_parse_rule_result
|
||||
@@ -44,11 +48,11 @@ namespace boost { namespace spirit { namespace x3
|
||||
}
|
||||
|
||||
// default parse_rule implementation
|
||||
template <typename ID, typename Attribute, typename Iterator
|
||||
template <typename ID, typename Iterator
|
||||
, typename Context, typename ActualAttribute>
|
||||
inline detail::default_parse_rule_result
|
||||
parse_rule(
|
||||
rule<ID, Attribute> rule_
|
||||
detail::rule_id<ID>
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, ActualAttribute& attr);
|
||||
}}}
|
||||
@@ -93,15 +97,14 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
|
||||
template <typename ID, typename Iterator, typename Context>
|
||||
struct has_on_error<ID, Iterator, Context,
|
||||
typename disable_if_substitution_failure<
|
||||
decltype(
|
||||
decltype(void(
|
||||
std::declval<ID>().on_error(
|
||||
std::declval<Iterator&>()
|
||||
, std::declval<Iterator>()
|
||||
, std::declval<expectation_failure<Iterator>>()
|
||||
, std::declval<Context>()
|
||||
)
|
||||
)>::type
|
||||
))
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
@@ -111,15 +114,14 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
|
||||
template <typename ID, typename Iterator, typename Attribute, typename Context>
|
||||
struct has_on_success<ID, Iterator, Context, Attribute,
|
||||
typename disable_if_substitution_failure<
|
||||
decltype(
|
||||
decltype(void(
|
||||
std::declval<ID>().on_success(
|
||||
std::declval<Iterator&>()
|
||||
, std::declval<Iterator>()
|
||||
, std::declval<Iterator&>()
|
||||
, std::declval<Attribute&>()
|
||||
, std::declval<Context>()
|
||||
)
|
||||
)>::type
|
||||
))
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
@@ -151,12 +153,12 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
return make_unique_context<ID>(rhs, context);
|
||||
}
|
||||
|
||||
template <typename Attribute, typename ID>
|
||||
template <typename Attribute, typename ID, bool skip_definition_injection = false>
|
||||
struct rule_parser
|
||||
{
|
||||
template <typename Iterator, typename Context, typename ActualAttribute>
|
||||
static bool call_on_success(
|
||||
Iterator& /* first */, Iterator const& /* last */
|
||||
Iterator& /* before */, Iterator& /* after */
|
||||
, Context const& /* context */, ActualAttribute& /* attr */
|
||||
, mpl::false_ /* No on_success handler */ )
|
||||
{
|
||||
@@ -165,14 +167,15 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
|
||||
template <typename Iterator, typename Context, typename ActualAttribute>
|
||||
static bool call_on_success(
|
||||
Iterator& first, Iterator const& last
|
||||
Iterator& before, Iterator& after
|
||||
, Context const& context, ActualAttribute& attr
|
||||
, mpl::true_ /* Has on_success handler */)
|
||||
{
|
||||
x3::skip_over(before, after, context);
|
||||
bool pass = true;
|
||||
ID().on_success(
|
||||
first
|
||||
, last
|
||||
before
|
||||
, after
|
||||
, attr
|
||||
, make_context<parse_pass_context_tag>(pass, context)
|
||||
);
|
||||
@@ -190,8 +193,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
// see if the user has a BOOST_SPIRIT_DEFINE for this rule
|
||||
typedef
|
||||
decltype(parse_rule(
|
||||
rule<ID, Attribute>(), first, last
|
||||
, make_unique_context<ID>(rhs, context), attr))
|
||||
detail::rule_id<ID>{}, first, last
|
||||
, make_unique_context<ID>(rhs, context), std::declval<Attribute&>()))
|
||||
parse_rule_result;
|
||||
|
||||
// If there is no BOOST_SPIRIT_DEFINE for this rule,
|
||||
@@ -202,25 +205,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
is_same<parse_rule_result, default_parse_rule_result>
|
||||
is_default_parse_rule;
|
||||
|
||||
Iterator i = first;
|
||||
Iterator start = first;
|
||||
bool r = rhs.parse(
|
||||
i
|
||||
first
|
||||
, last
|
||||
, make_rule_context<ID>(rhs, context, is_default_parse_rule())
|
||||
, make_rule_context<ID>(rhs, context, std::conditional_t<skip_definition_injection, mpl::false_, is_default_parse_rule>())
|
||||
, rcontext
|
||||
, attr
|
||||
);
|
||||
|
||||
if (r)
|
||||
{
|
||||
auto first_ = first;
|
||||
x3::skip_over(first_, last, context);
|
||||
r = call_on_success(first_, i, context, attr
|
||||
r = call_on_success(start, first, context, attr
|
||||
, has_on_success<ID, Iterator, Context, ActualAttribute>());
|
||||
}
|
||||
|
||||
if (r)
|
||||
first = i;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
|
||||
#define SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
|
||||
#ifndef BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
|
||||
#define BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
|
||||
|
||||
#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
|
||||
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
|
||||
@@ -25,9 +25,9 @@ namespace boost { namespace spirit { namespace x3
|
||||
|
||||
static Transformed pre(Exposed&) { return Transformed(); }
|
||||
|
||||
static void post(Exposed& val, Transformed&& attr)
|
||||
static void post(Exposed& val, Transformed&& attribute)
|
||||
{
|
||||
traits::move_to(std::forward<Transformed>(attr), val);
|
||||
traits::move_to(std::forward<Transformed>(attribute), val);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,26 +22,26 @@
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
// default parse_rule implementation
|
||||
template <typename ID, typename Attribute, typename Iterator
|
||||
template <typename ID, typename Iterator
|
||||
, typename Context, typename ActualAttribute>
|
||||
inline detail::default_parse_rule_result
|
||||
parse_rule(
|
||||
rule<ID, Attribute> /* rule_ */
|
||||
detail::rule_id<ID>
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, ActualAttribute& attr)
|
||||
{
|
||||
static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
|
||||
static_assert(!is_same<decltype(x3::get<ID>(context)), unused_type>::value,
|
||||
"BOOST_SPIRIT_DEFINE undefined for this rule.");
|
||||
return get<ID>(context).parse(first, last, context, unused, attr);
|
||||
return x3::get<ID>(context).parse(first, last, context, unused, attr);
|
||||
}
|
||||
|
||||
template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
|
||||
struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
|
||||
template <typename ID, typename RHS, typename Attribute, bool force_attribute_, bool skip_definition_injection = false>
|
||||
struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection>>
|
||||
{
|
||||
typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
|
||||
typedef rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection> this_type;
|
||||
typedef ID id;
|
||||
typedef RHS rhs_type;
|
||||
typedef rule<ID, Attribute> lhs_type;
|
||||
typedef rule<ID, Attribute, force_attribute_> lhs_type;
|
||||
typedef Attribute attribute_type;
|
||||
|
||||
static bool const has_attribute =
|
||||
@@ -51,14 +51,14 @@ namespace boost { namespace spirit { namespace x3
|
||||
static bool const force_attribute =
|
||||
force_attribute_;
|
||||
|
||||
rule_definition(RHS const& rhs, char const* name)
|
||||
constexpr rule_definition(RHS const& rhs, char const* name)
|
||||
: rhs(rhs), name(name) {}
|
||||
|
||||
template <typename Iterator, typename Context, typename Attribute_>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context const& context, unused_type, Attribute_& attr) const
|
||||
{
|
||||
return detail::rule_parser<attribute_type, ID>
|
||||
return detail::rule_parser<attribute_type, ID, skip_definition_injection>
|
||||
::call_rule_definition(
|
||||
rhs, name, first, last
|
||||
, context
|
||||
@@ -71,8 +71,11 @@ namespace boost { namespace spirit { namespace x3
|
||||
};
|
||||
|
||||
template <typename ID, typename Attribute, bool force_attribute_>
|
||||
struct rule : parser<rule<ID, Attribute>>
|
||||
struct rule : parser<rule<ID, Attribute, force_attribute_>>
|
||||
{
|
||||
static_assert(!std::is_reference<Attribute>::value,
|
||||
"Reference qualifier on rule attribute type is meaningless");
|
||||
|
||||
typedef ID id;
|
||||
typedef Attribute attribute_type;
|
||||
static bool const has_attribute =
|
||||
@@ -84,24 +87,53 @@ namespace boost { namespace spirit { namespace x3
|
||||
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
|
||||
rule() : name(typeid(rule).name()) {}
|
||||
#else
|
||||
rule() : name("unnamed") {}
|
||||
constexpr rule() : name("unnamed") {}
|
||||
#endif
|
||||
|
||||
rule(char const* name)
|
||||
constexpr rule(char const* name)
|
||||
: name(name) {}
|
||||
|
||||
constexpr rule(rule const& r)
|
||||
: name(r.name)
|
||||
{
|
||||
// Assert that we are not copying an unitialized static rule. If
|
||||
// the static is in another TU, it may be initialized after we copy
|
||||
// it. If so, its name member will be nullptr.
|
||||
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
rule_definition<
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
|
||||
operator=(RHS const& rhs) const
|
||||
operator=(RHS const& rhs) const&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
rule_definition<
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
|
||||
operator%=(RHS const& rhs) const
|
||||
operator%=(RHS const& rhs) const&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
// When a rule placeholder constructed and immediately consumed it cannot be used recursively,
|
||||
// that's why the rule definition injection into a parser context can be skipped.
|
||||
// This optimization has a huge impact on compile times because immediate rules are commonly
|
||||
// used to cast an attribute like `as`/`attr_cast` does in Qi.
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_, true>
|
||||
operator=(RHS const& rhs) const&&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, true, true>
|
||||
operator%=(RHS const& rhs) const&&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
@@ -120,7 +152,7 @@ namespace boost { namespace spirit { namespace x3
|
||||
using transform_attr = typename transform::type;
|
||||
transform_attr attr_ = transform::pre(attr);
|
||||
|
||||
if (parse_rule(*this, first, last, context, attr_)) {
|
||||
if (parse_rule(detail::rule_id<ID>{}, first, last, context, attr_)) {
|
||||
transform::post(attr, std::forward<transform_attr>(attr_));
|
||||
return true;
|
||||
}
|
||||
@@ -131,12 +163,9 @@ namespace boost { namespace spirit { namespace x3
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context const& context, unused_type, unused_type) const
|
||||
{
|
||||
static_assert(!has_attribute,
|
||||
"The rule requires an input attribute. Check your parser.");
|
||||
|
||||
// make sure we pass exactly the rule attribute type
|
||||
attribute_type no_attr;
|
||||
return parse_rule(*this, first, last, context, no_attr);
|
||||
attribute_type no_attr{};
|
||||
return parse_rule(detail::rule_id<ID>{}, first, last, context, no_attr);
|
||||
}
|
||||
|
||||
char const* name;
|
||||
@@ -147,11 +176,11 @@ namespace boost { namespace spirit { namespace x3
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_rule : mpl::false_ {};
|
||||
|
||||
template <typename ID, typename Attribute>
|
||||
struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
|
||||
template <typename ID, typename Attribute, bool force_attribute>
|
||||
struct is_rule<rule<ID, Attribute, force_attribute>> : mpl::true_ {};
|
||||
|
||||
template <typename ID, typename Attribute, typename RHS, bool force_attribute>
|
||||
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
|
||||
template <typename ID, typename Attribute, typename RHS, bool force_attribute, bool skip_definition_injection>
|
||||
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute, skip_definition_injection>> : mpl::true_ {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -168,7 +197,7 @@ namespace boost { namespace spirit { namespace x3
|
||||
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
|
||||
template <typename Iterator, typename Context> \
|
||||
bool parse_rule( \
|
||||
rule_type rule_ \
|
||||
::boost::spirit::x3::detail::rule_id<rule_type::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, rule_type::attribute_type& attr); \
|
||||
/***/
|
||||
@@ -182,26 +211,34 @@ namespace boost { namespace spirit { namespace x3
|
||||
using BOOST_PP_CAT(rule_name, _synonym) = decltype(rule_name); \
|
||||
template <typename Iterator, typename Context> \
|
||||
inline bool parse_rule( \
|
||||
BOOST_PP_CAT(rule_name, _synonym) /* rule_ */ \
|
||||
::boost::spirit::x3::detail::rule_id<BOOST_PP_CAT(rule_name, _synonym)::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, BOOST_PP_CAT(rule_name, _synonym)::attribute_type& attr) \
|
||||
{ \
|
||||
using boost::spirit::x3::unused; \
|
||||
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
|
||||
return def_.parse(first, last, context, unused, attr); \
|
||||
using rule_t = BOOST_JOIN(rule_name, _synonym); \
|
||||
return ::boost::spirit::x3::detail \
|
||||
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
|
||||
::call_rule_definition( \
|
||||
BOOST_JOIN(rule_name, _def), rule_name.name \
|
||||
, first, last, context, attr \
|
||||
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
|
||||
} \
|
||||
/***/
|
||||
#else
|
||||
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
|
||||
template <typename Iterator, typename Context> \
|
||||
inline bool parse_rule( \
|
||||
decltype(rule_name) /* rule_ */ \
|
||||
::boost::spirit::x3::detail::rule_id<decltype(rule_name)::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, decltype(rule_name)::attribute_type& attr) \
|
||||
{ \
|
||||
using boost::spirit::x3::unused; \
|
||||
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
|
||||
return def_.parse(first, last, context, unused, attr); \
|
||||
using rule_t = decltype(rule_name); \
|
||||
return ::boost::spirit::x3::detail \
|
||||
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
|
||||
::call_rule_definition( \
|
||||
BOOST_JOIN(rule_name, _def), rule_name.name \
|
||||
, first, last, context, attr \
|
||||
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
|
||||
} \
|
||||
/***/
|
||||
#endif
|
||||
@@ -212,7 +249,7 @@ namespace boost { namespace spirit { namespace x3
|
||||
|
||||
#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
|
||||
template bool parse_rule<Iterator, Context>( \
|
||||
rule_type rule_ \
|
||||
::boost::spirit::x3::detail::rule_id<rule_type::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, rule_type::attribute_type&); \
|
||||
/***/
|
||||
|
||||
Reference in New Issue
Block a user