Replace string concatenations using + with concat()

This commit is contained in:
Florian Albrechtskirchinger 2022-04-03 18:34:22 +02:00
parent 10e451b58d
commit ddd60f2092
10 changed files with 507 additions and 435 deletions

View File

@ -17,6 +17,7 @@
#include <nlohmann/detail/meta/cpp_future.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp> #include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp> #include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
@ -42,7 +43,7 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_null())) if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
{ {
JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
} }
n = nullptr; n = nullptr;
} }
@ -80,7 +81,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
case value_t::binary: case value_t::binary:
case value_t::discarded: case value_t::discarded:
default: default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
} }
} }
@ -89,7 +90,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
{ {
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
} }
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
} }
@ -99,7 +100,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_string())) if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
{ {
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
} }
s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
} }
@ -115,7 +116,7 @@ void from_json(const BasicJsonType& j, ConstructibleStringType& s)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_string())) if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
{ {
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
} }
s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
@ -155,7 +156,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
l.clear(); l.clear();
std::transform(j.rbegin(), j.rend(), std::transform(j.rbegin(), j.rend(),
@ -172,7 +173,7 @@ void from_json(const BasicJsonType& j, std::valarray<T>& l)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
l.resize(j.size()); l.resize(j.size());
std::transform(j.begin(), j.end(), std::begin(l), std::transform(j.begin(), j.end(), std::begin(l),
@ -269,7 +270,7 @@ void())
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
from_json_array_impl(j, arr, priority_tag<3> {}); from_json_array_impl(j, arr, priority_tag<3> {});
@ -288,7 +289,7 @@ auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}); return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
@ -299,7 +300,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
{ {
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
} }
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>(); bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
@ -311,7 +312,7 @@ void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_object())) if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
{ {
JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
} }
ConstructibleObjectType ret; ConstructibleObjectType ret;
@ -371,7 +372,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
case value_t::binary: case value_t::binary:
case value_t::discarded: case value_t::discarded:
default: default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
} }
} }
@ -412,7 +413,7 @@ auto from_json(BasicJsonType&& j, TupleRelated&& t)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}); return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
@ -425,14 +426,14 @@ void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>&
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
m.clear(); m.clear();
for (const auto& p : j) for (const auto& p : j)
{ {
if (JSON_HEDLEY_UNLIKELY(!p.is_array())) if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
} }
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
} }
@ -445,14 +446,14 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array())) if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
} }
m.clear(); m.clear();
for (const auto& p : j) for (const auto& p : j)
{ {
if (JSON_HEDLEY_UNLIKELY(!p.is_array())) if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
} }
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
} }
@ -464,7 +465,7 @@ void from_json(const BasicJsonType& j, std_fs::path& p)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_string())) if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
{ {
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
} }
p = *j.template get_ptr<const typename BasicJsonType::string_t*>(); p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
} }

View File

@ -12,6 +12,8 @@
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp> #include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann namespace nlohmann
{ {
@ -41,7 +43,7 @@ class exception : public std::exception
static std::string name(const std::string& ename, int id_) static std::string name(const std::string& ename, int id_)
{ {
return "[json.exception." + ename + "." + std::to_string(id_) + "] "; return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
} }
static std::string diagnostics(std::nullptr_t /*leaf_element*/) static std::string diagnostics(std::nullptr_t /*leaf_element*/)
@ -102,11 +104,12 @@ class exception : public std::exception
return ""; return "";
} }
return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
[](const std::string & a, const std::string & b) [](const std::string & a, const std::string & b)
{ {
return a + "/" + detail::escape(b); return concat(a, '/', detail::escape(b));
}) + ") "; });
return concat('(', str, ") ");
#else #else
static_cast<void>(leaf_element); static_cast<void>(leaf_element);
return ""; return "";
@ -135,17 +138,17 @@ class parse_error : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context) static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("parse_error", id_) + "parse error" + std::string w = concat(exception::name("parse_error", id_), "parse error",
position_string(pos) + ": " + exception::diagnostics(context) + what_arg; position_string(pos), ": ", exception::diagnostics(context), what_arg);
return {id_, pos.chars_read_total, w.c_str()}; return {id_, pos.chars_read_total, w.c_str()};
} }
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context) static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("parse_error", id_) + "parse error" + std::string w = concat(exception::name("parse_error", id_), "parse error",
(byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
": " + exception::diagnostics(context) + what_arg; ": ", exception::diagnostics(context), what_arg);
return {id_, byte_, w.c_str()}; return {id_, byte_, w.c_str()};
} }
@ -166,8 +169,8 @@ class parse_error : public exception
static std::string position_string(const position_t& pos) static std::string position_string(const position_t& pos)
{ {
return " at line " + std::to_string(pos.lines_read + 1) + return concat(" at line ", std::to_string(pos.lines_read + 1),
", column " + std::to_string(pos.chars_read_current_line); ", column ", std::to_string(pos.chars_read_current_line));
} }
}; };
@ -179,7 +182,7 @@ class invalid_iterator : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context) static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
return {id_, w.c_str()}; return {id_, w.c_str()};
} }
@ -197,7 +200,7 @@ class type_error : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static type_error create(int id_, const std::string& what_arg, BasicJsonContext context) static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
return {id_, w.c_str()}; return {id_, w.c_str()};
} }
@ -214,7 +217,7 @@ class out_of_range : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context) static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
return {id_, w.c_str()}; return {id_, w.c_str()};
} }
@ -231,7 +234,7 @@ class other_error : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static other_error create(int id_, const std::string& what_arg, BasicJsonContext context) static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
{ {
std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
return {id_, w.c_str()}; return {id_, w.c_str()};
} }

