c++ - Error when adapting a class with BOOST_FUSION_ADAPT_ADT -


i've following class:

#ifndef wfractal_fractal_metadata_h_ #define wfractal_fractal_metadata_h_  #include <string>  namespace wfractal { namespace fractal {  class metadata {  public:      void setauthorname(const std::string &name);     void setauthoremail(const std::string &email);     void setbriefdescription(const std::string &brief);     void setcompletedescription(const std::string &description);     std::string getauthorname() const;     std::string getauthoremail() const;     std::string getbriefdescription() const;     std::string getcompletedescription() const;  public:      bool operator==(const metadata &other);  private:      std::string m_name;     std::string m_email;     std::string m_brief;     std::string m_description; };  } // namespace fractal } // namespace wfractal  #endif // !wfractal_fractal_metadata_h_ 

i want parse using boost::spirit following file content:

metadata {   author = "me";   email = "myemail";   brief = "brief description";   description = "complete description"; } 

i've read this page can use boost_fusion_adapt_struct in order parse it. grammar template:

#ifndef wfractal_fractal_parser_metadatagrammar_h_ #define wfractal_fractal_parser_metadatagrammar_h_  #include <boost/fusion/adapted/adt/adapt_adt.hpp> #include <boost/fusion/include/adapt_adt.hpp> #include <boost/spirit/include/qi_no_case.hpp> #include <string> #include "fractal/metadata.h"  boost_fusion_adapt_adt(     wfractal::fractal::metadata,     (obj.getauthorname(), obj.setauthorname(val))     (obj.getauthoremail(), obj.setbriefdescription(val))     (obj.getbriefdescription(), obj.setcompletedescription(val))     (obj.getcompletedescription(), obj.setauthoremail(val)) )  namespace wfractal { namespace fractal { namespace parser {  template <typename iterator> struct metadataparser : boost::spirit::qi::grammar<iterator, metadata(), boost::spirit::ascii::space_type> {     metadataparser() : metadataparser::base_type(start) {         using boost::spirit::qi::int_;         using boost::spirit::qi::lit;         using boost::spirit::qi::double_;         using boost::spirit::qi::lexeme;         using boost::spirit::ascii::char_;         using boost::spirit::ascii::no_case;          quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];          start %=         no_case[lit("metadata")]         >> '{'         >>  no_case[lit("author")] >> '=' >> quoted_string >> ';'         >>  no_case[lit("email")] >> '=' >> quoted_string >> ';'         >>  no_case[lit("brief")] >> '=' >> quoted_string >> ';'         >>  no_case[lit("description")] >> '=' >> quoted_string >> ';'         >>  '}'         ;     }      boost::spirit::qi::rule<iterator, std::string(), boost::spirit::ascii::space_type> quoted_string;     boost::spirit::qi::rule<iterator, metadata(), boost::spirit::ascii::space_type> start; };  } // namespace parser } // namespace fractal } // namespace wfractal  #endif // !wfractal_fractal_parser_metadatagrammar_h_ 

when create instance of grammar (always following page example), obtain compiler error:

typedef string::const_iterator stringiterator; typedef parser::metadataparser<stringiterator> metadataparser; metadataparser parser; 

i obtain lot of errors (typical of boost...) , i've noticed inside them many copy of error:

src/fractal/filefactory.cpp:27:17:   required here /usr/include/boost/spirit/home/qi/detail/assign_to.hpp:152:18: error: no matching function call ‘boost::fusion::extension::adt_attribute_proxy<wfractal::fractal::metadata, 0, false>::adt_attribute_proxy(const std::__cxx11::basic_string<char>&)’              attr = static_cast<attribute>(val); 

what i'm doing wrong? how can fix it?

edit

as suggested m.s. i've added #include <boost/spirit/include/support_adapt_adt_attributes.hpp> header not working.

#ifndef wfractal_fractal_parser_metadataparser_h_ #define wfractal_fractal_parser_metadataparser_h_  #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_object.hpp> #include <boost/fusion/include/io.hpp> #include <boost/fusion/adapted/adt/adapt_adt.hpp> #include <boost/fusion/include/adapt_adt.hpp> #include <boost/spirit/include/support_adapt_adt_attributes.hpp> #include <string> #include "fractal/metadata.h"  boost_fusion_adapt_adt(     wfractal::fractal::metadata,     (obj.getauthorname(), obj.setauthorname(val))     (obj.getauthoremail(), obj.setauthoremail(val))     (obj.getbriefdescription(), obj.setbriefdescription(val))     (obj.getcompletedescription(), obj.setcompletedescription(val)) )  namespace wfractal { namespace fractal { namespace parser {  template <typename iterator> struct metadataparser : boost::spirit::qi::grammar<iterator, metadata(), boost::spirit::ascii::space_type> {     metadataparser() : metadataparser::base_type(start) {         using boost::spirit::qi::lit;         using boost::spirit::qi::lexeme;         using boost::spirit::ascii::char_;         using boost::spirit::ascii::no_case;          quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];          start %=         no_case[lit("metadata")]         >> '{'         >> ((no_case[lit("author")] >> '=' >> quoted_string >> ';')         ^  (no_case[lit("email")] >> '=' >> quoted_string >> ';')         ^  (no_case[lit("brief")] >> '=' >> quoted_string >> ';')         ^  (no_case[lit("description")] >> '=' >> quoted_string >> ';'))         >>  '}'         ;     }      boost::spirit::qi::rule<iterator, std::string(), boost::spirit::ascii::space_type> quoted_string;     boost::spirit::qi::rule<iterator, metadata(), boost::spirit::ascii::space_type> start; };  } // namespace parser } // namespace fractal } // namespace wfractal  #endif // !wfractal_fractal_parser_metadataparser_h_ 

hmm.

after long struggle modular boost , git... i've found regression.

the regression has been partially fixed pull request:

sadly, it's still broken in presence of permutation parser. i've tested boost_fusion_adapt_struct verify not broken in other way.

i'll add reduced sample pr comments. meanwhile, here's reproducer made selfcontained:

live on coliru

#include <boost/spirit/include/qi.hpp> #include <boost/fusion/adapted.hpp> #include <iostream>  class foo {   public:     char const& geta() const { return a; }      char const& getb() const { return b; }       void seta(char value)    { = value; }      void setb(char value)    { b = value; }    private:     char a, b; };  boost_fusion_adapt_adt(         foo,         (char const&, char const&, obj.geta(), obj.seta(val))         (char const&, char const&, obj.getb(), obj.setb(val))     )   int main() {     namespace qi = boost::spirit::qi;      boost::spirit::istream_iterator f(std::cin), l; // input e.g. "a=a;b=b;"     foo foo;      bool r = qi::parse(f, l, #if 0 // fails compile                       ("a=" >> qi::char_ >> ';')                     ^ ("b=" >> qi::char_ >> ';') #else // compiles fix pr #153                       ("a=" >> qi::char_ >> ';')                    >> ("b=" >> qi::char_ >> ';') #endif                  , foo);      if (r)         std::cout << "parsed: " << boost::fusion::as_vector(foo) << "\n";     else         std::cerr << "parse failed\n"; } 

if you, however, change #if 1 #if 0, output:

parsed: (a b) 

note of course that's assuming use branch has pr 153 applied.


Comments

Popular posts from this blog

javascript - Slick Slider width recalculation -

jsf - PrimeFaces Datatable - What is f:facet actually doing? -

angular2 services - Angular 2 RC 4 Http post not firing -