From f5f975a48c4d32e23e6ee732c495a91f166f5532 Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Tue, 5 Apr 2022 14:57:10 +0200 Subject: [PATCH] Allow comparing different json_pointers --- include/nlohmann/detail/json_pointer.hpp | 33 +++++++++++++++++------- single_include/nlohmann/json.hpp | 33 +++++++++++++++++------- test/src/unit-json_pointer.cpp | 14 ++++++++++ 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index a9b208dfd4..f94f3bdf9a 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -836,11 +836,10 @@ class json_pointer @exceptionsafety No-throw guarantee: this function never throws exceptions. */ - friend bool operator==(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return lhs.reference_tokens == rhs.reference_tokens; - } + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(json_pointer const& lhs, + json_pointer const& rhs) noexcept; /*! @brief compares two JSON pointers for inequality @@ -853,13 +852,27 @@ class json_pointer @exceptionsafety No-throw guarantee: this function never throws exceptions. */ - friend bool operator!=(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return !(lhs == rhs); - } + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(json_pointer const& lhs, + json_pointer const& rhs) noexcept; /// the reference tokens std::vector reference_tokens; }; + +// functions cannot be defined inside class due to ODR violations +template +inline bool operator==(json_pointer const& lhs, + json_pointer const& rhs) noexcept +{ + return lhs.reference_tokens == rhs.reference_tokens; +} + +template +inline bool operator!=(json_pointer const& lhs, + json_pointer const& rhs) noexcept +{ + return !(lhs == rhs); +} } // namespace nlohmann diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 56d02b7f07..5df8554a66 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -13301,11 +13301,10 @@ class json_pointer @exceptionsafety No-throw guarantee: this function never throws exceptions. */ - friend bool operator==(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return lhs.reference_tokens == rhs.reference_tokens; - } + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(json_pointer const& lhs, + json_pointer const& rhs) noexcept; /*! @brief compares two JSON pointers for inequality @@ -13318,15 +13317,29 @@ class json_pointer @exceptionsafety No-throw guarantee: this function never throws exceptions. */ - friend bool operator!=(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return !(lhs == rhs); - } + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(json_pointer const& lhs, + json_pointer const& rhs) noexcept; /// the reference tokens std::vector reference_tokens; }; + +// functions cannot be defined inside class due to ODR violations +template +inline bool operator==(json_pointer const& lhs, + json_pointer const& rhs) noexcept +{ + return lhs.reference_tokens == rhs.reference_tokens; +} + +template +inline bool operator!=(json_pointer const& lhs, + json_pointer const& rhs) noexcept +{ + return !(lhs == rhs); +} } // namespace nlohmann // #include diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp index 7b73807923..7ec157db33 100644 --- a/test/src/unit-json_pointer.cpp +++ b/test/src/unit-json_pointer.cpp @@ -661,6 +661,15 @@ TEST_CASE("JSON pointers") CHECK(ptr.to_string() == "/object/~1"); } + SECTION("equality comparison") + { + auto ptr1 = json::json_pointer("/foo/bar"); + auto ptr2 = json::json_pointer("/foo/bar"); + + CHECK(ptr1 == ptr2); + CHECK_FALSE(ptr1 != ptr2); + } + SECTION("backwards compatibility and mixing") { json j = R"( @@ -695,5 +704,10 @@ TEST_CASE("JSON pointers") CHECK(j.value(ptr, "x") == j.value(ptr_j, "x")); CHECK(j.value(ptr, "x") == j.value(ptr_oj, "x")); + + CHECK(ptr == ptr_j); + CHECK(ptr == ptr_oj); + CHECK_FALSE(ptr != ptr_j); + CHECK_FALSE(ptr != ptr_oj); } }