diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 263fdb525c..2f0906705b 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -20,6 +20,7 @@ #include // char_traits, string #include // make_pair, move #include // vector +#include #include #include @@ -62,7 +63,8 @@ static inline bool little_endianness(int num = 1) noexcept /*! @brief deserialization of CBOR, MessagePack, and UBJSON values */ -template> +template, typename AllocatorChar = std::allocator< typename InputAdapterType::char_type> + , typename SAX = json_sax_dom_parser> class binary_reader { using number_integer_t = typename BasicJsonType::number_integer_t; @@ -2694,7 +2696,7 @@ class binary_reader // parse number string using ia_type = decltype(detail::input_adapter(number_vector)); - auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); + auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); const auto result_number = number_lexer.scan(); const auto number_string = number_lexer.get_token_string(); const auto result_remainder = number_lexer.scan(); @@ -2714,7 +2716,7 @@ class binary_reader case token_type::value_unsigned: return sax->number_unsigned(number_lexer.get_number_unsigned()); case token_type::value_float: - return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); + return sax->number_float(number_lexer.get_number_float(), std::move(static_cast(number_string))); case token_type::uninitialized: case token_type::literal_true: case token_type::literal_false: @@ -3001,8 +3003,8 @@ class binary_reader }; #ifndef JSON_HAS_CPP_17 - template - constexpr std::size_t binary_reader::npos; + template + constexpr std::size_t binary_reader::npos; #endif } // namespace detail diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index ce1c66065f..03fcc19e44 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -12,6 +12,7 @@ #include // string #include // move #include // vector +#include #include #include @@ -157,7 +158,7 @@ constructor contains the parsed value. @tparam BasicJsonType the JSON type */ -template +template> class json_sax_dom_parser { public: @@ -331,7 +332,7 @@ class json_sax_dom_parser /// the parsed JSON value BasicJsonType& root; /// stack to model hierarchy of values - std::vector ref_stack {}; + std::vector ref_stack {}; /// helper to hold the reference for the next object element BasicJsonType* object_element = nullptr; /// whether a syntax error occurred diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index 50fc9df59d..be2ae048e1 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -17,6 +17,7 @@ #include // char_traits, string #include // move #include // vector +#include #include #include @@ -107,7 +108,7 @@ class lexer_base This class organizes the lexical analysis during JSON deserialization. */ -template +template> class lexer : public lexer_base { using number_integer_t = typename BasicJsonType::number_integer_t; @@ -1611,7 +1612,7 @@ class lexer : public lexer_base position_t position {}; /// raw input token string (for error messages) - std::vector token_string {}; + std::vector token_string {}; /// buffer for variable-length tokens (numbers, strings) string_t token_buffer {}; diff --git a/include/nlohmann/detail/input/parser.hpp b/include/nlohmann/detail/input/parser.hpp index 8acbd4fcad..f6a4a3ea92 100644 --- a/include/nlohmann/detail/input/parser.hpp +++ b/include/nlohmann/detail/input/parser.hpp @@ -56,14 +56,14 @@ using parser_callback_t = This class implements a recursive descent parser. */ -template +template class parser { using number_integer_t = typename BasicJsonType::number_integer_t; using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using lexer_t = lexer; + using lexer_t = lexer; using token_type = typename lexer_t::token_type; public: @@ -122,7 +122,7 @@ class parser } else { - json_sax_dom_parser sdp(result, allow_exceptions); + json_sax_dom_parser sdp(result, allow_exceptions); sax_parse_internal(&sdp); // in strict mode, input must be completely read @@ -181,7 +181,8 @@ class parser { // stack to remember the hierarchy of structured values we are parsing // true = array; false = object - std::vector states; + std::vector states; + // value to avoid a goto (see comment where set to true) bool skip_to_state_evaluation = false; diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index d3495a4bbe..232e97d5cb 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -1110,7 +1110,7 @@ class binary_writer const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) { - return result + calc_bson_element_size(std::to_string(array_index++), el); + return result + calc_bson_element_size(static_cast(std::to_string(array_index++)), el); }); return sizeof(std::int32_t) + embedded_document_size + 1ul; @@ -1137,7 +1137,7 @@ class binary_writer for (const auto& el : value) { - write_bson_element(std::to_string(array_index++), el); + write_bson_element(static_cast(std::to_string(array_index++)), el); } oa->write_character(to_char_type(0x00)); diff --git a/include/nlohmann/detail/output/output_adapters.hpp b/include/nlohmann/detail/output/output_adapters.hpp index 630bd8f73f..0f59340353 100644 --- a/include/nlohmann/detail/output/output_adapters.hpp +++ b/include/nlohmann/detail/output/output_adapters.hpp @@ -124,7 +124,10 @@ class output_adapter public: template> output_adapter(std::vector& vec) - : oa(std::make_shared>(vec)) {} + { + AllocatorType alloc; + oa = std::allocate_shared>(alloc, vec); + } #ifndef JSON_NO_IO output_adapter(std::basic_ostream& s) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index f7fac1fb40..62c8c123a5 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -105,16 +105,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // can be restored when json_pointer backwards compatibility is removed // friend ::nlohmann::json_pointer; - template + template friend class ::nlohmann::detail::parser; friend ::nlohmann::detail::serializer; template friend class ::nlohmann::detail::iter_impl; template friend class ::nlohmann::detail::binary_writer; - template + template friend class ::nlohmann::detail::binary_reader; - template + template friend class ::nlohmann::detail::json_sax_dom_parser; template friend class ::nlohmann::detail::json_sax_dom_callback_parser; @@ -129,14 +129,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec using lexer = ::nlohmann::detail::lexer_base; template - static ::nlohmann::detail::parser parser( - InputAdapterType adapter, - detail::parser_callback_tcb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false - ) + static ::nlohmann::detail::parser, AllocatorType, AllocatorType> parser( + InputAdapterType adapter, + detail::parser_callback_tcb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false + ) { - return ::nlohmann::detail::parser(std::move(adapter), + return ::nlohmann::detail::parser, AllocatorType, AllocatorType>(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); } @@ -153,8 +153,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template using output_adapter_t = ::nlohmann::detail::output_adapter_t; - template - using binary_reader = ::nlohmann::detail::binary_reader; + template + using binary_reader = ::nlohmann::detail::binary_reader, AllocatorType>; template using binary_writer = ::nlohmann::detail::binary_writer; JSON_PRIVATE_UNLESS_TESTED: @@ -218,7 +218,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the allocator type using allocator_type = AllocatorType; - + using allocator_type_ptr = AllocatorType; + using allocator_type_char = AllocatorType; /// the type of an element pointer using pointer = typename std::allocator_traits::pointer; /// the type of an element const pointer @@ -566,7 +567,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec if (t == value_t::array || t == value_t::object) { // flatten the current json_value to a heap-allocated stack - std::vector stack; + std::vector> stack; // move the top-level items to stack if (t == value_t::array) @@ -4087,7 +4088,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec auto ia = detail::input_adapter(std::forward(i)); return format == input_format_t::json ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } /// @brief generate SAX events @@ -4102,7 +4103,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec auto ia = detail::input_adapter(std::move(first), std::move(last)); return format == input_format_t::json ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } /// @brief generate SAX events @@ -4123,7 +4124,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } #ifndef JSON_NO_IO /// @brief deserialize from stream @@ -4365,7 +4366,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); return res ? result : basic_json(value_t::discarded); @@ -4381,7 +4382,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); return res ? result : basic_json(value_t::discarded); @@ -4406,7 +4407,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); @@ -4422,7 +4423,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4437,7 +4438,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4460,7 +4461,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); @@ -4476,7 +4477,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4491,7 +4492,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4514,7 +4515,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); @@ -4530,7 +4531,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4545,7 +4546,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4560,7 +4561,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4575,7 +4576,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -4598,7 +4599,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index ac4a1d08b7..992a75d703 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6068,6 +6068,7 @@ NLOHMANN_JSON_NAMESPACE_END #include // char_traits, string #include // make_pair, move #include // vector +#include // #include @@ -6581,6 +6582,7 @@ NLOHMANN_JSON_NAMESPACE_END #include // string #include // move #include // vector +#include // #include @@ -6729,7 +6731,7 @@ constructor contains the parsed value. @tparam BasicJsonType the JSON type */ -template +template> class json_sax_dom_parser { public: @@ -6903,7 +6905,7 @@ class json_sax_dom_parser /// the parsed JSON value BasicJsonType& root; /// stack to model hierarchy of values - std::vector ref_stack {}; + std::vector ref_stack {}; /// helper to hold the reference for the next object element BasicJsonType* object_element = nullptr; /// whether a syntax error occurred @@ -7318,6 +7320,7 @@ NLOHMANN_JSON_NAMESPACE_END #include // char_traits, string #include // move #include // vector +#include // #include @@ -7411,7 +7414,7 @@ class lexer_base This class organizes the lexical analysis during JSON deserialization. */ -template +template> class lexer : public lexer_base { using number_integer_t = typename BasicJsonType::number_integer_t; @@ -8915,7 +8918,7 @@ class lexer : public lexer_base position_t position {}; /// raw input token string (for error messages) - std::vector token_string {}; + std::vector token_string {}; /// buffer for variable-length tokens (numbers, strings) string_t token_buffer {}; @@ -9139,7 +9142,8 @@ static inline bool little_endianness(int num = 1) noexcept /*! @brief deserialization of CBOR, MessagePack, and UBJSON values */ -template> +template, typename AllocatorChar = std::allocator< typename InputAdapterType::char_type> + , typename SAX = json_sax_dom_parser> class binary_reader { using number_integer_t = typename BasicJsonType::number_integer_t; @@ -11771,7 +11775,7 @@ class binary_reader // parse number string using ia_type = decltype(detail::input_adapter(number_vector)); - auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); + auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); const auto result_number = number_lexer.scan(); const auto number_string = number_lexer.get_token_string(); const auto result_remainder = number_lexer.scan(); @@ -11791,7 +11795,7 @@ class binary_reader case token_type::value_unsigned: return sax->number_unsigned(number_lexer.get_number_unsigned()); case token_type::value_float: - return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); + return sax->number_float(number_lexer.get_number_float(), std::move(static_cast(number_string))); case token_type::uninitialized: case token_type::literal_true: case token_type::literal_false: @@ -12078,8 +12082,8 @@ class binary_reader }; #ifndef JSON_HAS_CPP_17 - template - constexpr std::size_t binary_reader::npos; + template + constexpr std::size_t binary_reader::npos; #endif } // namespace detail @@ -12156,14 +12160,14 @@ using parser_callback_t = This class implements a recursive descent parser. */ -template +template class parser { using number_integer_t = typename BasicJsonType::number_integer_t; using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using lexer_t = lexer; + using lexer_t = lexer; using token_type = typename lexer_t::token_type; public: @@ -12222,7 +12226,7 @@ class parser } else { - json_sax_dom_parser sdp(result, allow_exceptions); + json_sax_dom_parser sdp(result, allow_exceptions); sax_parse_internal(&sdp); // in strict mode, input must be completely read @@ -12281,7 +12285,8 @@ class parser { // stack to remember the hierarchy of structured values we are parsing // true = array; false = object - std::vector states; + std::vector states; + // value to avoid a goto (see comment where set to true) bool skip_to_state_evaluation = false; @@ -14950,7 +14955,10 @@ class output_adapter public: template> output_adapter(std::vector& vec) - : oa(std::make_shared>(vec)) {} + { + AllocatorType alloc; + oa = std::allocate_shared>(alloc, vec); + } #ifndef JSON_NO_IO output_adapter(std::basic_ostream& s) @@ -16061,7 +16069,7 @@ class binary_writer const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) { - return result + calc_bson_element_size(std::to_string(array_index++), el); + return result + calc_bson_element_size(static_cast(std::to_string(array_index++)), el); }); return sizeof(std::int32_t) + embedded_document_size + 1ul; @@ -16088,7 +16096,7 @@ class binary_writer for (const auto& el : value) { - write_bson_element(std::to_string(array_index++), el); + write_bson_element(static_cast(std::to_string(array_index++)), el); } oa->write_character(to_char_type(0x00)); @@ -19319,16 +19327,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // can be restored when json_pointer backwards compatibility is removed // friend ::nlohmann::json_pointer; - template + template friend class ::nlohmann::detail::parser; friend ::nlohmann::detail::serializer; template friend class ::nlohmann::detail::iter_impl; template friend class ::nlohmann::detail::binary_writer; - template + template friend class ::nlohmann::detail::binary_reader; - template + template friend class ::nlohmann::detail::json_sax_dom_parser; template friend class ::nlohmann::detail::json_sax_dom_callback_parser; @@ -19343,14 +19351,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec using lexer = ::nlohmann::detail::lexer_base; template - static ::nlohmann::detail::parser parser( + static ::nlohmann::detail::parser, AllocatorType, AllocatorType> parser( InputAdapterType adapter, detail::parser_callback_tcb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false ) { - return ::nlohmann::detail::parser(std::move(adapter), + return ::nlohmann::detail::parser, AllocatorType, AllocatorType>(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); } @@ -19367,8 +19375,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template using output_adapter_t = ::nlohmann::detail::output_adapter_t; - template - using binary_reader = ::nlohmann::detail::binary_reader; + template + using binary_reader = ::nlohmann::detail::binary_reader, AllocatorType>; template using binary_writer = ::nlohmann::detail::binary_writer; JSON_PRIVATE_UNLESS_TESTED: @@ -19432,7 +19440,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the allocator type using allocator_type = AllocatorType; - + using allocator_type_ptr = AllocatorType; + using allocator_type_char = AllocatorType; /// the type of an element pointer using pointer = typename std::allocator_traits::pointer; /// the type of an element const pointer @@ -19780,7 +19789,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec if (t == value_t::array || t == value_t::object) { // flatten the current json_value to a heap-allocated stack - std::vector stack; + std::vector> stack; // move the top-level items to stack if (t == value_t::array) @@ -23301,7 +23310,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec auto ia = detail::input_adapter(std::forward(i)); return format == input_format_t::json ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } /// @brief generate SAX events @@ -23316,7 +23325,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec auto ia = detail::input_adapter(std::move(first), std::move(last)); return format == input_format_t::json ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } /// @brief generate SAX events @@ -23337,7 +23346,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); + : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } #ifndef JSON_NO_IO /// @brief deserialize from stream @@ -23579,7 +23588,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); return res ? result : basic_json(value_t::discarded); @@ -23595,7 +23604,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); return res ? result : basic_json(value_t::discarded); @@ -23620,7 +23629,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); @@ -23636,7 +23645,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23651,7 +23660,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23674,7 +23683,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); @@ -23690,7 +23699,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23705,7 +23714,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23728,7 +23737,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); @@ -23744,7 +23753,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23759,7 +23768,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23774,7 +23783,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::forward(i)); const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23789,7 +23798,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = detail::input_adapter(std::move(first), std::move(last)); const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); return res ? result : basic_json(value_t::discarded); @@ -23812,7 +23821,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool allow_exceptions = true) { basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); + detail::json_sax_dom_parser sdp(result, allow_exceptions); auto ia = i.get(); // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); diff --git a/tests/src/unit-allocator.cpp b/tests/src/unit-allocator.cpp index f9a25b24f7..7ea44f01ba 100644 --- a/tests/src/unit-allocator.cpp +++ b/tests/src/unit-allocator.cpp @@ -261,3 +261,90 @@ TEST_CASE("bad my_allocator::construct") j["test"].push_back("should not leak"); } } + + +TEST_CASE("controlled bad_alloc_rt_string") +{ + using RtString = std::basic_string, my_allocator>; + // create JSON type using the throwing allocator + using my_json = nlohmann::basic_json; + + + + SECTION("class json_value") + { + + SECTION("json_value(value_t)") + { + + SECTION("string") + { + next_construct_fails = false; + auto t = my_json::value_t::string; + CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).string)); + next_construct_fails = true; + CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&); + next_construct_fails = false; + } + } + + SECTION("json_value(const string_t&)") + { + next_construct_fails = false; + const my_json::string_t v("foo"); + CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(v).string)); + next_construct_fails = true; + CHECK_THROWS_AS(my_json::json_value(v), std::bad_alloc&); + next_construct_fails = false; + } + } + + SECTION("class basic_json_rt_string") + { + SECTION("basic_json(const CompatibleObjectType&)") + { + next_construct_fails = false; + const std::map v {{"foo", "bar"}}; + CHECK_NOTHROW(my_json(v)); + next_construct_fails = true; + CHECK_THROWS_AS(my_json(v), std::bad_alloc&); + next_construct_fails = false; + } + + SECTION("basic_json(const CompatibleArrayType&)") + { + next_construct_fails = false; + const std::vector v {"foo", "bar", "baz"}; + CHECK_NOTHROW(my_json(v)); + next_construct_fails = true; + CHECK_THROWS_AS(my_json(v), std::bad_alloc&); + next_construct_fails = false; + } + + SECTION("basic_json(const typename string_t::value_type*)") + { + next_construct_fails = false; + CHECK_NOTHROW(my_json("foo")); + next_construct_fails = true; + CHECK_THROWS_AS(my_json("foo"), std::bad_alloc&); + next_construct_fails = false; + } + + SECTION("basic_json(const typename string_t::value_type*)") + { + next_construct_fails = false; + const RtString s("foo"); + CHECK_NOTHROW(my_json(s)); + next_construct_fails = true; + CHECK_THROWS_AS(my_json(s), std::bad_alloc&); + next_construct_fails = false; + } + } +}