Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ordered_json doesn't support construction from C array of custom type #3810

Closed
2 tasks done
lethal-guitar opened this issue Oct 30, 2022 · 3 comments · Fixed by #4597
Closed
2 tasks done

ordered_json doesn't support construction from C array of custom type #3810

lethal-guitar opened this issue Oct 30, 2022 · 3 comments · Fixed by #4597
Labels
kind: bug solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@lethal-guitar
Copy link

lethal-guitar commented Oct 30, 2022

Description

I have a C-style array of structs, plus an appropriate to_json overload. I can succesfully convert the array to JSON using a regular nlohmann::json object. However, trying to do the same using nlohmann::ordered_json fails to compile - see details below.

Reproduction steps

See the example code below.

Expected vs. actual results

I'd expect the code to compile, but I get a compiler error.

Minimal code example

Build with -std=c++17 -O3.

#include <nlohmann/json.hpp>

struct Example
{
    int bla;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example, bla);

int main()
{
    Example states[45];

    // This works:
    nlohmann::json j;
    j["test"] = states;

    // This doesn't compile:
    nlohmann::ordered_json oj;
    oj["test"] = states;
}

Error messages

gcc 9.4.0 reports:

In file included from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/vector:66,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/functional:62,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/pstl/glue_algorithm_defs.h:13,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/algorithm:71,
                 from /opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:21,
                 from <source>:1:
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const Example*; _ForwardIterator = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>*]':
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h:307:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const Example*; _ForwardIterator = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>*; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_vector.h:1582:33:   required from 'void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const Example*; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; _Alloc = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_vector.h:654:4:   required from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = const Example*; <template-parameter-2-2> = void; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; _Alloc = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/ext/new_allocator.h:146:4:   required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::vector<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>, std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> > >; _Args = {const Example*, const Example*}; _Tp = std::vector<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>, std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> > >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/alloc_traits.h:483:4:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5412:25:   required from 'static void nlohmann::json_v3_11_1::detail::external_constructor<nlohmann::json_v3_11_1::detail::value_t::array>::construct(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; CompatibleArrayType = Example [45]; typename std::enable_if<(! std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5607:52:   required from 'void nlohmann::json_v3_11_1::detail::to_json(BasicJsonType&, const T (&)[N]) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; T = Example; long unsigned int N = 45; typename std::enable_if<(! std::is_constructible<typename BasicJsonType::string_t, const T (&)[N]>::value), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5650:23:   required from 'decltype ((nlohmann::json_v3_11_1::detail::to_json(j, forward<T>(val)), void())) nlohmann::json_v3_11_1::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; T = Example (&)[45]; decltype ((nlohmann::json_v3_11_1::detail::to_json(j, forward<T>(val)), void())) = void]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5706:28:   required from 'static decltype ((nlohmann::json_v3_11_1::to_json(j, forward<TargetType>(val)), void())) nlohmann::json_v3_11_1::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, TargetType&&) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; TargetType = Example (&)[45]; ValueType = Example [45]; <template-parameter-1-2> = void; decltype ((nlohmann::json_v3_11_1::to_json(j, forward<TargetType>(val)), void())) = void]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:19798:35:   required from 'nlohmann::json_v3_11_1::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::basic_json(CompatibleType&&) [with CompatibleType = Example (&)[45]; U = Example [45]; typename std::enable_if<((! nlohmann::json_v3_11_1::detail::is_basic_json<U>::value) && nlohmann::json_v3_11_1::detail::is_compatible_type<nlohmann::json_v3_11_1::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, U>::value), int>::type <anonymous> = 0; ObjectType = nlohmann::json_v3_11_1::ordered_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_v3_11_1::adl_serializer; BinaryType = std::vector<unsigned char>]'
<source>:20:18:   required from here
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
  127 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
      |

Clang outputs a significantly longer error message, which boils down to "No matching constructor found".

Compiler and operating system

GCC 9.4 on Linux (godbolt), Apple Clang 10 on Mac OS

Library version

3.11.1

Validation

@falbrechtskirchinger
Copy link
Contributor

This will be fixed by #2843. In the meantime, this can be solved by writing from_json/to_json functions that accept arbitrary basic_json types (or just ordered_json in your case).

@lethal-guitar
Copy link
Author

I see, thanks!

@nlohmann nlohmann linked a pull request Jan 19, 2025 that will close this issue
4 tasks
@nlohmann nlohmann added solution: proposed fix a fix for the issue has been proposed and waits for confirmation and removed state: waiting for PR labels Jan 19, 2025
@nlohmann nlohmann added this to the Release 3.11.4 milestone Jan 19, 2025
@nlohmann
Copy link
Owner

Fixed by merging #4597.

nlohmann added a commit that referenced this issue Jan 19, 2025
Signed-off-by: Niels Lohmann <[email protected]>
nlohmann added a commit that referenced this issue Jan 22, 2025
Signed-off-by: Niels Lohmann <[email protected]>
nlohmann added a commit that referenced this issue Jan 22, 2025
Signed-off-by: Niels Lohmann <[email protected]>
nlohmann added a commit that referenced this issue Jan 23, 2025
Signed-off-by: Niels Lohmann <[email protected]>
nlohmann added a commit that referenced this issue Jan 23, 2025
Signed-off-by: Niels Lohmann <[email protected]>
nlohmann added a commit that referenced this issue Feb 15, 2025
* ✅ add regression test for #3810

Signed-off-by: Niels Lohmann <[email protected]>

* ✅ add regression test for #3810

Signed-off-by: Niels Lohmann <[email protected]>

* ✅ add regression test for #3810

Signed-off-by: Niels Lohmann <[email protected]>

* ✅ add regression test for #3810

Signed-off-by: Niels Lohmann <[email protected]>

* ✅ add regression test for #3810

Signed-off-by: Niels Lohmann <[email protected]>

---------

Signed-off-by: Niels Lohmann <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants