json icon indicating copy to clipboard operation
json copied to clipboard

nlohmann::ordered_json: not compatible with NLOHMANN_DEFINE_TYPE_INTRUSIVE

Open 17steen opened this issue 1 year ago • 1 comments

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

17steen avatar May 22 '24 09:05 17steen

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;

frostbone25 avatar Aug 24 '24 19:08 frostbone25