View File

@ -20,6 +20,7 @@
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/is_sax.hpp> #include <nlohmann/detail/meta/is_sax.hpp>
#include <nlohmann/detail/meta/type_traits.hpp> #include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
namespace nlohmann namespace nlohmann
@ -139,8 +140,8 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof())) if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
{ {
return sax->parse_error(chars_read, get_token_string(), return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), nullptr)); exception_message(format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
} }
} }
@ -216,7 +217,8 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(len < 1)) if (JSON_HEDLEY_UNLIKELY(len < 1))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
} }
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof(); return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
@ -237,7 +239,8 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(len < 0)) if (JSON_HEDLEY_UNLIKELY(len < 0))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
} }
// All BSON binary values have a subtype // All BSON binary values have a subtype
@ -319,7 +322,9 @@ class binary_reader
{ {
std::array<char, 3> cr{{}}; std::array<char, 3> cr{{}};
static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), nullptr)); std::string cr_str{cr.data()};
return sax->parse_error(element_type_parse_position, cr_str,
parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
} }
} }
} }
@ -719,7 +724,8 @@ class binary_reader
case cbor_tag_handler_t::error: case cbor_tag_handler_t::error:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
} }
case cbor_tag_handler_t::ignore: case cbor_tag_handler_t::ignore:
@ -876,7 +882,8 @@ class binary_reader
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
} }
} }
} }
@ -971,7 +978,8 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
} }
} }
} }
@ -1070,7 +1078,8 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
} }
} }
} }
@ -1540,7 +1549,8 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
} }
} }
} }
@ -1622,7 +1632,8 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
} }
} }
} }
@ -1872,7 +1883,8 @@ class binary_reader
default: default:
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::ubjson, concat("expected length type specification (U, i, I, l, L); last byte: 0x", last_token), "string"), nullptr));
} }
} }
@ -1942,7 +1954,8 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::ubjson, concat("expected length type specification (U, i, I, l, L) after '#'; last byte: 0x", last_token), "size"), nullptr));
} }
} }
} }
@ -1980,7 +1993,8 @@ class binary_reader
return false; return false;
} }
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::ubjson, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
} }
return get_ubjson_size_value(result.first); return get_ubjson_size_value(result.first);
@ -2070,7 +2084,8 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(current > 127)) if (JSON_HEDLEY_UNLIKELY(current > 127))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
exception_message(input_format_t::ubjson, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
} }
string_t s(1, static_cast<typename string_t::value_type>(current)); string_t s(1, static_cast<typename string_t::value_type>(current));
return sax->string(s); return sax->string(s);
@ -2091,7 +2106,8 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), nullptr)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
exception_message(input_format_t::ubjson, concat("invalid byte: 0x", last_token), "value"), nullptr));
} }
} }
} }
@ -2269,7 +2285,8 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
{ {
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), nullptr)); return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
exception_message(input_format_t::ubjson, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
} }
switch (result_number) switch (result_number)
@ -2295,7 +2312,8 @@ class binary_reader
case token_type::end_of_input: case token_type::end_of_input:
case token_type::literal_or_value: case token_type::literal_or_value:
default: default:
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), nullptr)); return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
exception_message(input_format_t::ubjson, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
} }
} }
@ -2501,7 +2519,7 @@ class binary_reader
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
} }
return error_msg + " " + context + ": " + detail; return concat(error_msg, ' ', context, ": ", detail);
} }
private: private:

