boostboost-spirit-karma

boost karma semantic action call map


I need to map values to a std::string ( with the following map, and BOOST_FUSION_ADAPT_STRUCT )

    std::map< TYPEX, std::string> author2name;
    struct Emp
   {
     std::string name;
     TYPEX author;
   };

With the following code i want to generate my output:

karma::rule< it, std::string()> quote = '"' >> karma::string >> '"';
karma::rule< it, Emp> emp = karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];

Emp x;
karma::generate( std::ostream_iterator<char>(std::cout), emp, x);

But it doesn't compile.

And is there a way that i could write a header like this:

karma::rule< it, std::vector<std::string>()> header = karma::delimit('\t')[ % quote];
karma::rule< it, Emp> emp = header >> karma::eol >> karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];

karma::generate( std::ostream_iterator<char>(std::cout), {"A", "B", "C"},emp, x);

Solution

  • There is a number of small paper-cuts that killed you there :)

    Working example:

    Live On Coliru

    #include <boost/fusion/adapted.hpp>
    #include <boost/spirit/include/karma.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <map>
    
    namespace karma = boost::spirit::karma;
    namespace phx   = boost::phoenix;
    
    enum TYPEX { AUTHOR1, AUTHOR2, AUTHOR3, AUTHOR4 };
    
    std::map<TYPEX, std::string> author2name;
    struct Emp {
        std::string name;
        TYPEX author;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(Emp, name, author) // boost 1_59
    //BOOST_FUSION_ADAPT_STRUCT(Emp, (std::string, name)(std::string, author)) // older boost
    
    int main() {
        using it = boost::spirit::ostream_iterator;
    
        karma::rule<it, std::string()> quote;
        karma::rule<it, TYPEX()> author;
        karma::rule<it, Emp()> emp;
    
        {
            using namespace karma;
            quote  %= '"' << string << '"';
            author  = quote [ _1 = phx::ref(author2name)[ _val ] ];
            emp    %= delimit('\t')[ quote << author ];
        }
    
        Emp x { "one", AUTHOR2 };
        author2name[AUTHOR2] = "TWO!";
        std::cout << karma::format(emp, x);
    }
    

    Prints:

    "one"   "TWO!"  
    

    The things that caused trouble: