diff --git a/README.md b/README.md index b3d13916a..cb7e85a31 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,15 @@ Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if If you are using [`wsjcpp`](https://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch. +If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake: + +```cmake +CPMAddPackage( + NAME nlohmann_json + GITHUB_REPOSITORY nlohmann/json + VERSION 3.9.1) +``` + ### Pkg-config If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed: diff --git a/include/nlohmann/byte_container_with_subtype.hpp b/include/nlohmann/byte_container_with_subtype.hpp index 69f9feb21..ee3ab4011 100644 --- a/include/nlohmann/byte_container_with_subtype.hpp +++ b/include/nlohmann/byte_container_with_subtype.hpp @@ -39,15 +39,15 @@ class byte_container_with_subtype : public BinaryType : container_type(std::move(b)) {} - byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b))) + byte_container_with_subtype(const container_type& b, std::uint8_t subtype_) noexcept(noexcept(container_type(b))) : container_type(b) - , m_subtype(subtype) + , m_subtype(subtype_) , m_has_subtype(true) {} - byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) + byte_container_with_subtype(container_type&& b, std::uint8_t subtype_) noexcept(noexcept(container_type(std::move(b)))) : container_type(std::move(b)) - , m_subtype(subtype) + , m_subtype(subtype_) , m_has_subtype(true) {} @@ -80,9 +80,9 @@ class byte_container_with_subtype : public BinaryType @since version 3.8.0 */ - void set_subtype(std::uint8_t subtype) noexcept + void set_subtype(std::uint8_t subtype_) noexcept { - m_subtype = subtype; + m_subtype = subtype_; m_has_subtype = true; } diff --git a/include/nlohmann/detail/json_ref.hpp b/include/nlohmann/detail/json_ref.hpp index c9bf6cb22..18e09f051 100644 --- a/include/nlohmann/detail/json_ref.hpp +++ b/include/nlohmann/detail/json_ref.hpp @@ -17,19 +17,14 @@ class json_ref json_ref(value_type&& value) : owned_value(std::move(value)) - , value_ref(&owned_value) - , is_rvalue(true) {} json_ref(const value_type& value) - : value_ref(const_cast(&value)) - , is_rvalue(false) + : value_ref(&value) {} json_ref(std::initializer_list init) : owned_value(init) - , value_ref(&owned_value) - , is_rvalue(true) {} template < @@ -37,8 +32,6 @@ class json_ref enable_if_t::value, int> = 0 > json_ref(Args && ... args) : owned_value(std::forward(args)...) - , value_ref(&owned_value) - , is_rvalue(true) {} // class should be movable only @@ -50,27 +43,26 @@ class json_ref value_type moved_or_copied() const { - if (is_rvalue) + if (value_ref == nullptr) { - return std::move(*value_ref); + return std::move(owned_value); } return *value_ref; } value_type const& operator*() const { - return *static_cast(value_ref); + return value_ref ? *value_ref : owned_value; } value_type const* operator->() const { - return static_cast(value_ref); + return &**this; } private: mutable value_type owned_value = nullptr; - value_type* value_ref = nullptr; - const bool is_rvalue = true; + value_type const* value_ref = nullptr; }; } // namespace detail } // namespace nlohmann diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index f59e8ad31..0a34c8011 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -881,6 +881,7 @@ class serializer } }; + JSON_ASSERT(byte < utf8d.size()); const std::uint8_t type = utf8d[byte]; codep = (state != UTF8_ACCEPT) diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 7dd644543..330677c4d 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -168,6 +168,19 @@ template , Container::push_back(value); return {--this->end(), true}; } + + template + using require_input_iter = typename std::enable_if::iterator_category, + std::input_iterator_tag>::value>::type; + + template> + void insert(InputIt first, InputIt last) + { + for (auto it = first; it != last; ++it) + { + insert(*it); + } + } }; } // namespace nlohmann diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e821c79a3..835140b3d 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -12605,19 +12605,14 @@ class json_ref json_ref(value_type&& value) : owned_value(std::move(value)) - , value_ref(&owned_value) - , is_rvalue(true) {} json_ref(const value_type& value) - : value_ref(const_cast(&value)) - , is_rvalue(false) + : value_ref(&value) {} json_ref(std::initializer_list init) : owned_value(init) - , value_ref(&owned_value) - , is_rvalue(true) {} template < @@ -12625,8 +12620,6 @@ class json_ref enable_if_t::value, int> = 0 > json_ref(Args && ... args) : owned_value(std::forward(args)...) - , value_ref(&owned_value) - , is_rvalue(true) {} // class should be movable only @@ -12638,27 +12631,26 @@ class json_ref value_type moved_or_copied() const { - if (is_rvalue) + if (value_ref == nullptr) { - return std::move(*value_ref); + return std::move(owned_value); } return *value_ref; } value_type const& operator*() const { - return *static_cast(value_ref); + return value_ref ? *value_ref : owned_value; } value_type const* operator->() const { - return static_cast(value_ref); + return &**this; } private: mutable value_type owned_value = nullptr; - value_type* value_ref = nullptr; - const bool is_rvalue = true; + value_type const* value_ref = nullptr; }; } // namespace detail } // namespace nlohmann @@ -16392,6 +16384,7 @@ class serializer } }; + JSON_ASSERT(byte < utf8d.size()); const std::uint8_t type = utf8d[byte]; codep = (state != UTF8_ACCEPT) @@ -16634,6 +16627,19 @@ template , Container::push_back(value); return {--this->end(), true}; } + + template + using require_input_iter = typename std::enable_if::iterator_category, + std::input_iterator_tag>::value>::type; + + template> + void insert(InputIt first, InputIt last) + { + for (auto it = first; it != last; ++it) + { + insert(*it); + } + } }; } // namespace nlohmann diff --git a/test/src/unit-ordered_json.cpp b/test/src/unit-ordered_json.cpp index 9b242c825..9bd1187e4 100644 --- a/test/src/unit-ordered_json.cpp +++ b/test/src/unit-ordered_json.cpp @@ -76,4 +76,18 @@ TEST_CASE("ordered_json") CHECK(multi_ordered.dump() == "{\"z\":1,\"m\":2,\"y\":4}"); CHECK(multi_ordered.erase("m") == 1); CHECK(multi_ordered.dump() == "{\"z\":1,\"y\":4}"); + + // Ranged insert test. + // It seems that values shouldn't be overwritten. Only new values are added + json j1 {{"c", 1}, {"b", 2}, {"a", 3}}; + const json j2 {{"c", 77}, {"d", 42}, {"a", 4}}; + j1.insert( j2.cbegin(), j2.cend() ); + CHECK(j1.size() == 4); + CHECK(j1.dump() == "{\"a\":3,\"b\":2,\"c\":1,\"d\":42}"); + + ordered_json oj1 {{"c", 1}, {"b", 2}, {"a", 3}}; + const ordered_json oj2 {{"c", 77}, {"d", 42}, {"a", 4}}; + oj1.insert( oj2.cbegin(), oj2.cend() ); + CHECK(oj1.size() == 4); + CHECK(oj1.dump() == "{\"c\":1,\"b\":2,\"a\":3,\"d\":42}"); }