View File

@ -7,6 +7,7 @@
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann namespace nlohmann
{ {
@ -224,7 +225,7 @@ class json_sax_dom_parser
if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), ref_stack.back())); JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
} }
return true; return true;
@ -250,7 +251,7 @@ class json_sax_dom_parser
if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), ref_stack.back())); JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
} }
return true; return true;
@ -405,7 +406,7 @@ class json_sax_dom_callback_parser
// check object limit // check object limit
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), ref_stack.back())); JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
} }
return true; return true;
@ -475,7 +476,7 @@ class json_sax_dom_callback_parser
// check array limit // check array limit
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size())) if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), ref_stack.back())); JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
} }
return true; return true;

View File

@ -13,6 +13,7 @@
#include <nlohmann/detail/input/lexer.hpp> #include <nlohmann/detail/input/lexer.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/is_sax.hpp> #include <nlohmann/detail/meta/is_sax.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
namespace nlohmann namespace nlohmann
@ -261,7 +262,7 @@ class parser
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", nullptr)); out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
} }
if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
@ -461,24 +462,24 @@ class parser
if (!context.empty()) if (!context.empty())
{ {
error_msg += "while parsing " + context + " "; error_msg += concat("while parsing ", context, ' ');
} }
error_msg += "- "; error_msg += "- ";
if (last_token == token_type::parse_error) if (last_token == token_type::parse_error)
{ {
error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + error_msg += concat(m_lexer.get_error_message(), "; last read: '",
m_lexer.get_token_string() + "'"; m_lexer.get_token_string(), '\'');
} }
else else
{ {
error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
} }
if (expected != token_type::uninitialized) if (expected != token_type::uninitialized)
{ {
error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); error_msg += concat("; expected ", lexer_t::token_type_name(expected));
} }
return error_msg; return error_msg;

View File

@ -10,6 +10,7 @@
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/string_escape.hpp> #include <nlohmann/detail/string_escape.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
@ -40,7 +41,7 @@ class json_pointer
std::string{}, std::string{},
[](const std::string & a, const std::string & b) [](const std::string & a, const std::string & b)
{ {
return a + "/" + detail::escape(b); return detail::concat(a, '/', detail::escape(b));
}); });
} }
@ -175,13 +176,13 @@ class json_pointer
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
{ {
JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", nullptr)); JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
} }
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
{ {
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", nullptr)); JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
} }
std::size_t processed_chars = 0; std::size_t processed_chars = 0;
@ -192,20 +193,20 @@ class json_pointer
} }
JSON_CATCH(std::out_of_range&) JSON_CATCH(std::out_of_range&)
{ {
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", nullptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
} }
// check if the string was completely read // check if the string was completely read
if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size())) if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
{ {
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", nullptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
} }
// only triggered on special platforms (like 32bit), see also // only triggered on special platforms (like 32bit), see also
// https://github.com/nlohmann/json/pull/2203 // https://github.com/nlohmann/json/pull/2203
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int) if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
{ {
JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", nullptr)); // LCOV_EXCL_LINE JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
} }
return static_cast<size_type>(res); return static_cast<size_type>(res);
@ -366,7 +367,7 @@ class json_pointer
case detail::value_t::binary: case detail::value_t::binary:
case detail::value_t::discarded: case detail::value_t::discarded:
default: default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", ptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
} }
} }
@ -397,9 +398,9 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (" + std::to_string(ptr->m_value.array->size()) + "array index '-' (", std::to_string(ptr->m_value.array->size()),
") is out of range", ptr)); ") is out of range"), ptr));
} }
// note: at performs range check // note: at performs range check
@ -416,7 +417,7 @@ class json_pointer
case detail::value_t::binary: case detail::value_t::binary:
case detail::value_t::discarded: case detail::value_t::discarded:
default: default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", ptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
} }
} }
@ -454,7 +455,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" cannot be used for const access // "-" cannot be used for const access
JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", ptr)); JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
} }
// use unchecked array access // use unchecked array access
@ -471,7 +472,7 @@ class json_pointer
case detail::value_t::binary: case detail::value_t::binary:
case detail::value_t::discarded: case detail::value_t::discarded:
default: default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", ptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
} }
} }
@ -502,9 +503,9 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (" + std::to_string(ptr->m_value.array->size()) + "array index '-' (", std::to_string(ptr->m_value.array->size()),
") is out of range", ptr)); ") is out of range"), ptr));
} }
// note: at performs range check // note: at performs range check
@ -521,7 +522,7 @@ class json_pointer
case detail::value_t::binary: case detail::value_t::binary:
case detail::value_t::discarded: case detail::value_t::discarded:
default: default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", ptr)); JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
} }
} }
@ -633,7 +634,7 @@ class json_pointer
// check if nonempty reference string begins with slash // check if nonempty reference string begins with slash
if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
{ {
JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", nullptr)); JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
} }
// extract the reference tokens: // extract the reference tokens:
@ -706,7 +707,7 @@ class json_pointer
// iterate array and use index as reference string // iterate array and use index as reference string
for (std::size_t i = 0; i < value.m_value.array->size(); ++i) for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
{ {
flatten(reference_string + "/" + std::to_string(i), flatten(detail::concat(reference_string, '/', std::to_string(i)),
value.m_value.array->operator[](i), result); value.m_value.array->operator[](i), result);
} }
} }
@ -725,7 +726,7 @@ class json_pointer
// iterate object and use keys as reference string // iterate object and use keys as reference string
for (const auto& element : *value.m_value.object) for (const auto& element : *value.m_value.object)
{ {
flatten(reference_string + "/" + detail::escape(element.first), element.second, result); flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
} }
} }
break; break;

View File

@ -12,6 +12,7 @@
#include <nlohmann/detail/input/binary_reader.hpp> #include <nlohmann/detail/input/binary_reader.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/output/output_adapters.hpp> #include <nlohmann/detail/output/output_adapters.hpp>
#include <nlohmann/detail/string_concat.hpp>
namespace nlohmann namespace nlohmann
{ {
@ -67,7 +68,7 @@ class binary_writer
case value_t::discarded: case value_t::discarded:
default: default:
{ {
JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), &j)); JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
} }
} }
} }
@ -937,7 +938,7 @@ class binary_writer
const auto it = name.find(static_cast<typename string_t::value_type>(0)); const auto it = name.find(static_cast<typename string_t::value_type>(0));
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos)) if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{ {
JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", &j)); JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
static_cast<void>(j); static_cast<void>(j);
} }
@ -1062,7 +1063,7 @@ class binary_writer
} }
else else
{ {
JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", &j)); JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
} }
} }

View File

@ -19,6 +19,7 @@
#include <nlohmann/detail/meta/cpp_future.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/output/binary_writer.hpp> #include <nlohmann/detail/output/binary_writer.hpp>
#include <nlohmann/detail/output/output_adapters.hpp> #include <nlohmann/detail/output/output_adapters.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
namespace nlohmann namespace nlohmann
@ -500,7 +501,7 @@ class serializer
{ {
case error_handler_t::strict: case error_handler_t::strict:
{ {
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + hex_bytes(byte | 0), nullptr)); JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
} }
case error_handler_t::ignore: case error_handler_t::ignore:
@ -592,7 +593,7 @@ class serializer
{ {
case error_handler_t::strict: case error_handler_t::strict:
{ {
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + hex_bytes(static_cast<std::uint8_t>(s.back() | 0)), nullptr)); JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
} }
case error_handler_t::ignore: case error_handler_t::ignore:

View File

