struct puzzle

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

struct puzzle

Patrick Welche
Following Seth's excellent example, the attached simple program parses
an int and a map of strings. The puzzle is why it no longer compiles
when I remove the int with the following patch:

@@ -11,23 +11,21 @@
 using Map = std::map<std::string, std::string>;
 
 struct result {
-    int onemore;
     Map both;
 };
 
-BOOST_FUSION_ADAPT_STRUCT(result, onemore, both)
+BOOST_FUSION_ADAPT_STRUCT(result, both)
 
 int main()
 {
-    std::string const buf("1;one two;three four;");
+    std::string const buf("one two;three four;");
     auto iter = buf.begin(), end = buf.end();
     auto parser = []{
         using namespace boost::spirit::x3;
 
         auto string_ = lexeme[+alpha];
         auto map_    = (string_ >> string_) >> ';';
- auto num_    = int_ >> ';';
- auto all_    = num_ >> +map_;
+ auto all_    = +map_;
 
         return rule<struct _, struct result> {"parser"} = skip(space) [ all_ ];
     };
@@ -49,6 +47,5 @@
         for (auto p : res.both) {
             std::cout << "found: " << p.first << ' ' << p.second << std::endl;
         }
- std::cout << "and: " << res.onemore << " !" << std::endl;
     }
 }


Less is more?

Cheers,

Patrick

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general

struct.cpp (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: struct puzzle

sehe
On 12-04-17 18:15, Patrick Welche wrote:
Following Seth's excellent example, the attached simple program parses
an int and a map of strings. The puzzle is why it no longer compiles
when I remove the int with the following patch:
I think it's the single-element fusion sequence edge-case again.

This has been a pain-point in Qi for a long time, and apparently still crops up in X3 in specific circumstances (looks like, detecting whether the bound argument in context is a container fails since it's a sequence containing just the container).

This is very hard to get right - given the C++ type system and methods to do meta-programming, I think. For now I'd accept the workaround of adding padding on single-element (adapted) fusion sequences with a container element.

struct result {
    Map both;
    //
    boost::spirit::x3::unused_type padding;
};

BOOST_FUSION_ADAPT_STRUCT(result, padding, both)

        auto placebo_ = attr(nullptr);
        auto all_     = placebo_ >> +map_;

It's not pretty, but at least you know why.

Note that you can trivially use something non-x3 instead of unused_type:

struct Blackhole {
    template <typename T> Blackhole& operator=(T&&) { return *this; }
};

struct result {
    Map both;
    //
    Blackhole padding;
};


See http://coliru.stacked-crooked.com/a/7a55bf8e1529c3f4    


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Loading...