From 8d8f8907715798dcca106509e4d9056a2b9f784e Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 10 Apr 2018 08:29:07 +0200 Subject: [PATCH] :hankey: first try on #1045 --- .../detail/iterators/iteration_proxy.hpp | 17 +++++++++++++++ single_include/nlohmann/json.hpp | 17 +++++++++++++++ test/src/unit-regression.cpp | 21 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index 7547d038..b035a812 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -2,6 +2,7 @@ #include // size_t #include // string, to_string +#include // input_iterator_tag #include @@ -16,6 +17,13 @@ template class iteration_proxy /// helper class for iteration class iteration_proxy_internal { + public: + using difference_type = std::ptrdiff_t; + using value_type = iteration_proxy_internal; + using pointer = iteration_proxy_internal*; + using reference = iteration_proxy_internal&; + using iterator_category = std::input_iterator_tag; + private: /// the iterator IteratorType anchor; @@ -25,6 +33,9 @@ template class iteration_proxy public: explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} + iteration_proxy_internal(const iteration_proxy_internal&) = default; + iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default; + /// dereference operator (needed for range-based for) iteration_proxy_internal& operator*() { @@ -40,6 +51,12 @@ template class iteration_proxy return *this; } + /// equality operator (needed for InputIterator) + bool operator==(const iteration_proxy_internal& o) const noexcept + { + return anchor == o.anchor; + } + /// inequality operator (needed for range-based for) bool operator!=(const iteration_proxy_internal& o) const noexcept { diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index b7558aa5..ce534f34 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4491,6 +4491,7 @@ class iter_impl #include // size_t #include // string, to_string +#include // input_iterator_tag // #include @@ -4506,6 +4507,13 @@ template class iteration_proxy /// helper class for iteration class iteration_proxy_internal { + public: + using difference_type = std::ptrdiff_t; + using value_type = iteration_proxy_internal; + using pointer = iteration_proxy_internal*; + using reference = iteration_proxy_internal&; + using iterator_category = std::input_iterator_tag; + private: /// the iterator IteratorType anchor; @@ -4515,6 +4523,9 @@ template class iteration_proxy public: explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} + iteration_proxy_internal(const iteration_proxy_internal&) = default; + iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default; + /// dereference operator (needed for range-based for) iteration_proxy_internal& operator*() { @@ -4530,6 +4541,12 @@ template class iteration_proxy return *this; } + /// equality operator (needed for InputIterator) + bool operator==(const iteration_proxy_internal& o) const noexcept + { + return anchor == o.anchor; + } + /// inequality operator (needed for range-based for) bool operator!=(const iteration_proxy_internal& o) const noexcept { diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 01e68957..d26e0e57 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1615,4 +1615,25 @@ TEST_CASE("regression tests") float_json j2 = {1000.0, 2000.0, 3000.0}; CHECK(float_json::from_ubjson(float_json::to_ubjson(j2, true, true)) == j2); } + + SECTION("issue #1045 - Using STL algorithms with JSON containers with expected results?") + { + json diffs = nlohmann::json::array(); + json m1{{"key1", 42}}; + json m2{{"key2", 42}}; + auto p1 = m1.items(); + auto p2 = m2.items(); + + using it_type = decltype(p1.begin()); + + std::set_difference( + p1.begin(), p1.end(), + p2.begin(), p2.end(), + std::inserter(diffs, diffs.end()), [&](const it_type & e1, const it_type & e2) -> bool + { + return (e1.key() < e2.key()) and (e1.value() < e2.value()); + }); + + CHECK(diffs.size() == 2); + } }