diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index e47d9b4e37..19ede3e98c 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -26,8 +26,24 @@ class json_pointer NLOHMANN_BASIC_JSON_TPL_DECLARATION friend class basic_json; + template + friend class json_pointer; + + template + struct string_t_helper + { + using type = T; + }; + + NLOHMANN_BASIC_JSON_TPL_DECLARATION + struct string_t_helper + { + using type = StringType; + }; + public: - using string_t = RefStringType; + // for backwards compatibility accept BasicJsonType + using string_t = typename string_t_helper::type; /// @brief create JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/ @@ -799,6 +815,21 @@ class json_pointer return result; } + // can't use conversion operator because of ambiguity + json_pointer convert() const& + { + json_pointer result; + result.reference_tokens = reference_tokens; + return result; + } + + json_pointer convert()&& + { + json_pointer result; + result.reference_tokens = std::move(reference_tokens); + return result; + } + /*! @brief compares two JSON pointers for equality diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 3c92b9445e..335e04301a 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -51,6 +51,11 @@ struct is_basic_json_context : || std::is_same::value > {}; +template struct is_json_pointer : std::false_type {}; + +template +struct is_json_pointer> : std::true_type {}; + ////////////////////// // json_ref helpers // ////////////////////// diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index dce8f18956..b2e0985836 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -2210,6 +2210,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); } + template::value, int>::type = 0> + JSON_HEDLEY_DEPRECATED(3.10.6) + ValueType value(const ::nlohmann::json_pointer& ptr, const ValueType& default_value) const + { + return value(ptr.convert(), default_value); + } + /// @brief access specified object element via JSON Pointer with default value /// @sa https://json.nlohmann.me/api/basic_json/value/ /// overload for a default value of type const char* @@ -2219,6 +2227,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return value(ptr, string_t(default_value)); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + JSON_HEDLEY_NON_NULL(3) + string_t value(const typename ::nlohmann::json_pointer& ptr, const char* default_value) const + { + return value(ptr.convert(), default_value); + } + /// @brief access the first element /// @sa https://json.nlohmann.me/api/basic_json/front/ reference front() @@ -2481,7 +2497,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief check the existence of an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/contains/ template < typename KeyT, typename std::enable_if < - !std::is_same::type, json_pointer>::value, int >::type = 0 > + !detail::is_json_pointer::type>::value, int >::type = 0 > bool contains(KeyT && key) const { return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); @@ -2494,6 +2510,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.contains(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + bool contains(const typename ::nlohmann::json_pointer ptr) const + { + return ptr.contains(this); + } + /// @} @@ -4182,6 +4205,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_unchecked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + reference operator[](const ::nlohmann::json_pointer& ptr) + { + return ptr.get_unchecked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ const_reference operator[](const json_pointer& ptr) const @@ -4189,6 +4219,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_unchecked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + const_reference operator[](const ::nlohmann::json_pointer& ptr) const + { + return ptr.get_unchecked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/at/ reference at(const json_pointer& ptr) @@ -4196,6 +4233,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_checked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + reference at(const ::nlohmann::json_pointer& ptr) + { + return ptr.get_checked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/at/ const_reference at(const json_pointer& ptr) const @@ -4203,6 +4247,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_checked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + const_reference at(const ::nlohmann::json_pointer& ptr) const + { + return ptr.get_checked(this); + } + /// @brief return flattened JSON value /// @sa https://json.nlohmann.me/api/basic_json/flatten/ basic_json flatten() const diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 0f6499692b..f9a7cd3cac 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3172,6 +3172,11 @@ struct is_basic_json_context : || std::is_same::value > {}; +template struct is_json_pointer : std::false_type {}; + +template +struct is_json_pointer> : std::true_type {}; + ////////////////////// // json_ref helpers // ////////////////////// @@ -12470,8 +12475,24 @@ class json_pointer NLOHMANN_BASIC_JSON_TPL_DECLARATION friend class basic_json; + template + friend class json_pointer; + + template + struct string_t_helper + { + using type = T; + }; + + NLOHMANN_BASIC_JSON_TPL_DECLARATION + struct string_t_helper + { + using type = StringType; + }; + public: - using string_t = RefStringType; + // for backwards compatibility accept BasicJsonType + using string_t = typename string_t_helper::type; /// @brief create JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/ @@ -13243,6 +13264,21 @@ class json_pointer return result; } + // can't use conversion operator because of ambiguity + json_pointer convert() const& + { + json_pointer result; + result.reference_tokens = reference_tokens; + return result; + } + + json_pointer convert()&& + { + json_pointer result; + result.reference_tokens = std::move(reference_tokens); + return result; + } + /*! @brief compares two JSON pointers for equality @@ -19607,6 +19643,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this)); } + template::value, int>::type = 0> + JSON_HEDLEY_DEPRECATED(3.10.6) + ValueType value(const ::nlohmann::json_pointer& ptr, const ValueType& default_value) const + { + return value(ptr.convert(), default_value); + } + /// @brief access specified object element via JSON Pointer with default value /// @sa https://json.nlohmann.me/api/basic_json/value/ /// overload for a default value of type const char* @@ -19616,6 +19660,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return value(ptr, string_t(default_value)); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + JSON_HEDLEY_NON_NULL(3) + string_t value(const typename ::nlohmann::json_pointer& ptr, const char* default_value) const + { + return value(ptr.convert(), default_value); + } + /// @brief access the first element /// @sa https://json.nlohmann.me/api/basic_json/front/ reference front() @@ -19878,7 +19930,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief check the existence of an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/contains/ template < typename KeyT, typename std::enable_if < - !std::is_same::type, json_pointer>::value, int >::type = 0 > + !detail::is_json_pointer::type>::value, int >::type = 0 > bool contains(KeyT && key) const { return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); @@ -19891,6 +19943,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.contains(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + bool contains(const typename ::nlohmann::json_pointer ptr) const + { + return ptr.contains(this); + } + /// @} @@ -21579,6 +21638,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_unchecked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + reference operator[](const ::nlohmann::json_pointer& ptr) + { + return ptr.get_unchecked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ const_reference operator[](const json_pointer& ptr) const @@ -21586,6 +21652,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_unchecked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + const_reference operator[](const ::nlohmann::json_pointer& ptr) const + { + return ptr.get_unchecked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/at/ reference at(const json_pointer& ptr) @@ -21593,6 +21666,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_checked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + reference at(const ::nlohmann::json_pointer& ptr) + { + return ptr.get_checked(this); + } + /// @brief access specified element via JSON Pointer /// @sa https://json.nlohmann.me/api/basic_json/at/ const_reference at(const json_pointer& ptr) const @@ -21600,6 +21680,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return ptr.get_checked(this); } + template + JSON_HEDLEY_DEPRECATED(3.10.6) + const_reference at(const ::nlohmann::json_pointer& ptr) const + { + return ptr.get_checked(this); + } + /// @brief return flattened JSON value /// @sa https://json.nlohmann.me/api/basic_json/flatten/ basic_json flatten() const diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp index 8853c7aa60..cbb0c58a36 100644 --- a/test/src/unit-json_pointer.cpp +++ b/test/src/unit-json_pointer.cpp @@ -660,4 +660,35 @@ TEST_CASE("JSON pointers") CHECK(j[ptr] == j["object"]["/"]); CHECK(ptr.to_string() == "/object/~1"); } + + SECTION("backwards compatibility and mixing") + { + json j = R"( + { + "foo": ["bar", "baz"] + } + )"_json; + + using nlohmann::ordered_json; + using json_ptr_str = nlohmann::json_pointer; + using json_ptr_j = nlohmann::json_pointer; + using json_ptr_oj = nlohmann::json_pointer; + + json_ptr_str ptr{"/foo/0"}; + json_ptr_j ptr_j{"/foo/0"}; + json_ptr_oj ptr_oj{"/foo/0"}; + + CHECK(j.contains(ptr)); + CHECK(j.contains(ptr_j)); + CHECK(j.contains(ptr_oj)); + + CHECK(j.at(ptr) == j.at(ptr_j)); + CHECK(j.at(ptr) == j.at(ptr_oj)); + + CHECK(j[ptr] == j[ptr_j]); + CHECK(j[ptr] == j[ptr_oj]); + + CHECK(j.value(ptr, "x") == j.value(ptr_j, "x")); + CHECK(j.value(ptr, "x") == j.value(ptr_oj, "x")); + } }