mirror of
https://github.com/boostorg/spirit.git
synced 2026-01-19 16:52:10 +00:00
bug fix for x3 where container attribute is substitute for the container value type. happens with recursive data structures such as vector<v> where v is a variant that also contains vector<v>.
This commit is contained in:
@@ -75,6 +75,13 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Parser, typename Container, typename Context>
|
||||
struct parser_accepts_container
|
||||
: traits::is_substitute<
|
||||
typename traits::attribute_of<Parser, Context>::type
|
||||
, Container
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Parser>
|
||||
struct parse_into_container_base_impl
|
||||
@@ -84,10 +91,10 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
// Parser has attribute (synthesize; Attribute is a container)
|
||||
template <typename Iterator, typename Context
|
||||
, typename RContext, typename Attribute>
|
||||
static bool call_synthesize(
|
||||
static bool call_synthesize_x(
|
||||
Parser const& parser
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr)
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
|
||||
{
|
||||
// synthesized attribute needs to be value initialized
|
||||
typedef typename
|
||||
@@ -103,6 +110,33 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parser has attribute (synthesize; Attribute is a container)
|
||||
template <typename Iterator, typename Context
|
||||
, typename RContext, typename Attribute>
|
||||
static bool call_synthesize_x(
|
||||
Parser const& parser
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
|
||||
{
|
||||
return parser.parse(first, last, context, rcontext, attr);
|
||||
}
|
||||
|
||||
// Parser has attribute (synthesize; Attribute is a container)
|
||||
template <typename Iterator, typename Context
|
||||
, typename RContext, typename Attribute>
|
||||
static bool call_synthesize(
|
||||
Parser const& parser
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr)
|
||||
{
|
||||
typedef
|
||||
parser_accepts_container<Parser, Attribute, Context>
|
||||
parser_accepts_container;
|
||||
|
||||
return call_synthesize_x(parser, first, last, context, rcontext, attr
|
||||
, parser_accepts_container());
|
||||
}
|
||||
|
||||
// Parser has attribute (synthesize; Attribute is a single element fusion sequence)
|
||||
template <typename Iterator, typename Context
|
||||
, typename RContext, typename Attribute>
|
||||
@@ -193,7 +227,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
template <typename Parser, typename Context, typename RContext, typename Enable = void>
|
||||
struct parse_into_container_impl : parse_into_container_base_impl<Parser> {};
|
||||
|
||||
template <typename Parser, typename Container, typename RContext, typename Context>
|
||||
template <typename Parser, typename Container, typename Context>
|
||||
struct parser_attr_is_substitute_for_container_value
|
||||
: traits::is_substitute<
|
||||
typename traits::attribute_of<Parser, Context>::type
|
||||
@@ -209,7 +243,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
static bool call(
|
||||
Parser const& parser
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
|
||||
{
|
||||
return parse_into_container_base_impl<Parser>::call(
|
||||
parser, first, last, context, rcontext, attr);
|
||||
@@ -219,7 +253,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
static bool call(
|
||||
Parser const& parser
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
|
||||
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
|
||||
{
|
||||
return parser.parse(first, last, context, rcontext, attr);
|
||||
}
|
||||
@@ -229,9 +263,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, Attribute& attr)
|
||||
{
|
||||
typedef parser_accepts_container<
|
||||
Parser, Attribute, Context>
|
||||
parser_accepts_container;
|
||||
|
||||
typedef parser_attr_is_substitute_for_container_value<
|
||||
Parser, Attribute, Context>
|
||||
parser_attr_is_substitute_for_container_value;
|
||||
|
||||
typedef mpl::or_<
|
||||
parser_accepts_container
|
||||
, mpl::not_<parser_attr_is_substitute_for_container_value>>
|
||||
pass_attibute_as_is;
|
||||
|
||||
return call(parser, first, last, context, rcontext, attr,
|
||||
parser_attr_is_substitute_for_container_value<
|
||||
Parser, Attribute, Context, RContext>());
|
||||
pass_attibute_as_is());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user