// Copyright 2026 Christian Granzin // Copyright 2008 Christophe Henry // henry UNDERSCORE christophe AT hotmail DOT com // This is an extended version of the state machine available in the boost::mpl library // Distributed under the same license as the original. // Copyright for the original version: // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed // under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_MSM_BACKMP11_SERIALIZATION_NLOHMANN_JSON_HPP #define BOOST_MSM_BACKMP11_SERIALIZATION_NLOHMANN_JSON_HPP #include #include #include namespace boost::msm::backmp11::serialization { // Serializer for nlohmann json. class nlohmann_json_serializer { using json = nlohmann::json; public: nlohmann_json_serializer(json& json) : m_json({&json}) {} template void visit_front_end(FrontEnd&& front_end) { if constexpr (!std::is_empty_v>) { top()["front_end"] = front_end; } } template void visit_front_end(FrontEnd&& /*front_end*/, Reflect&& reflect) { auto& json_front_end = top()["front_end"]; m_json.push(&json_front_end); reflect(); m_json.pop(); } template void visit_member(const char* key, Member&& member) { top()[key] = member; } template void visit_state(size_t state_id, State&& state) { if constexpr (!std::is_empty_v>) { top()["states"][std::to_string(state_id)] = state; } } template void visit_state(size_t state_id, State&& /*state*/, Reflect&& reflect) { auto& json_state = top()["states"][std::to_string(state_id)]; m_json.push(&json_state); reflect(); m_json.pop(); } private: json& top() { return *m_json.top(); } std::stack m_json; }; // Deserializer for nlohmann json. class nlohmann_json_deserializer { using json = nlohmann::json; public: nlohmann_json_deserializer(const json& json) : m_json({&json}) {} template void visit_front_end(FrontEnd&& front_end) { if constexpr (!std::is_empty_v>) { front_end = top()["front_end"]; } } template void visit_front_end(FrontEnd&& /*front_end*/, Reflect&& reflect) { auto& json_state = top().at("front_end"); m_json.push(&json_state); reflect(); m_json.pop(); } template void visit_member(const char* key, Member&& member) { member = top().at(key); } template void visit_state(size_t state_id, State&& state) { if constexpr (!std::is_empty_v>) { state = top()["states"][std::to_string(state_id)]; } } template void visit_state(size_t state_id, State& /*state*/, Reflect&& reflect) { auto& json_state = top().at("states").at(std::to_string(state_id)); m_json.push(&json_state); reflect(); m_json.pop(); } private: const json& top() { return *m_json.top(); } std::stack m_json; }; } // namespace boost::msm::backmp11::serialization namespace boost::msm::backmp11::detail { template >> void to_json(nlohmann::json& json, const StateMachine& state_machine) { reflect(state_machine, serialization::nlohmann_json_serializer{json}); } template >> void from_json(const nlohmann::json& json, StateMachine& state_machine) { reflect(state_machine, serialization::nlohmann_json_deserializer{json}); } } // namespace boost::msm::backmp11::detail #endif // BOOST_MSM_BACKMP11_SERIALIZATION_NLOHMANN_JSON_HPP