Home:ALL Converter>Boost X3: Can a variant member be avoided in disjunctions?

Boost X3: Can a variant member be avoided in disjunctions?

Ask Time:2021-09-22T05:44:35         Author:Michaël

Json Formatter

I'd like to parse string | (string, int) and store it in a structure that defaults the int component to some value. The attribute of such a construction in X3 is a variant<string, tuple<string, int>>. I was thinking I could have a struct that takes either a string or a (string, int) to automagically be populated:

    struct bar
        bar (std::string x = "", int y = 0) : baz1 {x}, baz2 {y} {}

        std::string          baz1;
        int                  baz2;

BOOST_FUSION_ADAPT_STRUCT (disj::ast::bar, baz1, baz2)

and then simply have:

    const x3::rule<class bar, ast::bar> bar = "bar";
    using x3::int_;
    using x3::ascii::alnum;

    auto const bar_def = (+(alnum) | ('(' >> +(alnum) >> ',' >> int_ >> ')')) >> ';';


However this does not work:

/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:139:59: error: static assertion failed: Expecting a single element fusion sequence
  139 |             static_assert(traits::has_size<Attribute, 1>::value,

Setting baz2 to an optional does not help. One way to solve this is to have a variant field or inherit from that type:

    struct string_int {
        std::string s;
        int i;

    struct foo {
        boost::variant<std::string, string_int>  var;

BOOST_FUSION_ADAPT_STRUCT (disj::ast::string_int, s, i)
BOOST_FUSION_ADAPT_STRUCT (disj::ast::foo, var)

(For some reason, I have to use boost::variant instead of x3::variant for operator<< to work; also, using std::pair or tuple for string_int does not work, but boost::fusion::deque does.) One can then equip foo somehow to get the string and integer.

Question: What is the proper, clean way to do this in X3? Is there a more natural way than this second option and equipping foo with accessors?

Live On Coliru

Author:Michaël,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/69275873/boost-x3-can-a-variant-member-be-avoided-in-disjunctions