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:
garethsb-sony 2019-01-31 19:15:36 +00:00 committed by gbsylveg
parent a06e7f5d80
commit c850e9d82d
3 changed files with 120 additions and 48 deletions

View File

@ -76,6 +76,52 @@ class json_pointer
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
@ -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
*/
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);
}
/*!
@brief append a key-token at the end of the reference pointer and return a new json-pointer.
*/
json_pointer operator+(const std::string& tok) const
/// @copydoc push_back(const std::string&)
void push_back(std::string&& token)
{
auto ptr = *this;
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;
reference_tokens.push_back(std::move(token));
}
private:

View File

@ -11886,6 +11886,52 @@ class json_pointer
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
@ -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
*/
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);
}
/*!
@brief append a key-token at the end of the reference pointer and return a new json-pointer.
*/
json_pointer operator+(const std::string& tok) const
/// @copydoc push_back(const std::string&)
void push_back(std::string&& token)
{
auto ptr = *this;
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;
reference_tokens.push_back(std::move(token));
}
private:

View File

@ -499,7 +499,8 @@ TEST_CASE("JSON pointers")
CHECK(j[ptr] == j);
// object and children access
ptr.push_back("answer");
const std::string answer("answer");
ptr.push_back(answer);
ptr.push_back("everything");
CHECK(j[ptr] == j["answer"]["everything"]);
@ -546,24 +547,31 @@ TEST_CASE("JSON pointers")
CHECK(j[ptr] == j);
// simple field access
ptr = ptr + "pi";
ptr = ptr / "pi";
CHECK(j[ptr] == j["pi"]);
ptr.pop_back();
CHECK(j[ptr] == j);
// object and children access
ptr = ptr + "answer";
ptr = ptr + "everything";
const std::string answer("answer");
ptr /= answer;
ptr = ptr / "everything";
CHECK(j[ptr] == j["answer"]["everything"]);
ptr.pop_back();
ptr.pop_back();
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
ptr = ptr + "object";
ptr = ptr + "/";
ptr /= "object";
ptr = ptr / "/";
CHECK(j[ptr] == j["object"]["/"]);
CHECK(ptr.to_string() == "/object/~1");
}