/* NLOHMANN_JSON_SERIALIZE_ENUM expanded to inline functions, so this macro should be placed in header where enum class is declared also this macro must be declared within enum type's namespace ``` // include loguru header here, declear enum NamedVerbosity // this code injection happen in your project header file, no need to modify loguru.hpp namespace loguru { // this macro must be called in the enum declaring namespace NLOHMANN_JSON_SERIALIZE_ENUM(NamedVerbosity, { {Verbosity_OFF, "OFF"}, {Verbosity_FATAL, "FATAL"}, /// program will terminate {Verbosity_ERROR, "ERROR"}, /// red text print in console {Verbosity_WARNING, "WARNING"}, /// yellow text in console {Verbosity_INFO, "INFO"}, /// default 0 for loguru, 20 for python {Verbosity_1, "PROGRESS"}, /// 1 for loguru, write into log file {Verbosity_2, "DEBUG"}, /// 2 for loguru, write into file }); } // namespace loguru ``` */ #include "json.hpp" #include #include // copy of the NLOHMANN_JSON_SERIALIZE_ENUM here for illustration #define JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ template \ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ { \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [e](const std::pair& ej_pair) -> bool \ { \ return ej_pair.first == e; \ }); \ j = ((it != std::end(m)) ? it : std::begin(m))->second; \ } \ template \ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ { \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [j](const std::pair& ej_pair) -> bool \ { \ return ej_pair.second == j; \ }); \ e = ((it != std::end(m)) ? it : std::begin(m))->first; \ } enum class DevicePreference { CPU, /// item count is small, but processing each item take times GPU, /// large items but small job }; // use the official macro NLOHMANN_JSON_SERIALIZE_ENUM(DevicePreference, { {DevicePreference::CPU, "CPU"}, {DevicePreference::GPU, "GPU"}, }) /* this is the expansion of macro, for debugging, review purpose template inline void to_json(BasicJsonType& j, const DevicePreference& e) { static_assert(std::is_enum::value, "DevicePreference" " must be an enum!"); static const std::pair m[] = { {DevicePreference::CPU, "CPU"}, {DevicePreference::GPU, "GPU"}, }; auto it = std::find_if( std::begin(m), std::end(m), [e](const std::pair& ej_pair) -> bool { return ej_pair.first == e; }); j = ((it != std::end(m)) ? it : std::begin(m))->second; } template inline void from_json(const BasicJsonType& j, DevicePreference& e) { static_assert(std::is_enum::value, "DevicePreference" " must be an enum!"); static const std::pair m[] = { {DevicePreference::CPU, "CPU"}, {DevicePreference::GPU, "GPU"}, }; auto it = std::find_if( std::begin(m), std::end(m), [j](const std::pair& ej_pair) -> bool { return ej_pair.second == j; }); e = ((it != std::end(m)) ? it : std::begin(m))->first; } */ int main() { // Usage: // enum -> json string nlohmann::json j = DevicePreference::CPU; assert(j == "CPU"); std::cout << j << std::endl; // it is fine to scope enum value by enum type DevicePreference ts = DevicePreference::GPU; // json string-> enum nlohmann::json j3 = "GPU"; assert( j3.get() == DevicePreference::GPU); //std::cout << j3.get(); // << operator is not supported // unmapped json -> enum (default value is first pair) nlohmann::json jPi = "unknown"; assert( jPi.get() == DevicePreference::CPU ); return 0; }