diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index 491bb9873..672086675 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -471,11 +471,13 @@ inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence< j = { std::get(t)... }; } -#if JSON_BRACE_INIT_COPY_SEMANTICS -// JSON_BRACE_INIT_COPY_SEMANTICS makes a one-element braced list copy its -// element instead of wrapping it, which would serialize std::tuple{5} as 5 -// rather than [5]. Build what the default deduction builds instead: an object -// if the element is a [string, value] pair, a one-element array otherwise. +// A one-element braced list does not reliably wrap its element: with +// JSON_BRACE_INIT_COPY_SEMANTICS it copies it, which would serialize +// std::tuple{5} as 5 rather than [5], and some compilers (e.g., Apple clang +// 15 and 16) copy an element that is itself a basic_json even without it, so +// std::tuple{true} became true rather than [true]. Build what the default +// deduction builds instead: an object if the element is a [string, value] pair, +// a one-element array otherwise. template inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<0> /*unused*/) { @@ -493,7 +495,6 @@ inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence< j = BasicJsonType::array({std::move(element)}); } } -#endif template inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& /*unused*/, index_sequence<> /*unused*/) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 225b08010..dc9721b01 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -7016,11 +7016,13 @@ inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence< j = { std::get(t)... }; } -#if JSON_BRACE_INIT_COPY_SEMANTICS -// JSON_BRACE_INIT_COPY_SEMANTICS makes a one-element braced list copy its -// element instead of wrapping it, which would serialize std::tuple{5} as 5 -// rather than [5]. Build what the default deduction builds instead: an object -// if the element is a [string, value] pair, a one-element array otherwise. +// A one-element braced list does not reliably wrap its element: with +// JSON_BRACE_INIT_COPY_SEMANTICS it copies it, which would serialize +// std::tuple{5} as 5 rather than [5], and some compilers (e.g., Apple clang +// 15 and 16) copy an element that is itself a basic_json even without it, so +// std::tuple{true} became true rather than [true]. Build what the default +// deduction builds instead: an object if the element is a [string, value] pair, +// a one-element array otherwise. template inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<0> /*unused*/) { @@ -7038,7 +7040,6 @@ inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence< j = BasicJsonType::array({std::move(element)}); } } -#endif template inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& /*unused*/, index_sequence<> /*unused*/)