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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*!
 | 
			
		||||
    @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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue