Skip to content

Commit 72af4a6

Browse files
committed
♻️ allow patch and diff to be used with arbitrary string types
1 parent e6cafa5 commit 72af4a6

File tree

5 files changed

+146
-41
lines changed

5 files changed

+146
-41
lines changed

include/nlohmann/detail/iterators/iteration_proxy.hpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#include <cstddef> // size_t
1212
#include <iterator> // forward_iterator_tag
13-
#include <string> // string, to_string
1413
#include <tuple> // tuple_size, get, tuple_element
1514
#include <utility> // move
1615

@@ -20,19 +19,13 @@
2019

2120
#include <nlohmann/detail/abi_macros.hpp>
2221
#include <nlohmann/detail/meta/type_traits.hpp>
22+
#include <nlohmann/detail/string_utils.hpp>
2323
#include <nlohmann/detail/value_t.hpp>
2424

2525
NLOHMANN_JSON_NAMESPACE_BEGIN
2626
namespace detail
2727
{
2828

29-
template<typename string_type>
30-
void int_to_string( string_type& target, std::size_t value )
31-
{
32-
// For ADL
33-
using std::to_string;
34-
target = to_string(value);
35-
}
3629
template<typename IteratorType> class iteration_proxy_value
3730
{
3831
public:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// __ _____ _____ _____
2+
// __| | __| | | | JSON for Modern C++
3+
// | | |__ | | | | | | version 3.11.3
4+
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5+
//
6+
// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann <https://nlohmann.me>
7+
// SPDX-License-Identifier: MIT
8+
9+
#pragma once
10+
11+
#include <cstddef> // size_t
12+
#include <string> // string, to_string
13+
14+
#include <nlohmann/detail/abi_macros.hpp>
15+
16+
NLOHMANN_JSON_NAMESPACE_BEGIN
17+
namespace detail
18+
{
19+
20+
template<typename StringType>
21+
void int_to_string(StringType& target, std::size_t value)
22+
{
23+
// For ADL
24+
using std::to_string;
25+
target = to_string(value);
26+
}
27+
28+
template<typename StringType>
29+
StringType to_string(std::size_t value)
30+
{
31+
StringType result;
32+
int_to_string(result, value);
33+
return result;
34+
}
35+
36+
} // namespace detail
37+
NLOHMANN_JSON_NAMESPACE_END

include/nlohmann/json.hpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <nlohmann/detail/macro_scope.hpp>
5353
#include <nlohmann/detail/string_concat.hpp>
5454
#include <nlohmann/detail/string_escape.hpp>
55+
#include <nlohmann/detail/string_utils.hpp>
5556
#include <nlohmann/detail/meta/cpp_future.hpp>
5657
#include <nlohmann/detail/meta/type_traits.hpp>
5758
#include <nlohmann/detail/output/binary_writer.hpp>
@@ -4702,7 +4703,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
47024703
// the valid JSON Patch operations
47034704
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
47044705

4705-
const auto get_op = [](const std::string & op)
4706+
const auto get_op = [](const string_t& op)
47064707
{
47074708
if (op == "add")
47084709
{
@@ -4839,8 +4840,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
48394840
for (const auto& val : json_patch)
48404841
{
48414842
// wrapper to get a value for an operation
4842-
const auto get_value = [&val](const std::string & op,
4843-
const std::string & member,
4843+
const auto get_value = [&val](const string_t& op,
4844+
const string_t& member,
48444845
bool string_type) -> basic_json &
48454846
{
48464847
// find value
@@ -4874,8 +4875,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
48744875
}
48754876

48764877
// collect mandatory members
4877-
const auto op = get_value("op", "op", true).template get<std::string>();
4878-
const auto path = get_value(op, "path", true).template get<std::string>();
4878+
const auto op = get_value("op", "op", true).template get<string_t>();
4879+
const auto path = get_value(op, "path", true).template get<string_t>();
48794880
json_pointer ptr(path);
48804881

48814882
switch (get_op(op))
@@ -4901,7 +4902,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
49014902

49024903
case patch_operations::move:
49034904
{
4904-
const auto from_path = get_value("move", "from", true).template get<std::string>();
4905+
const auto from_path = get_value("move", "from", true).template get<string_t>();
49054906
json_pointer from_ptr(from_path);
49064907

49074908
// the "from" location must exist - use at()
@@ -4918,7 +4919,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
49184919

49194920
case patch_operations::copy:
49204921
{
4921-
const auto from_path = get_value("copy", "from", true).template get<std::string>();
4922+
const auto from_path = get_value("copy", "from", true).template get<string_t>();
49224923
const json_pointer from_ptr(from_path);
49234924

49244925
// the "from" location must exist - use at()
@@ -4978,7 +4979,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
49784979
/// @sa https://json.nlohmann.me/api/basic_json/diff/
49794980
JSON_HEDLEY_WARN_UNUSED_RESULT
49804981
static basic_json diff(const basic_json& source, const basic_json& target,
4981-
const std::string& path = "")
4982+
const string_t& path = "")
49824983
{
49834984
// the patch
49844985
basic_json result(value_t::array);
@@ -5008,7 +5009,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
50085009
while (i < source.size() && i < target.size())
50095010
{
50105011
// recursive call to compare array values at index i
5011-
auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
5012+
auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i)));
50125013
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
50135014
++i;
50145015
}
@@ -5025,7 +5026,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
50255026
result.insert(result.begin() + end_index, object(
50265027
{
50275028
{"op", "remove"},
5028-
{"path", detail::concat(path, '/', std::to_string(i))}
5029+
{"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))}
50295030
}));
50305031
++i;
50315032
}
@@ -5036,7 +5037,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
50365037
result.push_back(
50375038
{
50385039
{"op", "add"},
5039-
{"path", detail::concat(path, "/-")},
5040+
{"path", detail::concat<string_t>(path, "/-")},
50405041
{"value", target[i]}
50415042
});
50425043
++i;
@@ -5051,7 +5052,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
50515052
for (auto it = source.cbegin(); it != source.cend(); ++it)
50525053
{
50535054
// escape the key name to be used in a JSON patch
5054-
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
5055+
const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
50555056

50565057
if (target.find(it.key()) != target.end())
50575058
{
@@ -5075,7 +5076,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
50755076
if (source.find(it.key()) == source.end())
50765077
{
50775078
// found a key that is not in this -> add it
5078-
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
5079+
const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
50795080
result.push_back(
50805081
{
50815082
{"op", "add"}, {"path", path_key},

single_include/nlohmann/json.hpp

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5275,7 +5275,6 @@ NLOHMANN_JSON_NAMESPACE_END
52755275

52765276
#include <cstddef> // size_t
52775277
#include <iterator> // forward_iterator_tag
5278-
#include <string> // string, to_string
52795278
#include <tuple> // tuple_size, get, tuple_element
52805279
#include <utility> // move
52815280

@@ -5287,20 +5286,53 @@ NLOHMANN_JSON_NAMESPACE_END
52875286

52885287
// #include <nlohmann/detail/meta/type_traits.hpp>
52895288

5290-
// #include <nlohmann/detail/value_t.hpp>
5289+
// #include <nlohmann/detail/string_utils.hpp>
5290+
// __ _____ _____ _____
5291+
// __| | __| | | | JSON for Modern C++
5292+
// | | |__ | | | | | | version 3.11.3
5293+
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5294+
//
5295+
// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann <https://nlohmann.me>
5296+
// SPDX-License-Identifier: MIT
5297+
5298+
5299+
5300+
#include <cstddef> // size_t
5301+
#include <string> // string, to_string
5302+
5303+
// #include <nlohmann/detail/abi_macros.hpp>
52915304

52925305

52935306
NLOHMANN_JSON_NAMESPACE_BEGIN
52945307
namespace detail
52955308
{
52965309

5297-
template<typename string_type>
5298-
void int_to_string( string_type& target, std::size_t value )
5310+
template<typename StringType>
5311+
void int_to_string(StringType& target, std::size_t value)
52995312
{
53005313
// For ADL
53015314
using std::to_string;
53025315
target = to_string(value);
53035316
}
5317+
5318+
template<typename StringType>
5319+
StringType to_string(std::size_t value)
5320+
{
5321+
StringType result;
5322+
int_to_string(result, value);
5323+
return result;
5324+
}
5325+
5326+
} // namespace detail
5327+
NLOHMANN_JSON_NAMESPACE_END
5328+
5329+
// #include <nlohmann/detail/value_t.hpp>
5330+
5331+
5332+
NLOHMANN_JSON_NAMESPACE_BEGIN
5333+
namespace detail
5334+
{
5335+
53045336
template<typename IteratorType> class iteration_proxy_value
53055337
{
53065338
public:
@@ -15125,6 +15157,8 @@ NLOHMANN_JSON_NAMESPACE_END
1512515157

1512615158
// #include <nlohmann/detail/string_escape.hpp>
1512715159

15160+
// #include <nlohmann/detail/string_utils.hpp>
15161+
1512815162
// #include <nlohmann/detail/meta/cpp_future.hpp>
1512915163

1513015164
// #include <nlohmann/detail/meta/type_traits.hpp>
@@ -24249,7 +24283,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2424924283
// the valid JSON Patch operations
2425024284
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
2425124285

24252-
const auto get_op = [](const std::string & op)
24286+
const auto get_op = [](const string_t& op)
2425324287
{
2425424288
if (op == "add")
2425524289
{
@@ -24386,8 +24420,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2438624420
for (const auto& val : json_patch)
2438724421
{
2438824422
// wrapper to get a value for an operation
24389-
const auto get_value = [&val](const std::string & op,
24390-
const std::string & member,
24423+
const auto get_value = [&val](const string_t& op,
24424+
const string_t& member,
2439124425
bool string_type) -> basic_json &
2439224426
{
2439324427
// find value
@@ -24421,8 +24455,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2442124455
}
2442224456

2442324457
// collect mandatory members
24424-
const auto op = get_value("op", "op", true).template get<std::string>();
24425-
const auto path = get_value(op, "path", true).template get<std::string>();
24458+
const auto op = get_value("op", "op", true).template get<string_t>();
24459+
const auto path = get_value(op, "path", true).template get<string_t>();
2442624460
json_pointer ptr(path);
2442724461

2442824462
switch (get_op(op))
@@ -24448,7 +24482,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2444824482

2444924483
case patch_operations::move:
2445024484
{
24451-
const auto from_path = get_value("move", "from", true).template get<std::string>();
24485+
const auto from_path = get_value("move", "from", true).template get<string_t>();
2445224486
json_pointer from_ptr(from_path);
2445324487

2445424488
// the "from" location must exist - use at()
@@ -24465,7 +24499,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2446524499

2446624500
case patch_operations::copy:
2446724501
{
24468-
const auto from_path = get_value("copy", "from", true).template get<std::string>();
24502+
const auto from_path = get_value("copy", "from", true).template get<string_t>();
2446924503
const json_pointer from_ptr(from_path);
2447024504

2447124505
// the "from" location must exist - use at()
@@ -24525,7 +24559,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2452524559
/// @sa https://json.nlohmann.me/api/basic_json/diff/
2452624560
JSON_HEDLEY_WARN_UNUSED_RESULT
2452724561
static basic_json diff(const basic_json& source, const basic_json& target,
24528-
const std::string& path = "")
24562+
const string_t& path = "")
2452924563
{
2453024564
// the patch
2453124565
basic_json result(value_t::array);
@@ -24555,7 +24589,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2455524589
while (i < source.size() && i < target.size())
2455624590
{
2455724591
// recursive call to compare array values at index i
24558-
auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24592+
auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i)));
2455924593
result.insert(result.end(), temp_diff.begin(), temp_diff.end());
2456024594
++i;
2456124595
}
@@ -24572,7 +24606,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2457224606
result.insert(result.begin() + end_index, object(
2457324607
{
2457424608
{"op", "remove"},
24575-
{"path", detail::concat(path, '/', std::to_string(i))}
24609+
{"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))}
2457624610
}));
2457724611
++i;
2457824612
}
@@ -24583,7 +24617,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2458324617
result.push_back(
2458424618
{
2458524619
{"op", "add"},
24586-
{"path", detail::concat(path, "/-")},
24620+
{"path", detail::concat<string_t>(path, "/-")},
2458724621
{"value", target[i]}
2458824622
});
2458924623
++i;
@@ -24598,7 +24632,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2459824632
for (auto it = source.cbegin(); it != source.cend(); ++it)
2459924633
{
2460024634
// escape the key name to be used in a JSON patch
24601-
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24635+
const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
2460224636

2460324637
if (target.find(it.key()) != target.end())
2460424638
{
@@ -24622,7 +24656,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2462224656
if (source.find(it.key()) == source.end())
2462324657
{
2462424658
// found a key that is not in this -> add it
24625-
const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24659+
const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
2462624660
result.push_back(
2462724661
{
2462824662
{"op", "add"}, {"path", path_key},

0 commit comments

Comments
 (0)