[karma] Losing attribute?
Hi,
I've got a Karma generator that should emit a vector of records, writing
out the index of every entry at the start. My code looks like this (note
that GEOPOINT is a fusion-adapted struct of two doubles):
typedef std::vector<GEOPOINT> Contour;
typedef std::vector<Contour> Poly;
rule
Sebastian,
I've got a Karma generator that should emit a vector of records, writing out the index of every entry at the start. My code looks like this (note that GEOPOINT is a fusion-adapted struct of two doubles):
typedef std::vector<GEOPOINT> Contour; typedef std::vector<Contour> Poly; rule
point; rule contour; rule polygon; rule start; point = L';' << double_ << L';' << double_;
contour = L";SUBPOLYGON " << lit(_r1 - 1) << L" POINTS " << lit(phoenix::size(_val)) << L" MASK XOR" << *point;
polygon = L"POLYGON COUNT " << lit(phoenix::size(_val)) << *(contour(_a)[++_a]);
start = polygon;
This doesn't work. If I take away the modification of _a, it works, except that of course the index is 0 in every iteration. But the moment I modify _a in any way (including assigning to it anywhere in the polygon rule), suddenly contour seems to get an incorrect attribute: it never fails, but never emits points either, i.e. I get an endless string of ";SUBPOLYGON 1 POINTS 0 MASK XOR;SUBPOLYGON 2 POINTS 0 MASK XOR;SUBPOLYGON 3 POINTS 0 MASK XOR...".
Any idea why that is?
Could you please provide a minimal, but still self-contained example I could run? That would help me to give you a proper answer to your question. From what I can see your code should work just fine. Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
On Wed, 24 Feb 2010 09:25:55 -0600, "Hartmut Kaiser"
Sebastian,
I've got a Karma generator that should emit a vector of records, writing out the index of every entry at the start. My code looks like this (note that GEOPOINT is a fusion-adapted struct of two doubles):
Could you please provide a minimal, but still self-contained example I could run? That would help me to give you a proper answer to your question. From what I can see your code should work just fine.
This is the test program I'm using, minus a special float formatter.
#include
Sebastian,
I've got a Karma generator that should emit a vector of records, writing out the index of every entry at the start. My code looks like this (note that GEOPOINT is a fusion-adapted struct of two doubles):
Could you please provide a minimal, but still self-contained example I could run? That would help me to give you a proper answer to your question. From what I can see your code should work just fine.
This is the test program I'm using, minus a special float formatter.
Thanks! Please see comments inline below.
#include
#include #include #include #include <iostream> #include <vector> namespace ph = boost::phoenix; namespace km = boost::spirit::karma;
struct GEOPOINT { double x, y; }; BOOST_FUSION_ADAPT_STRUCT( GEOPOINT, (double, x) (double, y) )
typedef std::vector<GEOPOINT> Contour; typedef std::vector<Contour> Poly;
template <typename Iterator> class ZoneWriter : public km::grammar
{ public: ZoneWriter() : base_type(start) { using namespace km; point = L';' << double_ << L';' << double_; contour = L";SUBPOLYGON " << lit(_r1 - 1) << L" POINTS " << lit(ph::size(_val)) << L" MASK XOR" << *point;
polygon = L"POLYGON COUNT " << lit(ph::size(_val)) << *(contour(_a)[++_a]);
The reason for the behavior you're seeing is in the line above. The operator=() for rules applies auto attribute propagation to the expression only as long as no semantic actions are attached to any of the sub-expressions of the right hand side. In order to force auto attribute propagation in your case you need to write that as: polygon %= L"POLYGON COUNT " << lit(ph::size(_val)) << *(contour(_a)[++_a]); After this change the output looks like what you might have expected...
start = polygon; }
private: km::rule
point; km::rule contour; km::rule polygon; km::rule start; }; int main() { Poly poly(5); for(int i = 0; i < 5; ++i) { Contour &c = poly[i]; c.resize(10); for(int j = 0; j < 10; ++j) { c[j].x = i + j / 4.25129; c[j].y = -j + i / 1.24951; } } typedef std::ostreambuf_iterator
osbi; km::generate(osbi(std::wcout), ZoneWriter<osbi>(), poly); std::wcout << L'\n'; }
BTW, nice example! HTH Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
participants (2)
-
Hartmut Kaiser
-
Sebastian Redl