@ -280,9 +280,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
result["name"] = "JSON for Modern C++"; result["name"] = "JSON for Modern C++";
result["url"] = "https://github.com/nlohmann/json"; result["url"] = "https://github.com/nlohmann/json";
result["version"]["string"] = result["version"]["string"] =
std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." + detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." + std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
std::to_string(NLOHMANN_JSON_VERSION_PATCH); std::to_string(NLOHMANN_JSON_VERSION_PATCH));
result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
@ -304,7 +304,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
#elif defined(__clang__) #elif defined(__clang__)
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
#elif defined(__GNUC__) || defined(__GNUG__) #elif defined(__GNUC__) || defined(__GNUG__)
result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
std::to_string(__GNUC__), '.',
std::to_string(__GNUC_MINOR__), '.',
std::to_string(__GNUC_PATCHLEVEL__))
}
};
#elif defined(__HP_cc) || defined(__HP_aCC) #elif defined(__HP_cc) || defined(__HP_aCC)
result["compiler"] = "hp" result["compiler"] = "hp"
#elif defined(__IBMCPP__) #elif defined(__IBMCPP__)
@ -1129,7 +1134,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::null: case value_t::null:
case value_t::discarded: case value_t::discarded:
default: default:
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), first.m_object)); JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
} }
set_parents(); set_parents();
@ -1413,7 +1418,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.boolean; return m_value.boolean;
} }
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), this)); JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
} }
/// get a pointer to the value (object) /// get a pointer to the value (object)
@ -1534,7 +1539,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return *ptr; return *ptr;
} }
JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), &obj)); JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
} }
public: public:
@ -1907,7 +1912,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
{ {
if (!is_binary()) if (!is_binary())
{ {
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), this)); JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
} }
return *get_ptr<binary_t*>(); return *get_ptr<binary_t*>();
@ -1919,7 +1924,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
{ {
if (!is_binary()) if (!is_binary())
{ {
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), this)); JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
} }
return *get_ptr<const binary_t*>(); return *get_ptr<const binary_t*>();
@ -1950,12 +1955,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", this)); JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
} }
} }
else else
{ {
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
} }
} }
@ -1973,12 +1978,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", this)); JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
} }
} }
else else
{ {
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
} }
} }
@ -1996,12 +2001,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", this)); JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
} }
} }
else else
{ {
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
} }
} }
@ -2019,12 +2024,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", this)); JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
} }
} }
else else
{ {
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
} }
} }
@ -2071,7 +2076,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
} }
/// @brief access specified array element /// @brief access specified array element
@ -2084,7 +2089,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
} }
/// @brief access specified object element /// @brief access specified object element
@ -2105,7 +2110,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return set_parent(m_value.object->operator[](key)); return set_parent(m_value.object->operator[](key));
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
} }
/// @brief access specified object element /// @brief access specified object element
@ -2119,7 +2124,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
} }
/// @brief access specified object element /// @brief access specified object element
@ -2142,7 +2147,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return set_parent(m_value.object->operator[](key)); return set_parent(m_value.object->operator[](key));
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
} }
/// @brief access specified object element /// @brief access specified object element
@ -2158,7 +2163,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), this)); JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
} }
/// @brief access specified object element with default value /// @brief access specified object element with default value
@ -2182,7 +2187,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return default_value; return default_value;
} }
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
} }
/// @brief access specified object element with default value /// @brief access specified object element with default value
@ -2213,7 +2218,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
} }
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
} }
/// @brief access specified object element via JSON Pointer with default value /// @brief access specified object element via JSON Pointer with default value
@ -2322,7 +2327,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::null: case value_t::null:
case value_t::discarded: case value_t::discarded:
default: default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
} }
return result; return result;
@ -2396,7 +2401,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::null: case value_t::null:
case value_t::discarded: case value_t::discarded:
default: default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
} }
return result; return result;
@ -2412,7 +2417,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->erase(key); return m_value.object->erase(key);
} }
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
} }
/// @brief remove element from a JSON array given an index /// @brief remove element from a JSON array given an index
@ -2424,14 +2429,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
{ {
if (JSON_HEDLEY_UNLIKELY(idx >= size())) if (JSON_HEDLEY_UNLIKELY(idx >= size()))
{ {
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", this)); JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
} }
m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
} }
else else
{ {
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
} }
} }
@ -2839,7 +2844,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{ {
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
} }
// transform null object into an array // transform null object into an array
@ -2872,7 +2877,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{ {
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
} }
// transform null object into an array // transform null object into an array
@ -2904,7 +2909,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// push_back only works for null objects or objects // push_back only works for null objects or objects
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
{ {
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
} }
// transform null object into an object // transform null object into an object
@ -2960,7 +2965,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// emplace_back only works for null objects or arrays // emplace_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{ {
JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
} }
// transform null object into an array // transform null object into an array
@ -2985,7 +2990,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// emplace only works for null objects or arrays // emplace only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
{ {
JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
} }
// transform null object into an object // transform null object into an object
@ -3046,7 +3051,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return insert_iterator(pos, val); return insert_iterator(pos, val);
} }
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
} }
/// @brief inserts element into array /// @brief inserts element into array
@ -3073,7 +3078,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return insert_iterator(pos, cnt, val); return insert_iterator(pos, cnt, val);
} }
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
} }
/// @brief inserts range of elements into array /// @brief inserts range of elements into array
@ -3083,7 +3088,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// insert only works for arrays // insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array())) if (JSON_HEDLEY_UNLIKELY(!is_array()))
{ {
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
@ -3114,7 +3119,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// insert only works for arrays // insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array())) if (JSON_HEDLEY_UNLIKELY(!is_array()))
{ {
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
@ -3134,7 +3139,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// insert only works for objects // insert only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object())) if (JSON_HEDLEY_UNLIKELY(!is_object()))
{ {
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
} }
// check if range iterators belong to the same JSON object // check if range iterators belong to the same JSON object
@ -3173,7 +3178,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
if (JSON_HEDLEY_UNLIKELY(!is_object())) if (JSON_HEDLEY_UNLIKELY(!is_object()))
{ {
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
} }
// check if range iterators belong to the same JSON object // check if range iterators belong to the same JSON object
@ -3185,7 +3190,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// passed iterators must belong to objects // passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
{ {
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), first.m_object)); JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
} }
for (auto it = first; it != last; ++it) for (auto it = first; it != last; ++it)
@ -3246,7 +3251,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
} }
} }
@ -3261,7 +3266,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
} }
} }
@ -3276,7 +3281,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
} }
} }
@ -3291,7 +3296,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
} }
} }
@ -3306,7 +3311,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), this)); JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
} }
} }
@ -4319,7 +4324,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
if (JSON_HEDLEY_UNLIKELY(idx > parent.size())) if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
{ {
// avoid undefined behavior // avoid undefined behavior
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", &parent)); JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
} }
// default case: insert add offset // default case: insert add offset
@ -4360,7 +4365,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} }
else else
{ {
JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", this)); JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
} }
} }
else if (parent.is_array()) else if (parent.is_array())
@ -4388,20 +4393,20 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
auto it = val.m_value.object->find(member); auto it = val.m_value.object->find(member);
// context-sensitive error message // context-sensitive error message
const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
// check if desired value is present // check if desired value is present
if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
{ {
// NOLINTNEXTLINE(performance-inefficient-string-concatenation) // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", &val)); JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
} }
// check if result is of type string // check if result is of type string
if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string())) if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
{ {
// NOLINTNEXTLINE(performance-inefficient-string-concatenation) // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", &val)); JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
} }
// no error: return value // no error: return value
@ -4489,7 +4494,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// throw an exception if test fails // throw an exception if test fails
if (JSON_HEDLEY_UNLIKELY(!success)) if (JSON_HEDLEY_UNLIKELY(!success))
{ {
JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), &val)); JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
} }
break; break;
@ -4500,7 +4505,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
{ {
// op must be "add", "remove", "replace", "move", "copy", or // op must be "add", "remove", "replace", "move", "copy", or
// "test" // "test"
JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", &val)); JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
} }
} }
} }
@ -4542,7 +4547,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
while (i < source.size() && i < target.size()) while (i < source.size() && i < target.size())
{ {
// recursive call to compare array values at index i // recursive call to compare array values at index i
auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
result.insert(result.end(), temp_diff.begin(), temp_diff.end()); result.insert(result.end(), temp_diff.begin(), temp_diff.end());
++i; ++i;
} }
@ -4559,7 +4564,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
result.insert(result.begin() + end_index, object( result.insert(result.begin() + end_index, object(
{ {
{"op", "remove"}, {"op", "remove"},
{"path", path + "/" + std::to_string(i)} {"path", detail::concat(path, '/', std::to_string(i))}
})); }));
++i; ++i;
} }
@ -4570,7 +4575,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
result.push_back( result.push_back(
{ {
{"op", "add"}, {"op", "add"},
{"path", path + "/-"}, {"path", detail::concat(path, "/-")},
{"value", target[i]} {"value", target[i]}
}); });
++i; ++i;
@ -4585,7 +4590,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
for (auto it = source.cbegin(); it != source.cend(); ++it) for (auto it = source.cbegin(); it != source.cend(); ++it)
{ {
// escape the key name to be used in a JSON patch // escape the key name to be used in a JSON patch
const auto path_key = path + "/" + detail::escape(it.key()); const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
if (target.find(it.key()) != target.end()) if (target.find(it.key()) != target.end())
{ {
@ -4609,7 +4614,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
if (source.find(it.key()) == source.end()) if (source.find(it.key()) == source.end())
{ {
// found a key that is not in this -> add it // found a key that is not in this -> add it
const auto path_key = path + "/" + detail::escape(it.key()); const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
result.push_back( result.push_back(
{ {
{"op", "add"}, {"path", path_key}, {"op", "add"}, {"path", path_key},

File diff suppressed because it is too large Load Diff