nlohmann::ordered_json: not compatible with NLOHMANN_DEFINE_TYPE_INTRUSIVE
Description
If a type is defined with NLOHMANN_DEFINE_TYPE_INTRUSIVE, it cannot directly be used with ordered_json.
Reproduction steps
#include <nlohmann/json.hpp>
struct my_type_t {
std::string key;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(my_type_t, key)
};
int main()
{
auto thing = my_type_t{};
nlohmann::json my_json = thing;
// doesn't compile
nlohmann::ordered_json my_ordered_json = thing;
return 0;
}
Expected vs. actual results
I would expect nlohmann::ordered_json my_ordered_json = custom_type; to compile
Minimal code example
No response
Error messages
No response
Compiler and operating system
gcc 13.1
Library version
trunk on godbolt
Validation
- [X] The bug also occurs if the latest version from the
developbranch is used. - [X] I can successfully compile and run the unit tests.
The issue with the macros that are defined is that they are all written with nlohmann::json and there are no set of macros written with nlohmann::ordered_json.
From the original macro_scope.hpp
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
The solution I did that ended up working for me was to write a secondary header file in my project, and write a couple of new macros that matched the original, except all I did was change the type from nlohmann::json to nlohmann::ordered_json.
#pragma once
#ifndef JSON_H
#define JSON_H
//||||||||||||||||||||||||||||| INCLUDED DEPENDENCIES |||||||||||||||||||||||||||||
//||||||||||||||||||||||||||||| INCLUDED DEPENDENCIES |||||||||||||||||||||||||||||
//||||||||||||||||||||||||||||| INCLUDED DEPENDENCIES |||||||||||||||||||||||||||||
//THIRD PARTY: JSON Library
#include <nlohmann/json.hpp>
//||||||||||||||||||||||||||||| NEW MACROS |||||||||||||||||||||||||||||
//||||||||||||||||||||||||||||| NEW MACROS |||||||||||||||||||||||||||||
//||||||||||||||||||||||||||||| NEW MACROS |||||||||||||||||||||||||||||
#define NLOHMANN_ORDERED_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(nlohmann::ordered_json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::ordered_json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_ORDERED_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::ordered_json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::ordered_json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
#endif
I would include this header I created into all of my other struct/classes and replace the original lines where I would use...
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
I would replace it with the new macro I defined in the header file...
NLOHMANN_ORDERED_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
Then in your original code...
nlohmann::json json;
json = myStructObjectUsingNewMacrosInternally;
You can change the type and have no issues...
nlohmann::ordered_json json;
json = myStructObjectUsingNewMacrosInternally;