Fixed basic_json::diff and basic_json::patch not compiling with custom string type (#4134)
This commit is contained in:
parent
7a95c5931f
commit
356489659c
@ -4702,7 +4702,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// the valid JSON Patch operations
|
||||
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
|
||||
|
||||
const auto get_op = [](const std::string & op)
|
||||
const auto get_op = [](const StringType & op)
|
||||
{
|
||||
if (op == "add")
|
||||
{
|
||||
@ -4839,8 +4839,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
for (const auto& val : json_patch)
|
||||
{
|
||||
// wrapper to get a value for an operation
|
||||
const auto get_value = [&val](const std::string & op,
|
||||
const std::string & member,
|
||||
const auto get_value = [&val](const StringType & op,
|
||||
const StringType & member,
|
||||
bool string_type) -> basic_json &
|
||||
{
|
||||
// find value
|
||||
@ -4874,8 +4874,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
// collect mandatory members
|
||||
const auto op = get_value("op", "op", true).template get<std::string>();
|
||||
const auto path = get_value(op, "path", true).template get<std::string>();
|
||||
const auto op = get_value("op", "op", true).template get<StringType>();
|
||||
const auto path = get_value(op, "path", true).template get<StringType>();
|
||||
json_pointer ptr(path);
|
||||
|
||||
switch (get_op(op))
|
||||
@ -4901,7 +4901,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case patch_operations::move:
|
||||
{
|
||||
const auto from_path = get_value("move", "from", true).template get<std::string>();
|
||||
const auto from_path = get_value("move", "from", true).template get<StringType>();
|
||||
json_pointer from_ptr(from_path);
|
||||
|
||||
// the "from" location must exist - use at()
|
||||
@ -4918,7 +4918,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case patch_operations::copy:
|
||||
{
|
||||
const auto from_path = get_value("copy", "from", true).template get<std::string>();
|
||||
const auto from_path = get_value("copy", "from", true).template get<StringType>();
|
||||
const json_pointer from_ptr(from_path);
|
||||
|
||||
// the "from" location must exist - use at()
|
||||
@ -4978,7 +4978,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/diff/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static basic_json diff(const basic_json& source, const basic_json& target,
|
||||
const std::string& path = "")
|
||||
const StringType& path = "")
|
||||
{
|
||||
// the patch
|
||||
basic_json result(value_t::array);
|
||||
@ -5007,8 +5007,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::size_t i = 0;
|
||||
while (i < source.size() && i < target.size())
|
||||
{
|
||||
StringType array_index_str;
|
||||
{
|
||||
using namespace detail;
|
||||
int_to_string(array_index_str, i);
|
||||
}
|
||||
|
||||
// recursive call to compare array values at index i
|
||||
auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
|
||||
auto temp_diff = diff(source[i], target[i], detail::concat<StringType>(path, '/', array_index_str));
|
||||
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
|
||||
++i;
|
||||
}
|
||||
@ -5022,10 +5028,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
// add operations in reverse order to avoid invalid
|
||||
// indices
|
||||
|
||||
StringType array_index_str;
|
||||
{
|
||||
using namespace detail;
|
||||
int_to_string(array_index_str, i);
|
||||
}
|
||||
|
||||
result.insert(result.begin() + end_index, object(
|
||||
{
|
||||
{"op", "remove"},
|
||||
{"path", detail::concat(path, '/', std::to_string(i))}
|
||||
{"path", detail::concat<StringType>(path, '/', array_index_str)}
|
||||
}));
|
||||
++i;
|
||||
}
|
||||
@ -5036,7 +5049,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
result.push_back(
|
||||
{
|
||||
{"op", "add"},
|
||||
{"path", detail::concat(path, "/-")},
|
||||
{"path", detail::concat<StringType>(path, "/-")},
|
||||
{"value", target[i]}
|
||||
});
|
||||
++i;
|
||||
@ -5051,7 +5064,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
for (auto it = source.cbegin(); it != source.cend(); ++it)
|
||||
{
|
||||
// escape the key name to be used in a JSON patch
|
||||
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
|
||||
const auto path_key = detail::concat<StringType>(path, '/', detail::escape(it.key()));
|
||||
|
||||
if (target.find(it.key()) != target.end())
|
||||
{
|
||||
@ -5075,7 +5088,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (source.find(it.key()) == source.end())
|
||||
{
|
||||
// found a key that is not in this -> add it
|
||||
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
|
||||
const auto path_key = detail::concat<StringType>(path, '/', detail::escape(it.key()));
|
||||
result.push_back(
|
||||
{
|
||||
{"op", "add"}, {"path", path_key},
|
||||
|
||||
@ -23877,7 +23877,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// the valid JSON Patch operations
|
||||
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
|
||||
|
||||
const auto get_op = [](const std::string & op)
|
||||
const auto get_op = [](const StringType & op)
|
||||
{
|
||||
if (op == "add")
|
||||
{
|
||||
@ -24014,8 +24014,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
for (const auto& val : json_patch)
|
||||
{
|
||||
// wrapper to get a value for an operation
|
||||
const auto get_value = [&val](const std::string & op,
|
||||
const std::string & member,
|
||||
const auto get_value = [&val](const StringType & op,
|
||||
const StringType & member,
|
||||
bool string_type) -> basic_json &
|
||||
{
|
||||
// find value
|
||||
@ -24049,8 +24049,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
// collect mandatory members
|
||||
const auto op = get_value("op", "op", true).template get<std::string>();
|
||||
const auto path = get_value(op, "path", true).template get<std::string>();
|
||||
const auto op = get_value("op", "op", true).template get<StringType>();
|
||||
const auto path = get_value(op, "path", true).template get<StringType>();
|
||||
json_pointer ptr(path);
|
||||
|
||||
switch (get_op(op))
|
||||
@ -24076,7 +24076,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case patch_operations::move:
|
||||
{
|
||||
const auto from_path = get_value("move", "from", true).template get<std::string>();
|
||||
const auto from_path = get_value("move", "from", true).template get<StringType>();
|
||||
json_pointer from_ptr(from_path);
|
||||
|
||||
// the "from" location must exist - use at()
|
||||
@ -24093,7 +24093,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case patch_operations::copy:
|
||||
{
|
||||
const auto from_path = get_value("copy", "from", true).template get<std::string>();
|
||||
const auto from_path = get_value("copy", "from", true).template get<StringType>();
|
||||
const json_pointer from_ptr(from_path);
|
||||
|
||||
// the "from" location must exist - use at()
|
||||
@ -24153,7 +24153,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/diff/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static basic_json diff(const basic_json& source, const basic_json& target,
|
||||
const std::string& path = "")
|
||||
const StringType& path = "")
|
||||
{
|
||||
// the patch
|
||||
basic_json result(value_t::array);
|
||||
@ -24182,8 +24182,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::size_t i = 0;
|
||||
while (i < source.size() && i < target.size())
|
||||
{
|
||||
StringType array_index_str;
|
||||
{
|
||||
using namespace detail;
|
||||
int_to_string(array_index_str, i);
|
||||
}
|
||||
|
||||
// recursive call to compare array values at index i
|
||||
auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
|
||||
auto temp_diff = diff(source[i], target[i], detail::concat<StringType>(path, '/', array_index_str));
|
||||
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
|
||||
++i;
|
||||
}
|
||||
@ -24197,10 +24203,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
// add operations in reverse order to avoid invalid
|
||||
// indices
|
||||
|
||||
StringType array_index_str;
|
||||
{
|
||||
using namespace detail;
|
||||
int_to_string(array_index_str, i);
|
||||
}
|
||||
|
||||
result.insert(result.begin() + end_index, object(
|
||||
{
|
||||
{"op", "remove"},
|
||||
{"path", detail::concat(path, '/', std::to_string(i))}
|
||||
{"path", detail::concat<StringType>(path, '/', array_index_str)}
|
||||
}));
|
||||
++i;
|
||||
}
|
||||
@ -24211,7 +24224,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
result.push_back(
|
||||
{
|
||||
{"op", "add"},
|
||||
{"path", detail::concat(path, "/-")},
|
||||
{"path", detail::concat<StringType>(path, "/-")},
|
||||
{"value", target[i]}
|
||||
});
|
||||
++i;
|
||||
@ -24226,7 +24239,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
for (auto it = source.cbegin(); it != source.cend(); ++it)
|
||||
{
|
||||
// escape the key name to be used in a JSON patch
|
||||
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
|
||||
const auto path_key = detail::concat<StringType>(path, '/', detail::escape(it.key()));
|
||||
|
||||
if (target.find(it.key()) != target.end())
|
||||
{
|
||||
@ -24250,7 +24263,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (source.find(it.key()) == source.end())
|
||||
{
|
||||
// found a key that is not in this -> add it
|
||||
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
|
||||
const auto path_key = detail::concat<StringType>(path, '/', detail::escape(it.key()));
|
||||
result.push_back(
|
||||
{
|
||||
{"op", "add"}, {"path", path_key},
|
||||
|
||||
@ -35,10 +35,33 @@ class alt_string
|
||||
alt_string(size_t count, char chr): str_impl(count, chr) {}
|
||||
alt_string() = default;
|
||||
|
||||
template <typename...TParams>
|
||||
alt_string& append(TParams&& ...params)
|
||||
alt_string& append(std::size_t count, char ch)
|
||||
{
|
||||
str_impl.append(std::forward<TParams>(params)...);
|
||||
str_impl.append(count, ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
alt_string& append(const alt_string& str)
|
||||
{
|
||||
str_impl.append(str.str_impl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
alt_string& append(const char* s, std::size_t count)
|
||||
{
|
||||
str_impl.append(s, count);
|
||||
return *this;
|
||||
}
|
||||
|
||||
alt_string& append(const char* s)
|
||||
{
|
||||
str_impl.append(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
alt_string& operator+=(char ch)
|
||||
{
|
||||
str_impl += ch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -74,6 +97,11 @@ class alt_string
|
||||
return str_impl.size();
|
||||
}
|
||||
|
||||
void reserve (std::size_t n)
|
||||
{
|
||||
str_impl.reserve(n);
|
||||
}
|
||||
|
||||
void resize (std::size_t n)
|
||||
{
|
||||
str_impl.resize(n);
|
||||
@ -319,4 +347,14 @@ TEST_CASE("alternative string type")
|
||||
CHECK(j.at(alt_json::json_pointer("/foo/0")) == j["foo"][0]);
|
||||
CHECK(j.at(alt_json::json_pointer("/foo/1")) == j["foo"][1]);
|
||||
}
|
||||
|
||||
SECTION("JSON patch")
|
||||
{
|
||||
// for now, just ensures successful compilation (see #4134)
|
||||
alt_json base, target;
|
||||
alt_json patch = alt_json::array();
|
||||
|
||||
base.patch(patch);
|
||||
CHECK_NOTHROW(alt_json::diff(target, base));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user