#include #include namespace qi = boost::spirit::qi; template void test_parser_attr(char const* input, P const& p, T& attr, bool full_match = true) { using boost::spirit::qi::parse; char const* f(input); char const* l(f + strlen(f)); if (parse(f, l, p, attr) && (!full_match || (f == l))) std::cout << "ok" << std::endl; else std::cout << "fail" << std::endl; } /* This test structure represents a primitive range limited type. */ struct body_temp { float t; }; bool no_chance(false); namespace boost { namespace spirit { namespace traits { template <> struct transform_attribute { typedef float type; static float pre(body_temp t) { return t.t; } /* if parsed attribute is within desired range, than assign it, * otherwise report failure. */ static bool post(body_temp& t, float const &attr) { if (attr > 30.0 && attr < 45.0) { t.t = attr; return true; } else return false; } static void fail(body_temp &t) { } }; }}} int main(int argc, char **argv) { namespace qi = boost::spirit::qi; using qi::float_; using qi::omit; using qi::rule; using qi::attr_cast; using boost::phoenix::ref; body_temp d1 = { 36.6 }, d2 = { 36.6 }; rule r; /* Adapt qi::float_ parser to struct body_temp which represents a range * limited numeric type. If range can not be accomodated, per conversion * defined, the first alternative will fail, and second will be invoked, * to set the error flag. */ r %= attr_cast(float_) | omit[float_[ref(no_chance) = true]]; /* Supplied value is within range and will be parsed as appropriate * range limited float. */ test_parser_attr("40.0", r, d1); std::cout << "parsed temp " << d1.t << " error flag " << no_chance << std::endl; no_chance = false; /* Supplied value is not within allowed range, the parser will take the * alternative choice to set the error flag. */ test_parser_attr("20.0", r, d2); std::cout << "parsed temp " << d2.t << " error flag " << no_chance << std::endl; return 0; }