diff options
author | GitHub Actions <action@github.com> | 2020-06-28 14:43:51 +0300 |
---|---|---|
committer | GitHub Actions <action@github.com> | 2020-06-28 14:43:51 +0300 |
commit | 363880a442feaf66aef91baacbf19c6fd62bb5d3 (patch) | |
tree | 4fd9a50cea756e8a2fdde3d4f44b835ac6c2e9ba | |
parent | a2b994bcb695ae15cca25dc9ffc52b93d6f2a8ea (diff) |
Upstream release v3.1.2v3.1.2
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | include/nlohmann/json.hpp | 298 |
2 files changed, 205 insertions, 95 deletions
@@ -13,7 +13,7 @@ include(FetchContent) FetchContent_Declare(json GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohman_json - GIT_TAG v3.1.1) + GIT_TAG v3.1.2) FetchContent_GetProperties(json) if(NOT json_POPULATED) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 3dcb834..6b6655a 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.1.1 +| | |__ | | | | | | version 3.1.2 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License <http://opensource.org/licenses/MIT>. @@ -31,7 +31,7 @@ SOFTWARE. #define NLOHMANN_JSON_VERSION_MAJOR 3 #define NLOHMANN_JSON_VERSION_MINOR 1 -#define NLOHMANN_JSON_VERSION_PATCH 1 +#define NLOHMANN_JSON_VERSION_PATCH 2 #include <algorithm> // all_of, find, for_each #include <cassert> // assert @@ -466,7 +466,7 @@ struct is_compatible_complete_type { static constexpr bool value = not std::is_base_of<std::istream, CompatibleCompleteType>::value and - not std::is_same<BasicJsonType, CompatibleCompleteType>::value and + not is_basic_json<CompatibleCompleteType>::value and not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and has_to_json<BasicJsonType, CompatibleCompleteType>::value; }; @@ -1871,6 +1871,7 @@ class lexer 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; public: /// token types for the parser @@ -2969,7 +2970,7 @@ scan_number_done: } /// return current string value (implicitly resets the token; useful only once) - std::string move_string() + string_t&& move_string() { return std::move(token_buffer); } @@ -3099,7 +3100,7 @@ scan_number_done: std::vector<char> token_string {}; /// buffer for variable-length tokens (numbers, strings) - std::string token_buffer {}; + string_t token_buffer {}; /// a description of occurred lexer errors const char* error_message = ""; @@ -3155,6 +3156,7 @@ 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<BasicJsonType>; using token_type = typename lexer_t::token_type; @@ -3298,7 +3300,7 @@ class parser } // parse values - std::string key; + string_t key; BasicJsonType value; while (true) { @@ -3526,6 +3528,7 @@ class parser if (keep and callback and not callback(depth, parse_event_t::value, result)) { + result.m_value.destroy(result.m_type); result.m_type = value_t::discarded; } } @@ -4776,11 +4779,11 @@ class output_stream_adapter : public output_adapter_protocol<CharType> }; /// output adapter for basic_string -template<typename CharType> +template<typename CharType, typename StringType = std::basic_string<CharType>> class output_string_adapter : public output_adapter_protocol<CharType> { public: - explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {} + explicit output_string_adapter(StringType& s) : str(s) {} void write_character(CharType c) override { @@ -4793,10 +4796,10 @@ class output_string_adapter : public output_adapter_protocol<CharType> } private: - std::basic_string<CharType>& str; + StringType& str; }; -template<typename CharType> +template<typename CharType, typename StringType = std::basic_string<CharType>> class output_adapter { public: @@ -4806,8 +4809,8 @@ class output_adapter output_adapter(std::basic_ostream<CharType>& s) : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} - output_adapter(std::basic_string<CharType>& s) - : oa(std::make_shared<output_string_adapter<CharType>>(s)) {} + output_adapter(StringType& s) + : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {} operator output_adapter_t<CharType>() { @@ -6909,114 +6912,124 @@ class binary_writer oa->write_characters(vec.data(), sizeof(NumberType)); } - template<typename NumberType> + // UBJSON: write number (floating point) + template<typename NumberType, typename std::enable_if< + std::is_floating_point<NumberType>::value, int>::type = 0> + void write_number_with_ubjson_prefix(const NumberType n, + const bool add_prefix) + { + if (add_prefix) + { + oa->write_character(static_cast<CharType>('D')); // float64 + } + write_number(n); + } + + // UBJSON: write number (unsigned integer) + template<typename NumberType, typename std::enable_if< + std::is_unsigned<NumberType>::value, int>::type = 0> void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix) { - if (std::is_floating_point<NumberType>::value) + if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)())) { if (add_prefix) { - oa->write_character(static_cast<CharType>('D')); // float64 + oa->write_character(static_cast<CharType>('i')); // int8 } - write_number(n); + write_number(static_cast<uint8_t>(n)); } - else if (std::is_unsigned<NumberType>::value) + else if (n <= (std::numeric_limits<uint8_t>::max)()) { - if (n <= (std::numeric_limits<int8_t>::max)()) - { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('i')); // int8 - } - write_number(static_cast<uint8_t>(n)); - } - else if (n <= (std::numeric_limits<uint8_t>::max)()) - { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('U')); // uint8 - } - write_number(static_cast<uint8_t>(n)); - } - else if (n <= (std::numeric_limits<int16_t>::max)()) + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('I')); // int16 - } - write_number(static_cast<int16_t>(n)); + oa->write_character(static_cast<CharType>('U')); // uint8 } - else if (n <= (std::numeric_limits<int32_t>::max)()) + write_number(static_cast<uint8_t>(n)); + } + else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)())) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('l')); // int32 - } - write_number(static_cast<int32_t>(n)); + oa->write_character(static_cast<CharType>('I')); // int16 } - else if (n <= (std::numeric_limits<int64_t>::max)()) + write_number(static_cast<int16_t>(n)); + } + else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)())) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('L')); // int64 - } - write_number(static_cast<int64_t>(n)); + oa->write_character(static_cast<CharType>('l')); // int32 } - else + write_number(static_cast<int32_t>(n)); + } + else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)())) + { + if (add_prefix) { - JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); + oa->write_character(static_cast<CharType>('L')); // int64 } + write_number(static_cast<int64_t>(n)); } else { - if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)()) + JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); + } + } + + // UBJSON: write number (signed integer) + template<typename NumberType, typename std::enable_if< + std::is_signed<NumberType>::value and + not std::is_floating_point<NumberType>::value, int>::type = 0> + void write_number_with_ubjson_prefix(const NumberType n, + const bool add_prefix) + { + if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)()) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('i')); // int8 - } - write_number(static_cast<int8_t>(n)); + oa->write_character(static_cast<CharType>('i')); // int8 } - else if ((std::numeric_limits<uint8_t>::min)() <= n and n <= (std::numeric_limits<uint8_t>::max)()) + write_number(static_cast<int8_t>(n)); + } + else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)())) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('U')); // uint8 - } - write_number(static_cast<uint8_t>(n)); + oa->write_character(static_cast<CharType>('U')); // uint8 } - else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)()) + write_number(static_cast<uint8_t>(n)); + } + else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)()) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('I')); // int16 - } - write_number(static_cast<int16_t>(n)); + oa->write_character(static_cast<CharType>('I')); // int16 } - else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)()) - { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('l')); // int32 - } - write_number(static_cast<int32_t>(n)); - } - else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)()) + write_number(static_cast<int16_t>(n)); + } + else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)()) + { + if (add_prefix) { - if (add_prefix) - { - oa->write_character(static_cast<CharType>('L')); // int64 - } - write_number(static_cast<int64_t>(n)); + oa->write_character(static_cast<CharType>('l')); // int32 } - // LCOV_EXCL_START - else + write_number(static_cast<int32_t>(n)); + } + else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)()) + { + if (add_prefix) { - JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); + oa->write_character(static_cast<CharType>('L')); // int64 } - // LCOV_EXCL_STOP + write_number(static_cast<int64_t>(n)); + } + // LCOV_EXCL_START + else + { + JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); } + // LCOV_EXCL_STOP } /*! @@ -10535,7 +10548,7 @@ class basic_json object = nullptr; // silence warning, see #821 if (JSON_UNLIKELY(t == value_t::null)) { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE + JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE } break; } @@ -10805,6 +10818,7 @@ class basic_json - @a CompatibleType is not derived from `std::istream`, - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move constructors), + - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) - @a CompatibleType is not a @ref basic_json nested type (e.g., @ref json_pointer, @ref iterator, etc ...) - @ref @ref json_serializer<U> has a @@ -10841,6 +10855,78 @@ class basic_json } /*! + @brief create a JSON value from an existing one + + This is a constructor for existing @ref basic_json types. + It does not hijack copy/move constructors, since the parameter has different + template arguments than the current ones. + + The constructor tries to convert the internal @ref m_value of the parameter. + + @tparam BasicJsonType a type such that: + - @a BasicJsonType is a @ref basic_json type. + - @a BasicJsonType has different template arguments than @ref basic_json_t. + + @param[in] val the @ref basic_json value to be converted. + + @complexity Usually linear in the size of the passed @a val, also + depending on the implementation of the called `to_json()` + method. + + @exceptionsafety Depends on the called constructor. For types directly + supported by the library (i.e., all types for which no `to_json()` function + was provided), strong guarantee holds: if an exception is thrown, there are + no changes to any JSON value. + + @since version 3.1.2 + */ + template <typename BasicJsonType, + detail::enable_if_t< + detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0> + basic_json(const BasicJsonType& val) + { + using other_boolean_t = typename BasicJsonType::boolean_t; + using other_number_float_t = typename BasicJsonType::number_float_t; + using other_number_integer_t = typename BasicJsonType::number_integer_t; + using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using other_string_t = typename BasicJsonType::string_t; + using other_object_t = typename BasicJsonType::object_t; + using other_array_t = typename BasicJsonType::array_t; + + switch (val.type()) + { + case value_t::boolean: + JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>()); + break; + case value_t::number_float: + JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>()); + break; + case value_t::number_integer: + JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>()); + break; + case value_t::number_unsigned: + JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>()); + break; + case value_t::string: + JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>()); + break; + case value_t::object: + JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>()); + break; + case value_t::array: + JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>()); + break; + case value_t::null: + *this = nullptr; + break; + case value_t::discarded: + m_type = value_t::discarded; + break; + } + assert_invariant(); + } + + /*! @brief create a container (array or object) from an initializer list Creates a JSON value of type array or object from the passed initializer @@ -11472,7 +11558,7 @@ class basic_json const bool ensure_ascii = false) const { string_t result; - serializer s(detail::output_adapter<char>(result), indent_char); + serializer s(detail::output_adapter<char, string_t>(result), indent_char); if (indent >= 0) { @@ -12013,6 +12099,29 @@ class basic_json } /*! + @brief get special-case overload + + This overloads converts the current @ref basic_json in a different + @ref basic_json type + + @tparam BasicJsonType == @ref basic_json + + @return a copy of *this, converted into @tparam BasicJsonType + + @complexity Depending on the implementation of the called `from_json()` + method. + + @since version 3.1.2 + */ + template<typename BasicJsonType, detail::enable_if_t< + not std::is_same<BasicJsonType, basic_json>::value and + detail::is_basic_json<BasicJsonType>::value, int> = 0> + BasicJsonType get() const + { + return *this; + } + + /*! @brief get a value (explicit) Explicit type conversion between the JSON value and a compatible value @@ -12053,7 +12162,7 @@ class basic_json */ template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>, detail::enable_if_t < - not std::is_same<basic_json_t, ValueType>::value and + not detail::is_basic_json<ValueType>::value and detail::has_from_json<basic_json_t, ValueType>::value and not detail::has_non_default_from_json<basic_json_t, ValueType>::value, int> = 0> @@ -12319,7 +12428,8 @@ class basic_json template < typename ValueType, typename std::enable_if < not std::is_pointer<ValueType>::value and not std::is_same<ValueType, detail::json_ref<basic_json>>::value and - not std::is_same<ValueType, typename string_t::value_type>::value + not std::is_same<ValueType, typename string_t::value_type>::value and + not detail::is_basic_json<ValueType>::value #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value #endif @@ -14777,7 +14887,7 @@ class basic_json // passed iterators must belong to objects if (JSON_UNLIKELY(not first.m_object->is_object() - or not first.m_object->is_object())) + or not last.m_object->is_object())) { JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects")); } |