boost::spirit::karma using the alternatives operator (|) with conditions
- by Ingemar
I'm trying to generate a string from my own class called Value using boost::spirit::karma, but i got stuck with this. I've tried to extract my problem into a simple example.
I want to generate a String with karma from instances of the following class:
class Value
{
public:
enum ValueType
{
BoolType,
NumericType
};
Value(bool b) : type_(BoolType), value_(b) {}
Value(const double d) : type_(NumericType), value_(d) {};
ValueType type() { return type_; }
operator bool() { return boost::get<bool>(value_); }
operator double() { return boost::get<double>(value_); }
private:
ValueType type_;
boost::variant<bool, double> value_;
};
Here you can see what I'm tying to do:
int main()
{
using karma::bool_;
using karma::double_;
using karma::rule;
using karma::eps;
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
rule<std::back_insert_iterator<std::string>, Value()> value_rule = bool_ | double_;
Value bool_value = Value(true);
Value double_value = Value(5.0);
karma::generate(sink, value_rule, bool_value);
std::cout << generated << "\n";
generated.clear();
karma::generate(sink, value_rule, double_value);
std::cout << generated << "\n";
return 0;
}
The first call to karma::generate() works fine because the value is a bool and the first generator in my rule also "consumes" a bool. But the second karma::generate() fails with boost::bad_get because karma tries to eat a bool and calls therefore Value::operator bool().
My next thought was to modify my generator rule and use the eps() generator together with a condition but here i got stuck:
value_rule = (eps( ... ) << bool_) | (eps( ... ) << double_);
I'm unable to fill the brackets of the eps generator with sth. like this (of course not working):
eps(value.type() == BoolType)
I've tried to get into boost::phoenix, but my brain seems not to be ready for things like this.
Please help me!
here is my full example (compiling but not working):
main.cpp