#pragma once #include #include #include namespace clice::json { using namespace llvm::json; template constexpr inline bool is_array_v = false; template constexpr inline bool is_array_v> = true; template constexpr inline bool is_array_v> = true; template constexpr inline bool is_array_v> = true; template constexpr inline bool is_string_v = false; template <> constexpr inline bool is_string_v = true; template <> constexpr inline bool is_string_v = true; template <> constexpr inline bool is_string_v = true; template constexpr inline bool is_integral_v = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v; template json::Value serialize(const Value& value) { if constexpr(std::is_same_v) { return value; } else if constexpr(is_integral_v) { return static_cast(value); } else if constexpr(is_enum_v) { return static_cast(underlying_value(value)); } else if constexpr(std::is_floating_point_v) { return static_cast(value); } else if constexpr(is_string_v) { return llvm::StringRef(value); } else if constexpr(is_array_v) { json::Array array; for(const auto& element: value) { array.push_back(serialize(element)); } return array; } else { json::Object object; refl::foreach(value, [&](llvm::StringRef name, const auto& field) { object.try_emplace(name, serialize(field)); }); return object; } } template Value deserialize(const json::Value& object) { if constexpr(std::is_same_v) { return Value{object.getAsBoolean().value()}; } else if constexpr(is_integral_v || is_enum_v) { return Value(object.getAsInteger().value()); } else if constexpr(std::is_floating_point_v) { return object.getAsNumber().value(); } else if constexpr(is_string_v) { return Value{object.getAsString().value()}; } else if constexpr(is_array_v) { Value array; for(const auto& element: *object.getAsArray()) { array.push_back(deserialize(element)); } return array; } else { Value value; refl::foreach(value, [&](llvm::StringRef name, auto& field) { if(auto element = object.getAsObject()->get(name)) { field = deserialize>(*element); } }); return value; } } } // namespace clice::json