Skip to content

nlohmann::ordered_json: not compatible with NLOHMANN_DEFINE_TYPE_INTRUSIVE #4377

Description

@17steen

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

Activity

  1. frostbone25 commented on Aug 24, 2024

    @frostbone25

    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;
  2. added this to the Release 3.11.4 milestone on Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: bugsolution: proposed fixa fix for the issue has been proposed and waits for confirmation

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions