From bec5bd2d1c308178e5a0887c20b23a409942fa29 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 10 Oct 2021 00:39:38 +0000 Subject: Upstream release v3.10.3 --- README.md | 2 +- include/nlohmann/json.hpp | 313 ++++++++++++++++++++++++++++++---------------- 2 files changed, 207 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index 0f102ef..6284668 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ include(FetchContent) FetchContent_Declare(json GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent - GIT_TAG v3.10.2) + GIT_TAG v3.10.3) FetchContent_GetProperties(json) if(NOT json_POPULATED) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 8959265..25c6983 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.10.2 +| | |__ | | | | | | version 3.10.3 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -32,7 +32,7 @@ SOFTWARE. #define NLOHMANN_JSON_VERSION_MAJOR 3 #define NLOHMANN_JSON_VERSION_MINOR 10 -#define NLOHMANN_JSON_VERSION_PATCH 2 +#define NLOHMANN_JSON_VERSION_PATCH 3 #include // all_of, find, for_each #include // nullptr_t, ptrdiff_t, size_t @@ -167,7 +167,7 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept // #include -#include // pair +#include // declval, pair // #include @@ -2214,6 +2214,83 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ +// #include + + +#include + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; +} // namespace detail +} // namespace nlohmann + + +// https://en.cppreference.com/w/cpp/experimental/is_detected +namespace nlohmann +{ +namespace detail +{ +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; +} // namespace detail +} // namespace nlohmann + // This file contains all internal macro definitions // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them @@ -2504,6 +2581,45 @@ JSON_HEDLEY_DIAGNOSTIC_POP inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 #endif @@ -3207,6 +3323,9 @@ template struct identity_tag {}; #include // declval #include // tuple +// #include + + // #include @@ -3214,19 +3333,6 @@ template struct identity_tag {}; // #include - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - // #include @@ -3275,73 +3381,31 @@ struct iterator_traits::value>> } // namespace detail } // namespace nlohmann -// #include - -// #include - -// #include - +// #include -#include -// #include +// #include -// https://en.cppreference.com/w/cpp/experimental/is_detected namespace nlohmann { -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); +} // namespace nlohmann -template class Op, class... Args> -using is_detected = typename detector::value_t; +// #include -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; -template class Op, class... Args> -using detected_t = typename detector::type; +// #include -template class Op, class... Args> -using detected_or = detector; -template class Op, class... Args> -using detected_or_t = typename detected_or::type; +namespace nlohmann +{ +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); +} // namespace nlohmann -template class Op, class... Args> -using is_detected_exact = std::is_same>; +// #include -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; -} // namespace detail -} // namespace nlohmann +// #include // #include #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ @@ -3492,9 +3556,6 @@ using reference_t = typename T::reference; template using iterator_category_t = typename T::iterator_category; -template -using iterator_t = typename T::iterator; - template using to_json_function = decltype(T::to_json(std::declval()...)); @@ -3630,6 +3691,31 @@ struct is_iterator_traits> is_detected::value; }; +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + // The following implementation of is_complete_type is taken from // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ // and is written by Xiang Fan who agreed to using it in this library. @@ -3704,8 +3790,9 @@ struct is_compatible_string_type_impl : std::false_type {}; template struct is_compatible_string_type_impl < BasicJsonType, CompatibleStringType, - enable_if_t::value >> + enable_if_t::value >> { static constexpr auto value = is_constructible::value; @@ -3740,17 +3827,13 @@ struct is_compatible_array_type_impl : std::false_type {}; template struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, - enable_if_t < is_detected::value&& + enable_if_t < is_detected::value&& -// This is needed because json_reverse_iterator has a ::iterator type... -// Therefore it is detected as a CompatibleArrayType. -// The real fix would be to have an Iterable concept. - !is_iterator_traits < - iterator_traits>::value >> + is_iterator_traits>>::value >> { static constexpr bool value = is_constructible::value; + range_value_t>::value; }; template @@ -3772,28 +3855,26 @@ struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& is_default_constructible::value&& (std::is_move_assignable::value || std::is_copy_assignable::value)&& -is_detected::value&& is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& is_complete_type < -detected_t>::value >> +detected_t>::value >> { + using value_type = range_value_t; + static constexpr bool value = - // This is needed because json_reverse_iterator has a ::iterator type, - // furthermore, std::back_insert_iterator (and other iterators) have a - // base class `iterator`... Therefore it is detected as a - // ConstructibleArrayType. The real fix would be to have an Iterable - // concept. - !is_iterator_traits>::value && - - (std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, typename ConstructibleArrayType::value_type >::value); + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; }; template @@ -13485,11 +13566,11 @@ template using output_adapter_t = std::shared_ptr>; /// output adapter for byte vectors -template +template> class output_vector_adapter : public output_adapter_protocol { public: - explicit output_vector_adapter(std::vector& vec) noexcept + explicit output_vector_adapter(std::vector& vec) noexcept : v(vec) {} @@ -13505,7 +13586,7 @@ class output_vector_adapter : public output_adapter_protocol } private: - std::vector& v; + std::vector& v; }; #ifndef JSON_NO_IO @@ -13562,8 +13643,9 @@ template> class output_adapter { public: - output_adapter(std::vector& vec) - : oa(std::make_shared>(vec)) {} + template> + output_adapter(std::vector& vec) + : oa(std::make_shared>(vec)) {} #ifndef JSON_NO_IO output_adapter(std::basic_ostream& s) @@ -18470,7 +18552,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec object = nullptr; // silence warning, see #821 if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE + JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.3", basic_json())); // LCOV_EXCL_LINE } break; } @@ -21100,15 +21182,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec if (idx >= m_value.array->size()) { #if JSON_DIAGNOSTICS - // remember array size before resizing - const auto previous_size = m_value.array->size(); + // remember array size & capacity before resizing + const auto old_size = m_value.array->size(); + const auto old_capacity = m_value.array->capacity(); #endif m_value.array->resize(idx + 1); #if JSON_DIAGNOSTICS - // set parent for values added above - set_parents(begin() + static_cast(previous_size), static_cast(idx + 1 - previous_size)); + if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) + { + // capacity has changed: update all parents + set_parents(); + } + else + { + // set parent for values added above + set_parents(begin() + static_cast(old_size), static_cast(idx + 1 - old_size)); + } #endif + assert_invariant(); } return m_value.array->operator[](idx); @@ -23414,6 +23506,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec for (auto it = j.cbegin(); it != j.cend(); ++it) { m_value.object->operator[](it.key()) = it.value(); +#if JSON_DIAGNOSTICS + m_value.object->operator[](it.key()).m_parent = this; +#endif } } @@ -23474,6 +23569,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec for (auto it = first; it != last; ++it) { m_value.object->operator[](it.key()) = it.value(); +#if JSON_DIAGNOSTICS + m_value.object->operator[](it.key()).m_parent = this; +#endif } } @@ -26482,6 +26580,7 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION #undef NLOHMANN_BASIC_JSON_TPL #undef JSON_EXPLICIT +#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL // #include -- cgit v1.2.3