mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-06-20 11:46:36 +02:00
update nlohmann::json to v3.11.1
This commit is contained in:
@ -1,7 +1,20 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++
|
||||
// | | |__ | | | | | | version 3.11.1
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm> // all_of
|
||||
#include <cctype> // isdigit
|
||||
#include <cerrno> // errno, ERANGE
|
||||
#include <cstdlib> // strtoull
|
||||
#ifndef JSON_NO_IO
|
||||
#include <iosfwd> // ostream
|
||||
#endif // JSON_NO_IO
|
||||
#include <limits> // max
|
||||
#include <numeric> // accumulate
|
||||
#include <string> // string
|
||||
@ -10,90 +23,78 @@
|
||||
|
||||
#include <nlohmann/detail/exceptions.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
#include <nlohmann/detail/string_concat.hpp>
|
||||
#include <nlohmann/detail/string_escape.hpp>
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
template<typename BasicJsonType>
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/
|
||||
template<typename RefStringType>
|
||||
class json_pointer
|
||||
{
|
||||
// allow basic_json to access private members
|
||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||
friend class basic_json;
|
||||
|
||||
template<typename>
|
||||
friend class json_pointer;
|
||||
|
||||
template<typename T>
|
||||
struct string_t_helper
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||
struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
|
||||
{
|
||||
using type = StringType;
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
@brief create JSON pointer
|
||||
// for backwards compatibility accept BasicJsonType
|
||||
using string_t = typename string_t_helper<RefStringType>::type;
|
||||
|
||||
Create a JSON pointer according to the syntax described in
|
||||
[Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
|
||||
|
||||
@param[in] s string representing the JSON pointer; if omitted, the empty
|
||||
string is assumed which references the whole JSON value
|
||||
|
||||
@throw parse_error.107 if the given JSON pointer @a s is nonempty and does
|
||||
not begin with a slash (`/`); see example below
|
||||
|
||||
@throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
|
||||
not followed by `0` (representing `~`) or `1` (representing `/`); see
|
||||
example below
|
||||
|
||||
@liveexample{The example shows the construction several valid JSON pointers
|
||||
as well as the exceptional behavior.,json_pointer}
|
||||
|
||||
@since version 2.0.0
|
||||
*/
|
||||
explicit json_pointer(const std::string& s = "")
|
||||
/// @brief create JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/
|
||||
explicit json_pointer(const string_t& s = "")
|
||||
: reference_tokens(split(s))
|
||||
{}
|
||||
|
||||
/*!
|
||||
@brief return a string representation of the JSON pointer
|
||||
|
||||
@invariant For each JSON pointer `ptr`, it holds:
|
||||
@code {.cpp}
|
||||
ptr == json_pointer(ptr.to_string());
|
||||
@endcode
|
||||
|
||||
@return a string representation of the JSON pointer
|
||||
|
||||
@liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
|
||||
|
||||
@since version 2.0.0
|
||||
*/
|
||||
std::string to_string() const
|
||||
/// @brief return a string representation of the JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/to_string/
|
||||
string_t to_string() const
|
||||
{
|
||||
return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
|
||||
std::string{},
|
||||
[](const std::string & a, const std::string & b)
|
||||
string_t{},
|
||||
[](const string_t& a, const string_t& b)
|
||||
{
|
||||
return a + "/" + detail::escape(b);
|
||||
return detail::concat(a, '/', detail::escape(b));
|
||||
});
|
||||
}
|
||||
|
||||
/// @copydoc to_string()
|
||||
operator std::string() const
|
||||
/// @brief return a string representation of the JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_string/
|
||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())
|
||||
operator string_t() const
|
||||
{
|
||||
return to_string();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief append another JSON pointer at the end of this JSON pointer
|
||||
#ifndef JSON_NO_IO
|
||||
/// @brief write string representation of the JSON pointer to stream
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/
|
||||
friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
|
||||
{
|
||||
o << ptr.to_string();
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
|
||||
@param[in] ptr JSON pointer to append
|
||||
@return JSON pointer with @a ptr appended
|
||||
|
||||
@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
|
||||
|
||||
@complexity Linear in the length of @a ptr.
|
||||
|
||||
@sa see @ref operator/=(std::string) to append a reference token
|
||||
@sa see @ref operator/=(std::size_t) to append an array index
|
||||
@sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief append another JSON pointer at the end of this JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
||||
json_pointer& operator/=(const json_pointer& ptr)
|
||||
{
|
||||
reference_tokens.insert(reference_tokens.end(),
|
||||
@ -102,123 +103,45 @@ class json_pointer
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief append an unescaped reference token at the end of this JSON pointer
|
||||
|
||||
@param[in] token reference token to append
|
||||
@return JSON pointer with @a token appended without escaping @a token
|
||||
|
||||
@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
|
||||
|
||||
@complexity Amortized constant.
|
||||
|
||||
@sa see @ref operator/=(const json_pointer&) to append a JSON pointer
|
||||
@sa see @ref operator/=(std::size_t) to append an array index
|
||||
@sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
json_pointer& operator/=(std::string token)
|
||||
/// @brief append an unescaped reference token at the end of this JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
||||
json_pointer& operator/=(string_t token)
|
||||
{
|
||||
push_back(std::move(token));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief append an array index at the end of this JSON pointer
|
||||
|
||||
@param[in] array_idx array index to append
|
||||
@return JSON pointer with @a array_idx appended
|
||||
|
||||
@liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
|
||||
|
||||
@complexity Amortized constant.
|
||||
|
||||
@sa see @ref operator/=(const json_pointer&) to append a JSON pointer
|
||||
@sa see @ref operator/=(std::string) to append a reference token
|
||||
@sa see @ref operator/(const json_pointer&, std::string) for a binary operator
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief append an array index at the end of this JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/
|
||||
json_pointer& operator/=(std::size_t array_idx)
|
||||
{
|
||||
return *this /= std::to_string(array_idx);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||
|
||||
@param[in] lhs JSON pointer
|
||||
@param[in] rhs JSON pointer
|
||||
@return a new JSON pointer with @a rhs appended to @a lhs
|
||||
|
||||
@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
|
||||
|
||||
@complexity Linear in the length of @a lhs and @a rhs.
|
||||
|
||||
@sa see @ref operator/=(const json_pointer&) to append a JSON pointer
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||
friend json_pointer operator/(const json_pointer& lhs,
|
||||
const json_pointer& rhs)
|
||||
{
|
||||
return json_pointer(lhs) /= rhs;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||
|
||||
@param[in] ptr JSON pointer
|
||||
@param[in] token reference token
|
||||
@return a new JSON pointer with unescaped @a token appended to @a ptr
|
||||
|
||||
@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
|
||||
|
||||
@complexity Linear in the length of @a ptr.
|
||||
|
||||
@sa see @ref operator/=(std::string) to append a reference token
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
|
||||
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||
friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
|
||||
{
|
||||
return json_pointer(ptr) /= std::move(token);
|
||||
return json_pointer(lhs) /= std::move(token);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||
|
||||
@param[in] ptr JSON pointer
|
||||
@param[in] array_idx array index
|
||||
@return a new JSON pointer with @a array_idx appended to @a ptr
|
||||
|
||||
@liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
|
||||
|
||||
@complexity Linear in the length of @a ptr.
|
||||
|
||||
@sa see @ref operator/=(std::size_t) to append an array index
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
|
||||
/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||
friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
|
||||
{
|
||||
return json_pointer(ptr) /= array_idx;
|
||||
return json_pointer(lhs) /= array_idx;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief returns the parent of this JSON pointer
|
||||
|
||||
@return parent of this JSON pointer; in case this JSON pointer is the root,
|
||||
the root itself is returned
|
||||
|
||||
@complexity Linear in the length of the JSON pointer.
|
||||
|
||||
@liveexample{The example shows the result of `parent_pointer` for different
|
||||
JSON Pointers.,json_pointer__parent_pointer}
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief returns the parent of this JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/
|
||||
json_pointer parent_pointer() const
|
||||
{
|
||||
if (empty())
|
||||
@ -231,90 +154,46 @@ class json_pointer
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief remove last reference token
|
||||
|
||||
@pre not `empty()`
|
||||
|
||||
@liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
|
||||
|
||||
@complexity Constant.
|
||||
|
||||
@throw out_of_range.405 if JSON pointer has no parent
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief remove last reference token
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/pop_back/
|
||||
void pop_back()
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
|
||||
}
|
||||
|
||||
reference_tokens.pop_back();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief return last reference token
|
||||
|
||||
@pre not `empty()`
|
||||
@return last reference token
|
||||
|
||||
@liveexample{The example shows the usage of `back`.,json_pointer__back}
|
||||
|
||||
@complexity Constant.
|
||||
|
||||
@throw out_of_range.405 if JSON pointer has no parent
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
const std::string& back() const
|
||||
/// @brief return last reference token
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/back/
|
||||
const string_t& back() const
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
|
||||
}
|
||||
|
||||
return reference_tokens.back();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief append an unescaped token at the end of the reference pointer
|
||||
|
||||
@param[in] token token to add
|
||||
|
||||
@complexity Amortized constant.
|
||||
|
||||
@liveexample{The example shows the result of `push_back` for different
|
||||
JSON Pointers.,json_pointer__push_back}
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
void push_back(const std::string& token)
|
||||
/// @brief append an unescaped token at the end of the reference pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/push_back/
|
||||
void push_back(const string_t& token)
|
||||
{
|
||||
reference_tokens.push_back(token);
|
||||
}
|
||||
|
||||
/// @copydoc push_back(const std::string&)
|
||||
void push_back(std::string&& token)
|
||||
/// @brief append an unescaped token at the end of the reference pointer
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/push_back/
|
||||
void push_back(string_t&& token)
|
||||
{
|
||||
reference_tokens.push_back(std::move(token));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief return whether pointer points to the root document
|
||||
|
||||
@return true iff the JSON pointer points to the root document
|
||||
|
||||
@complexity Constant.
|
||||
|
||||
@exceptionsafety No-throw guarantee: this function never throws exceptions.
|
||||
|
||||
@liveexample{The example shows the result of `empty` for different JSON
|
||||
Pointers.,json_pointer__empty}
|
||||
|
||||
@since version 3.6.0
|
||||
*/
|
||||
/// @brief return whether pointer points to the root document
|
||||
/// @sa https://json.nlohmann.me/api/json_pointer/empty/
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return reference_tokens.empty();
|
||||
@ -331,44 +210,39 @@ class json_pointer
|
||||
@throw out_of_range.404 if string @a s could not be converted to an integer
|
||||
@throw out_of_range.410 if an array index exceeds size_type
|
||||
*/
|
||||
static typename BasicJsonType::size_type array_index(const std::string& s)
|
||||
template<typename BasicJsonType>
|
||||
static typename BasicJsonType::size_type array_index(const string_t& s)
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
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'", BasicJsonType()));
|
||||
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)
|
||||
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", BasicJsonType()));
|
||||
JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
|
||||
}
|
||||
|
||||
std::size_t processed_chars = 0;
|
||||
unsigned long long res = 0; // NOLINT(runtime/int)
|
||||
JSON_TRY
|
||||
const char* p = s.c_str();
|
||||
char* p_end = nullptr;
|
||||
errno = 0; // strtoull doesn't reset errno
|
||||
unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
|
||||
if (p == p_end // invalid input or empty string
|
||||
|| errno == ERANGE // out of range
|
||||
|| JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
|
||||
{
|
||||
res = std::stoull(s, &processed_chars);
|
||||
}
|
||||
JSON_CATCH(std::out_of_range&)
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
|
||||
}
|
||||
|
||||
// check if the string was completely read
|
||||
if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
|
||||
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
|
||||
}
|
||||
|
||||
// only triggered on special platforms (like 32bit), see also
|
||||
// https://github.com/nlohmann/json/pull/2203
|
||||
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", BasicJsonType())); // 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);
|
||||
@ -379,7 +253,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
|
||||
}
|
||||
|
||||
json_pointer result = *this;
|
||||
@ -396,6 +270,7 @@ class json_pointer
|
||||
@throw parse_error.109 if array index is not a number
|
||||
@throw type_error.313 if value cannot be unflattened
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
BasicJsonType& get_and_create(BasicJsonType& j) const
|
||||
{
|
||||
auto* result = &j;
|
||||
@ -431,7 +306,7 @@ class json_pointer
|
||||
case detail::value_t::array:
|
||||
{
|
||||
// create an entry in the array
|
||||
result = &result->operator[](array_index(reference_token));
|
||||
result = &result->operator[](array_index<BasicJsonType>(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -449,7 +324,7 @@ class json_pointer
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
default:
|
||||
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
|
||||
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,6 +350,7 @@ class json_pointer
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
@throw out_of_range.404 if the JSON pointer can not be resolved
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
BasicJsonType& get_unchecked(BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
@ -515,7 +391,7 @@ class json_pointer
|
||||
else
|
||||
{
|
||||
// convert array index to number; unchecked access
|
||||
ptr = &ptr->operator[](array_index(reference_token));
|
||||
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -529,7 +405,7 @@ class json_pointer
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,6 +418,7 @@ class json_pointer
|
||||
@throw out_of_range.402 if the array index '-' is used
|
||||
@throw out_of_range.404 if the JSON pointer can not be resolved
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
BasicJsonType& get_checked(BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
@ -560,13 +437,13 @@ class json_pointer
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" always fails the range check
|
||||
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));
|
||||
}
|
||||
|
||||
// note: at performs range check
|
||||
ptr = &ptr->at(array_index(reference_token));
|
||||
ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -579,7 +456,7 @@ class json_pointer
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,6 +476,7 @@ class json_pointer
|
||||
@throw out_of_range.402 if the array index '-' is used
|
||||
@throw out_of_range.404 if the JSON pointer can not be resolved
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
@ -617,11 +495,11 @@ class json_pointer
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" 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
|
||||
ptr = &ptr->operator[](array_index(reference_token));
|
||||
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -634,7 +512,7 @@ class json_pointer
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,6 +525,7 @@ class json_pointer
|
||||
@throw out_of_range.402 if the array index '-' is used
|
||||
@throw out_of_range.404 if the JSON pointer can not be resolved
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
const BasicJsonType& get_checked(const BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
@ -665,13 +544,13 @@ class json_pointer
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" always fails the range check
|
||||
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));
|
||||
}
|
||||
|
||||
// note: at performs range check
|
||||
ptr = &ptr->at(array_index(reference_token));
|
||||
ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -684,7 +563,7 @@ class json_pointer
|
||||
case detail::value_t::binary:
|
||||
case detail::value_t::discarded:
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,6 +574,7 @@ class json_pointer
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index was not a number
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
bool contains(const BasicJsonType* ptr) const
|
||||
{
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
@ -742,7 +622,7 @@ class json_pointer
|
||||
}
|
||||
}
|
||||
|
||||
const auto idx = array_index(reference_token);
|
||||
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
// index out of range
|
||||
@ -783,9 +663,9 @@ class json_pointer
|
||||
@throw parse_error.107 if the pointer is not empty or begins with '/'
|
||||
@throw parse_error.108 if character '~' is not followed by '0' or '1'
|
||||
*/
|
||||
static std::vector<std::string> split(const std::string& reference_string)
|
||||
static std::vector<string_t> split(const string_t& reference_string)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<string_t> result;
|
||||
|
||||
// special case: empty reference string -> no reference tokens
|
||||
if (reference_string.empty())
|
||||
@ -796,7 +676,7 @@ class json_pointer
|
||||
// check if nonempty reference string begins with slash
|
||||
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 + "'", BasicJsonType()));
|
||||
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:
|
||||
@ -807,11 +687,11 @@ class json_pointer
|
||||
std::size_t slash = reference_string.find_first_of('/', 1),
|
||||
// set the beginning of the first reference token
|
||||
start = 1;
|
||||
// we can stop if start == 0 (if slash == std::string::npos)
|
||||
// we can stop if start == 0 (if slash == string_t::npos)
|
||||
start != 0;
|
||||
// set the beginning of the next reference token
|
||||
// (will eventually be 0 if slash == std::string::npos)
|
||||
start = (slash == std::string::npos) ? 0 : slash + 1,
|
||||
// (will eventually be 0 if slash == string_t::npos)
|
||||
start = (slash == string_t::npos) ? 0 : slash + 1,
|
||||
// find next slash
|
||||
slash = reference_string.find_first_of('/', start))
|
||||
{
|
||||
@ -821,7 +701,7 @@ class json_pointer
|
||||
|
||||
// check reference tokens are properly escaped
|
||||
for (std::size_t pos = reference_token.find_first_of('~');
|
||||
pos != std::string::npos;
|
||||
pos != string_t::npos;
|
||||
pos = reference_token.find_first_of('~', pos + 1))
|
||||
{
|
||||
JSON_ASSERT(reference_token[pos] == '~');
|
||||
@ -831,7 +711,7 @@ class json_pointer
|
||||
(reference_token[pos + 1] != '0' &&
|
||||
reference_token[pos + 1] != '1')))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
|
||||
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -851,7 +731,8 @@ class json_pointer
|
||||
|
||||
@note Empty objects or arrays are flattened to `null`.
|
||||
*/
|
||||
static void flatten(const std::string& reference_string,
|
||||
template<typename BasicJsonType>
|
||||
static void flatten(const string_t& reference_string,
|
||||
const BasicJsonType& value,
|
||||
BasicJsonType& result)
|
||||
{
|
||||
@ -869,7 +750,7 @@ class json_pointer
|
||||
// iterate array and use index as reference string
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -888,7 +769,7 @@ class json_pointer
|
||||
// iterate object and use keys as reference string
|
||||
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;
|
||||
@ -921,12 +802,13 @@ class json_pointer
|
||||
@throw type_error.315 if object values are not primitive
|
||||
@throw type_error.313 if value cannot be unflattened
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType
|
||||
unflatten(const BasicJsonType& value)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
|
||||
{
|
||||
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
|
||||
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
|
||||
}
|
||||
|
||||
BasicJsonType result;
|
||||
@ -936,7 +818,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
|
||||
{
|
||||
JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
|
||||
JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
|
||||
}
|
||||
|
||||
// assign value to reference pointed to by JSON pointer; Note that if
|
||||
@ -949,6 +831,21 @@ class json_pointer
|
||||
return result;
|
||||
}
|
||||
|
||||
// can't use conversion operator because of ambiguity
|
||||
json_pointer<string_t> convert() const&
|
||||
{
|
||||
json_pointer<string_t> result;
|
||||
result.reference_tokens = reference_tokens;
|
||||
return result;
|
||||
}
|
||||
|
||||
json_pointer<string_t> convert()&&
|
||||
{
|
||||
json_pointer<string_t> result;
|
||||
result.reference_tokens = std::move(reference_tokens);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief compares two JSON pointers for equality
|
||||
|
||||
@ -960,11 +857,10 @@ class json_pointer
|
||||
|
||||
@exceptionsafety No-throw guarantee: this function never throws exceptions.
|
||||
*/
|
||||
friend bool operator==(json_pointer const& lhs,
|
||||
json_pointer const& rhs) noexcept
|
||||
{
|
||||
return lhs.reference_tokens == rhs.reference_tokens;
|
||||
}
|
||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||
friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
|
||||
json_pointer<RefStringTypeRhs> const& rhs) noexcept;
|
||||
|
||||
/*!
|
||||
@brief compares two JSON pointers for inequality
|
||||
@ -977,13 +873,28 @@ class json_pointer
|
||||
|
||||
@exceptionsafety No-throw guarantee: this function never throws exceptions.
|
||||
*/
|
||||
friend bool operator!=(json_pointer const& lhs,
|
||||
json_pointer const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||
// NOLINTNEXTLINE(readability-redundant-declaration)
|
||||
friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
|
||||
json_pointer<RefStringTypeRhs> const& rhs) noexcept;
|
||||
|
||||
/// the reference tokens
|
||||
std::vector<std::string> reference_tokens;
|
||||
std::vector<string_t> reference_tokens;
|
||||
};
|
||||
} // namespace nlohmann
|
||||
|
||||
// functions cannot be defined inside class due to ODR violations
|
||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||
inline bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
|
||||
json_pointer<RefStringTypeRhs> const& rhs) noexcept
|
||||
{
|
||||
return lhs.reference_tokens == rhs.reference_tokens;
|
||||
}
|
||||
|
||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||
inline bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
|
||||
json_pointer<RefStringTypeRhs> const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
Reference in New Issue
Block a user