Gerador de Karma Boost para composição de classes

Eu tenho o seguinte diagrama de classes:

Há alguma classe não utilizada comoBinaryOperator, mas meu código real precisa deles, então quero mantê-los também no exemplo.

Eu quero usarboost :: karma para obter uma representação JSON disso. O JSON deve ser como o seguinte:

{
  "name": "Plus",
  "type": "Function",
  "arguments": [
    {
      "name": "IntegerValue",
      "type": "Value",
      "value": "4"
    },
    {
      "name": "Plus",
      "type": "Function",
      "arguments": [
        {
          "name": "IntegerValue",
          "type": "Value",
          "value": "5"
        },
        {
          "name": "IntegerValue",
          "type": "Value",
          "value": "6"
        }
      ]
    }
  ]
}

Como é um exemplo simples, eu gostaria de usarBOOST_FUSION_ADAPT_ADT macro para minhas aulas, a fim de modularizar o gerador.

Eu sou novo no Karma, li o tutorial no site do boost, mas não entendo como atacar o meu problema. Não consigo encontrar um bom tutorial sobre essa macro.

Não quero usar bibliotecas existentes para JSON porque, a princípio, quero aprender Karma, e, em segundo lugar, JSON é apenas um exemplo, preciso exportar minha expressão em muitos formatos e posso fazê-lo simplesmente mudando de gerador enquanto o código que usaBOOST_FUSION_ADAPT_ADT para minhas aulas deve ser o mesmo.

Você pode encontrar o código para criar uma expressão de amostra. Onde eu preciso começar para resolver meu problema?

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>

class Expression {
public:

  virtual std::string getName() const = 0;
};

class Value : public Expression {
public:

  virtual std::string getValue() const = 0;
};

class IntegerValue : public Value {
public:

  IntegerValue(int value) : m_value(value) {}
  virtual std::string getName() const override { return "IntegerValue"; }
  virtual std::string getValue() const override { return boost::lexical_cast<std::string>(m_value); }

private:

  int m_value;
};

class Function : public Expression {
public:

  void addArgument(Expression* expression) { m_arguments.push_back(expression); }
  virtual std::string getName() const override { return m_name; }

protected:

  std::vector<Expression*> m_arguments;
  std::string m_name;
};

class Plus : public Function {
public:

  Plus() : Function() { m_name = "Plus"; }
};

///////////////////////////////////////////////////////////////////////////////

int main(int argc, char **argv) {

  // Build expression 4 + 5 + 6 as 4 + (5 + 6)
  Function* plus1 = new Plus();
  Function* plus2 = new Plus();
  Value* iv4   = new IntegerValue(4);
  Value* iv5   = new IntegerValue(5);
  Value* iv6   = new IntegerValue(6);
  plus2->addArgument(iv5);
  plus2->addArgument(iv6);
  plus1->addArgument(iv4);
  plus1->addArgument(plus2);

  // Generate json string here, but how?

  return 0;
}