Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers, as well as convenience op/= and op= to append a single unescaped token or array index; inspired by std::filesystem::path
This commit is contained in:
parent
a06e7f5d80
commit
c850e9d82d
3 changed files with 120 additions and 48 deletions
|
@ -76,6 +76,52 @@ class json_pointer
|
||||||
return to_string();
|
return to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief append another JSON pointer at the end of this JSON pointer
|
||||||
|
*/
|
||||||
|
json_pointer& operator/=(const json_pointer& ptr)
|
||||||
|
{
|
||||||
|
reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc push_back(std::string&&)
|
||||||
|
json_pointer& operator/=(std::string token)
|
||||||
|
{
|
||||||
|
push_back(std::move(token));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc operator/=(std::string)
|
||||||
|
json_pointer& operator/=(std::size_t array_index)
|
||||||
|
{
|
||||||
|
return *this /= std::to_string(array_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& left_ptr, const json_pointer& right_ptr)
|
||||||
|
{
|
||||||
|
return json_pointer(left_ptr) /= right_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& ptr, std::string token)
|
||||||
|
{
|
||||||
|
return json_pointer(ptr) /= std::move(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& lhs, std::size_t array_index)
|
||||||
|
{
|
||||||
|
return json_pointer(lhs) /= array_index;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] s reference token to be converted into an array index
|
@param[in] s reference token to be converted into an array index
|
||||||
|
|
||||||
|
@ -98,7 +144,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief remove and return last reference pointer
|
@brief remove and return last reference token
|
||||||
@throw out_of_range.405 if JSON pointer has no parent
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
*/
|
*/
|
||||||
std::string pop_back()
|
std::string pop_back()
|
||||||
|
@ -114,31 +160,17 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief append a token at the end of the reference pointer
|
@brief append an unescaped token at the end of the reference pointer
|
||||||
*/
|
*/
|
||||||
void push_back(const std::string& tok)
|
void push_back(const std::string& token)
|
||||||
{
|
{
|
||||||
reference_tokens.push_back(tok);
|
reference_tokens.push_back(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/// @copydoc push_back(const std::string&)
|
||||||
@brief append a key-token at the end of the reference pointer and return a new json-pointer.
|
void push_back(std::string&& token)
|
||||||
*/
|
|
||||||
json_pointer operator+(const std::string& tok) const
|
|
||||||
{
|
{
|
||||||
auto ptr = *this;
|
reference_tokens.push_back(std::move(token));
|
||||||
ptr.push_back(tok);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief append a array-index-token at the end of the reference pointer and return a new json-pointer.
|
|
||||||
*/
|
|
||||||
json_pointer operator+(const size_t& index) const
|
|
||||||
{
|
|
||||||
auto ptr = *this;
|
|
||||||
ptr.push_back(std::to_string(index));
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -11886,6 +11886,52 @@ class json_pointer
|
||||||
return to_string();
|
return to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief append another JSON pointer at the end of this JSON pointer
|
||||||
|
*/
|
||||||
|
json_pointer& operator/=(const json_pointer& ptr)
|
||||||
|
{
|
||||||
|
reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc push_back(std::string&&)
|
||||||
|
json_pointer& operator/=(std::string token)
|
||||||
|
{
|
||||||
|
push_back(std::move(token));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc operator/=(std::string)
|
||||||
|
json_pointer& operator/=(std::size_t array_index)
|
||||||
|
{
|
||||||
|
return *this /= std::to_string(array_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& left_ptr, const json_pointer& right_ptr)
|
||||||
|
{
|
||||||
|
return json_pointer(left_ptr) /= right_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& ptr, std::string token)
|
||||||
|
{
|
||||||
|
return json_pointer(ptr) /= std::move(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||||
|
*/
|
||||||
|
friend json_pointer operator/(const json_pointer& lhs, std::size_t array_index)
|
||||||
|
{
|
||||||
|
return json_pointer(lhs) /= array_index;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] s reference token to be converted into an array index
|
@param[in] s reference token to be converted into an array index
|
||||||
|
|
||||||
|
@ -11908,7 +11954,7 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief remove and return last reference pointer
|
@brief remove and return last reference token
|
||||||
@throw out_of_range.405 if JSON pointer has no parent
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
*/
|
*/
|
||||||
std::string pop_back()
|
std::string pop_back()
|
||||||
|
@ -11924,31 +11970,17 @@ class json_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief append a token at the end of the reference pointer
|
@brief append an unescaped token at the end of the reference pointer
|
||||||
*/
|
*/
|
||||||
void push_back(const std::string& tok)
|
void push_back(const std::string& token)
|
||||||
{
|
{
|
||||||
reference_tokens.push_back(tok);
|
reference_tokens.push_back(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/// @copydoc push_back(const std::string&)
|
||||||
@brief append a key-token at the end of the reference pointer and return a new json-pointer.
|
void push_back(std::string&& token)
|
||||||
*/
|
|
||||||
json_pointer operator+(const std::string& tok) const
|
|
||||||
{
|
{
|
||||||
auto ptr = *this;
|
reference_tokens.push_back(std::move(token));
|
||||||
ptr.push_back(tok);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief append a array-index-token at the end of the reference pointer and return a new json-pointer.
|
|
||||||
*/
|
|
||||||
json_pointer operator+(const size_t& index) const
|
|
||||||
{
|
|
||||||
auto ptr = *this;
|
|
||||||
ptr.push_back(std::to_string(index));
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -499,7 +499,8 @@ TEST_CASE("JSON pointers")
|
||||||
CHECK(j[ptr] == j);
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
// object and children access
|
// object and children access
|
||||||
ptr.push_back("answer");
|
const std::string answer("answer");
|
||||||
|
ptr.push_back(answer);
|
||||||
ptr.push_back("everything");
|
ptr.push_back("everything");
|
||||||
CHECK(j[ptr] == j["answer"]["everything"]);
|
CHECK(j[ptr] == j["answer"]["everything"]);
|
||||||
|
|
||||||
|
@ -546,24 +547,31 @@ TEST_CASE("JSON pointers")
|
||||||
CHECK(j[ptr] == j);
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
// simple field access
|
// simple field access
|
||||||
ptr = ptr + "pi";
|
ptr = ptr / "pi";
|
||||||
CHECK(j[ptr] == j["pi"]);
|
CHECK(j[ptr] == j["pi"]);
|
||||||
|
|
||||||
ptr.pop_back();
|
ptr.pop_back();
|
||||||
CHECK(j[ptr] == j);
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
// object and children access
|
// object and children access
|
||||||
ptr = ptr + "answer";
|
const std::string answer("answer");
|
||||||
ptr = ptr + "everything";
|
ptr /= answer;
|
||||||
|
ptr = ptr / "everything";
|
||||||
CHECK(j[ptr] == j["answer"]["everything"]);
|
CHECK(j[ptr] == j["answer"]["everything"]);
|
||||||
|
|
||||||
ptr.pop_back();
|
ptr.pop_back();
|
||||||
ptr.pop_back();
|
ptr.pop_back();
|
||||||
CHECK(j[ptr] == j);
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
|
CHECK(ptr / ""_json_pointer == ptr);
|
||||||
|
CHECK(j["/answer"_json_pointer / "/everything"_json_pointer] == j["answer"]["everything"]);
|
||||||
|
|
||||||
|
// list children access
|
||||||
|
CHECK(j["/list"_json_pointer / 1] == j["list"][1]);
|
||||||
|
|
||||||
// push key which has to be encoded
|
// push key which has to be encoded
|
||||||
ptr = ptr + "object";
|
ptr /= "object";
|
||||||
ptr = ptr + "/";
|
ptr = ptr / "/";
|
||||||
CHECK(j[ptr] == j["object"]["/"]);
|
CHECK(j[ptr] == j["object"]["/"]);
|
||||||
CHECK(ptr.to_string() == "/object/~1");
|
CHECK(ptr.to_string() == "/object/~1");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue