Search code examples
c++jsonreflection

c++ JSON serialize using reflection


Can someone modify given code so my commented code works. Actully I don't understand how reflect macro is working at first place.

#include <vector>
#include <string>
#include <iostream>

using namespace std;

#define REFLECT(x) template<class R> void reflect(R& r) { r x; }

typedef struct _Employee {
    string emp_id;
    int salary;
    REFLECT(
        ("Emp_id", emp_id)
        ("Salary", salary)
    )
} Employee;

class Demo {
    std::ostream& output;
    bool flag = false;
public:
    Demo(std::ostream& output) : output(output) {}
    template<class T>

    auto write(T& myobj) -> decltype(myobj.reflect(*this), void())
    {
        output << "{";
        flag = false;
        myobj.reflect(*this);
        output << "}\n";
    }
    void write(int val) {
        output << val;
    }
    void write(std::string& val) {
        output << '"' << val << '"';
    }
    template<class T>
    Demo& operator()(const char* emp_id, T& myfield) {
        if (flag) {
            output << ",";
        }
        flag = true;
        output << "\"" << emp_id << "\":";
        write(myfield);
        return *this;
    }
};
int main() {
    Demo myObj(std::cout);
    //Demo myObj();
    Employee emp1 = { "2324354", 90000 };
    myObj.write(emp1);
    //std::cout << myObj.write(emp1);
}

I am not good at latest c++ coding styles and standards.

I got this snippet code from internet and want to use for json serializatzion.

Regards.

SM


Solution

  • @TRT thanks for your explanation. I got following solution.

    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    
    using namespace std;
    
    #define REFLECT(x) template<class R> void reflect(R& r) { r x; }
    
    typedef struct _Employee {
        string emp_id;
        int salary;
        REFLECT(
            ("Emp_id", emp_id)
            ("Salary", salary)
        )
    } Employee;
    
    typedef struct _Demo {
        bool flag = false;
        template<class T>
        auto write(T& myobj) -> decltype(myobj.reflect(*this), string()){
            std::stringstream ss;
    
            //cout << "{";
            output.push_back("{");
            flag = false;
            myobj.reflect(*this);
            //cout << "}\n";
            output.push_back("}\n");
    
            for (auto& s : output)
            {
                ss << s;
            }
            return ss.str();
        }
        void write(int& n) {
            //cout << n;
            output.push_back(to_string(n));
        }
        void write(string& s) {
            //cout << '"'<<s<<'"';
            output.push_back(string("\"") + s + "\":");
        }
        template<class T>
        struct _Demo& operator()(const char* emp_id, T& myfield) {
            std::stringstream ss;
    
            if (flag) {
                //cout << ",";
                output.push_back(",");
            }
            flag = true;
            //cout << "\"" << emp_id << "\":";
            output.push_back(string("\"") + emp_id + "\":");
            write(myfield);
            return *this;
        }
    private:
        vector<string> output;
    } Demo;
    
    int main()
    {
        Demo demo;
        Employee emp = { "2324354", 90000 };
        cout << demo.write(emp) << endl;
        cin.get();
        return 0;
    }