diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 0708e6f19..91bb663c5 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4960,6 +4960,8 @@ public: : m_value(v), m_old_size(old_size) {} array_append_rollback(const array_append_rollback&) = delete; array_append_rollback& operator=(const array_append_rollback&) = delete; + array_append_rollback(array_append_rollback&&) = delete; + array_append_rollback& operator=(array_append_rollback&&) = delete; void commit() noexcept { @@ -5098,6 +5100,8 @@ public: explicit object_clear_on_failure(basic_json* v) noexcept : m_value(v) {} object_clear_on_failure(const object_clear_on_failure&) = delete; object_clear_on_failure& operator=(const object_clear_on_failure&) = delete; + object_clear_on_failure(object_clear_on_failure&&) = delete; + object_clear_on_failure& operator=(object_clear_on_failure&&) = delete; void commit() noexcept { @@ -5128,6 +5132,8 @@ public: object_insert_rollback(basic_json* v, SourceIterator first) : m_value(v), m_first(first) {} object_insert_rollback(const object_insert_rollback&) = delete; object_insert_rollback& operator=(const object_insert_rollback&) = delete; + object_insert_rollback(object_insert_rollback&&) = delete; + object_insert_rollback& operator=(object_insert_rollback&&) = delete; /// call before each run of up to 64 members is inserted; may throw, which leaves the log complete void start_chunk() @@ -5168,7 +5174,7 @@ public: for (std::size_t i = 0; i < m_count; ++i, ++it) { const std::size_t chunk = i / 64; - const std::uint64_t word = chunk >= m_flushed ? m_word : (chunk < inline_words ? m_inline[chunk] : m_more[chunk - inline_words]); + const std::uint64_t word = logged_word(chunk); if (((word >> (i % 64)) & 1U) != 0) { object.erase(it->first); @@ -5181,14 +5187,24 @@ public: private: static constexpr std::size_t inline_words = 4; + /// the log word of a chunk: the one being filled, an inline one, or an overflow one + std::uint64_t logged_word(std::size_t chunk) const + { + if (chunk >= m_flushed) + { + return m_word; + } + return chunk < inline_words ? m_inline[chunk] : m_more[chunk - inline_words]; + } + basic_json* m_value; SourceIterator m_first; bool m_committed = false; std::size_t m_count = 0; std::size_t m_flushed = 0; std::uint64_t m_word = 0; - std::uint64_t m_inline[inline_words] {}; - std::vector m_more {}; + std::array m_inline {}; + std::vector m_more; }; public: diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index d2eb9eaa1..ef4b94c4f 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -42752,6 +42752,8 @@ public: : m_value(v), m_old_size(old_size) {} array_append_rollback(const array_append_rollback&) = delete; array_append_rollback& operator=(const array_append_rollback&) = delete; + array_append_rollback(array_append_rollback&&) = delete; + array_append_rollback& operator=(array_append_rollback&&) = delete; void commit() noexcept { @@ -42890,6 +42892,8 @@ public: explicit object_clear_on_failure(basic_json* v) noexcept : m_value(v) {} object_clear_on_failure(const object_clear_on_failure&) = delete; object_clear_on_failure& operator=(const object_clear_on_failure&) = delete; + object_clear_on_failure(object_clear_on_failure&&) = delete; + object_clear_on_failure& operator=(object_clear_on_failure&&) = delete; void commit() noexcept { @@ -42920,6 +42924,8 @@ public: object_insert_rollback(basic_json* v, SourceIterator first) : m_value(v), m_first(first) {} object_insert_rollback(const object_insert_rollback&) = delete; object_insert_rollback& operator=(const object_insert_rollback&) = delete; + object_insert_rollback(object_insert_rollback&&) = delete; + object_insert_rollback& operator=(object_insert_rollback&&) = delete; /// call before each run of up to 64 members is inserted; may throw, which leaves the log complete void start_chunk() @@ -42960,7 +42966,7 @@ public: for (std::size_t i = 0; i < m_count; ++i, ++it) { const std::size_t chunk = i / 64; - const std::uint64_t word = chunk >= m_flushed ? m_word : (chunk < inline_words ? m_inline[chunk] : m_more[chunk - inline_words]); + const std::uint64_t word = logged_word(chunk); if (((word >> (i % 64)) & 1U) != 0) { object.erase(it->first); @@ -42973,14 +42979,24 @@ public: private: static constexpr std::size_t inline_words = 4; + /// the log word of a chunk: the one being filled, an inline one, or an overflow one + std::uint64_t logged_word(std::size_t chunk) const + { + if (chunk >= m_flushed) + { + return m_word; + } + return chunk < inline_words ? m_inline[chunk] : m_more[chunk - inline_words]; + } + basic_json* m_value; SourceIterator m_first; bool m_committed = false; std::size_t m_count = 0; std::size_t m_flushed = 0; std::uint64_t m_word = 0; - std::uint64_t m_inline[inline_words] {}; - std::vector m_more {}; + std::array m_inline {}; + std::vector m_more; }; public: diff --git a/tests/src/unit-allocator.cpp b/tests/src/unit-allocator.cpp index fb3209f38..5e0997d20 100644 --- a/tests/src/unit-allocator.cpp +++ b/tests/src/unit-allocator.cpp @@ -881,7 +881,7 @@ void check_strong_guarantee(const std::function& make, { CHECK(j.dump() == before); CHECK(children_name_their_parent(j)); - const BasicJsonType copy(j); + const BasicJsonType copy(j); // NOLINT(performance-unnecessary-copy-initialization): the copy is the point, it allocates CHECK(copy.dump() == before); } } @@ -917,7 +917,7 @@ void check_insert_strong_guarantee() j.push_back(std::string(64, 'd')); j.erase(3); } - return j; + return json_t(std::move(j)); }; for (const bool at_end :