Example of serializing a C++ object to JSON with reflection:
template<typename T>
std::string to_json(const T& obj) {
std::ostringstream oss;
constexpr auto type_info = reflect(T);
if constexpr (type_info.is_fundamental()) {
// Fundamental types (int, float, etc.)
if constexpr (std::is_same_v<T, bool>) {
oss << (obj ? "true" : "false");
} else if constexpr (std::is_arithmetic_v<T>) {
oss << obj;
} else if constexpr (std::is_same_v<T, std::string>) {
oss << "\"" << obj << "\"";
}
}
else if constexpr (type_info.is_enum()) {
// Enums
oss << "\"" << type_info.enum_name(obj) << "\"";
}
else if constexpr (type_info.is_array() || std::is_same_v<T, std::vector<typename T::value_type>>) {
// Arrays and vectors
oss << "[";
bool first = true;
for (const auto& elem : obj) {
if (!first) oss << ",";
oss << to_json(elem);
first = false;
}
oss << "]";
}
else if constexpr (std::is_same_v<T, std::map<typename T::key_type, typename T::mapped_type>>) {
// Maps
oss << "{";
bool first = true;
for (const auto& [key, value] : obj) {
if (!first) oss << ",";
oss << "\"" << key << "\":" << to_json(value);
first = false;
}
oss << "}";
}
else if constexpr (type_info.is_class()) {
// Classes and structs
oss << "{";
bool first = true;
for (const auto& member : type_info.members()) {
if (!first) oss << ",";
oss << "\"" << member.name() << "\":" << to_json(member.get(obj));
first = false;
}
oss << "}";
}
return oss.str();
}
enum class Color { Red, Green, Blue };
struct Address {
std::string street;
std::string city;
int zip;
};
struct Person {
std::string name;
int age;
double height;
Color favorite_color;
Address address;
std::vector<std::string> hobbies;
std::map<std::string, int> scores;
};
int main() {
Person person {
"John Doe",
30,
175.5,
Color::Blue,
{"123 Main St", "Anytown", 12345},
{"reading", "hiking", "coding"},
{{"math", 95}, {"history", 88}, {"science", 92}}
};
std::cout << to_json(person) << std::endl;
return 0;
}