diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 3dd9162df..3ea359109 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -62,7 +62,8 @@ class serializer public: /*! - @param[in] s output stream to serialize to + @param[in] s output adapter to serialize to; not owned by the serializer, + so it must outlive it (it lives at the call site) @param[in] ichar indentation character to use @param[in] pretty_print_ whether the output shall be pretty-printed @param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII @@ -76,12 +77,12 @@ class serializer being threaded through every call to @ref dump, @ref dump_internal and @ref dump_iteratively. */ - serializer(output_adapter_t s, const char ichar, + serializer(output_adapter_protocol* s, const char ichar, const bool pretty_print_ = false, const bool ensure_ascii_ = false, const std::size_t indent_step_ = 0, error_handler_t error_handler_ = error_handler_t::strict) - : o(std::move(s)) + : o(s) , locale(std::localeconv()) , indent_char(ichar) , pretty_print(pretty_print_) @@ -1678,8 +1679,8 @@ class serializer const char decimal_point; }; - /// the output of the serializer - output_adapter_t o = nullptr; + /// the output of the serializer (non-owning; the adapter lives at the call site) + output_adapter_protocol* o = nullptr; /// a (hopefully) large enough character buffer std::array number_buffer{{}}; diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 7243c3c44..48cf3c4b0 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1343,16 +1343,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const error_handler_t error_handler = error_handler_t::strict) const { string_t result; + detail::output_string_adapter string_adapter(result); if (indent >= 0) { - serializer s(detail::output_adapter(result), indent_char, + serializer s(&string_adapter, indent_char, true, ensure_ascii, static_cast(indent), error_handler); s.dump(*this); } else { - serializer s(detail::output_adapter(result), indent_char, + serializer s(&string_adapter, indent_char, false, ensure_ascii, 0, error_handler); s.dump(*this); } @@ -4083,7 +4084,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec o.width(0); // do the actual serialization - serializer s(detail::output_adapter(o), o.fill(), + detail::output_stream_adapter stream_adapter(o); + serializer s(&stream_adapter, o.fill(), pretty_print, false, static_cast(indentation)); s.dump(j); return o; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 8b1f4506e..b3fcd6cdd 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -21410,7 +21410,8 @@ class serializer public: /*! - @param[in] s output stream to serialize to + @param[in] s output adapter to serialize to; not owned by the serializer, + so it must outlive it (it lives at the call site) @param[in] ichar indentation character to use @param[in] pretty_print_ whether the output shall be pretty-printed @param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII @@ -21424,12 +21425,12 @@ class serializer being threaded through every call to @ref dump, @ref dump_internal and @ref dump_iteratively. */ - serializer(output_adapter_t s, const char ichar, + serializer(output_adapter_protocol* s, const char ichar, const bool pretty_print_ = false, const bool ensure_ascii_ = false, const std::size_t indent_step_ = 0, error_handler_t error_handler_ = error_handler_t::strict) - : o(std::move(s)) + : o(s) , locale(std::localeconv()) , indent_char(ichar) , pretty_print(pretty_print_) @@ -23026,8 +23027,8 @@ class serializer const char decimal_point; }; - /// the output of the serializer - output_adapter_t o = nullptr; + /// the output of the serializer (non-owning; the adapter lives at the call site) + output_adapter_protocol* o = nullptr; /// a (hopefully) large enough character buffer std::array number_buffer{{}}; @@ -24738,16 +24739,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const error_handler_t error_handler = error_handler_t::strict) const { string_t result; + detail::output_string_adapter string_adapter(result); if (indent >= 0) { - serializer s(detail::output_adapter(result), indent_char, + serializer s(&string_adapter, indent_char, true, ensure_ascii, static_cast(indent), error_handler); s.dump(*this); } else { - serializer s(detail::output_adapter(result), indent_char, + serializer s(&string_adapter, indent_char, false, ensure_ascii, 0, error_handler); s.dump(*this); } @@ -27478,7 +27480,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec o.width(0); // do the actual serialization - serializer s(detail::output_adapter(o), o.fill(), + detail::output_stream_adapter stream_adapter(o); + serializer s(&stream_adapter, o.fill(), pretty_print, false, static_cast(indentation)); s.dump(j); return o; diff --git a/tests/src/unit-convenience.cpp b/tests/src/unit-convenience.cpp index 266497867..fcf6ba73c 100644 --- a/tests/src/unit-convenience.cpp +++ b/tests/src/unit-convenience.cpp @@ -98,7 +98,8 @@ void check_escaped(const char* original, const char* escaped = "", bool ensure_a void check_escaped(const char* original, const char* escaped, const bool ensure_ascii) { std::stringstream ss; - json::serializer s(nlohmann::detail::output_adapter(ss), ' ', false, ensure_ascii); + nlohmann::detail::output_stream_adapter adapter(ss); + json::serializer s(&adapter, ' ', false, ensure_ascii); s.dump_escaped(original); s.flush(); // dump_escaped writes into the serializer's internal buffer CHECK(ss.str() == escaped);