23#include <nlohmann/json.hpp>
24#include <source_location>
25#include <unordered_map>
32namespace shamrock::solvergraph {
108 static std::unique_ptr<JsonSerializable>
from_json(
const nlohmann::json &j);
130 = std::derived_from<T, JsonSerializable> &&
requires(
const nlohmann::json &j) {
131 { T::from_json(j) } -> std::same_as<T>;
142 using Factory = std::function<std::unique_ptr<JsonSerializable>(
const nlohmann::json &)>;
143 std::unordered_map<std::string, Factory> factories;
163 template<JsonDeserializable T>
165 const std::string &name, std::source_location loc = std::source_location::current()) {
167 const auto [it, inserted] = factories.try_emplace(name, [](
const nlohmann::json &j) {
168 return std::make_unique<T>(T::from_json(j));
173 throw std::runtime_error(
175 "Type {} already registered (called from {})",
197 std::unique_ptr<JsonSerializable>
create(
198 const std::string &type,
const nlohmann::json &data)
const {
199 auto it = factories.find(type);
201 if (it == factories.end())
202 throw std::runtime_error(
"Unknown type: " + type);
204 return it->second(data);
209 if (!j.is_object() || !j.contains(
"type") || !j[
"type"].is_string()) {
210 throw std::runtime_error(
211 "Invalid JSON for deserialization: expected an object with a string 'type' field.");
213 const std::string type = j.at(
"type").get<std::string>();
Singleton registry mapping type names to JSON factory functions.
static JsonSerializable_registry & instance()
Access the process-wide registry instance.
void register_type(const std::string &name, std::source_location loc=std::source_location::current())
Register a type under a string name for polymorphic deserialization.
std::unique_ptr< JsonSerializable > create(const std::string &type, const nlohmann::json &data) const
Create an instance of a registered type from JSON.
bool is_type_registered(const std::string &name) const
Check if a type is registered.
Concept for types that can be registered for polymorphic JSON deserialization.
std::string format_one_line_func(std::source_location loc)
format the location in a one liner with the function name displayed
Base interface for types that can be serialized to and from JSON.
virtual void _impl_to_json(nlohmann::json &j) const =0
Write derived-class fields into a JSON object.
void to_json(nlohmann::json &j) const
Write this object to JSON, including the "type" discriminator.
static std::unique_ptr< JsonSerializable > from_json(const nlohmann::json &j)
Reconstruct a registered type from JSON.
virtual std::string type_name() const =0
Return the type discriminator string for this class.