implemented deflatten function
This commit is contained in:
parent
007359675b
commit
f834965b44
3 changed files with 177 additions and 2 deletions
81
src/json.hpp
81
src/json.hpp
|
@ -8855,7 +8855,6 @@ basic_json_parser_63:
|
|||
}
|
||||
|
||||
private:
|
||||
/// return referenced value
|
||||
reference get(reference j) const
|
||||
{
|
||||
pointer result = &j;
|
||||
|
@ -8880,6 +8879,49 @@ basic_json_parser_63:
|
|||
return *result;
|
||||
}
|
||||
|
||||
reference get2(reference j) const
|
||||
{
|
||||
pointer result = &j;
|
||||
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (result->m_type)
|
||||
{
|
||||
case value_t::null:
|
||||
{
|
||||
if (reference_token == "0")
|
||||
{
|
||||
result = &result->operator[](0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = &result->operator[](reference_token);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result = &result->operator[](reference_token);
|
||||
continue;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
|
||||
continue;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::domain_error("unresolved reference token '" + reference_token + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
const_reference get(const_reference j) const
|
||||
{
|
||||
const_pointer result = &j;
|
||||
|
@ -9042,6 +9084,35 @@ basic_json_parser_63:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@param[in] value flattened JSON
|
||||
|
||||
@return deflattened JSON
|
||||
*/
|
||||
static basic_json deflatten(const basic_json& value)
|
||||
{
|
||||
if (not value.is_object())
|
||||
{
|
||||
throw std::domain_error("only objects can be deflattened");
|
||||
}
|
||||
|
||||
basic_json result;
|
||||
|
||||
// iterate the JSON object values
|
||||
for (const auto& element : *value.m_value.object)
|
||||
{
|
||||
if (not element.second.is_primitive())
|
||||
{
|
||||
throw std::domain_error("values in object must be primitive");
|
||||
}
|
||||
|
||||
// assign value to reference pointed to by JSON pointer
|
||||
json_pointer(element.first).get2(result) = element.second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -9053,6 +9124,14 @@ basic_json_parser_63:
|
|||
json_pointer::flatten("", *this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@return the original JSON from a flattened version
|
||||
*/
|
||||
basic_json deflatten() const
|
||||
{
|
||||
return json_pointer::deflatten(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8165,7 +8165,6 @@ class basic_json
|
|||
}
|
||||
|
||||
private:
|
||||
/// return referenced value
|
||||
reference get(reference j) const
|
||||
{
|
||||
pointer result = &j;
|
||||
|
@ -8190,6 +8189,49 @@ class basic_json
|
|||
return *result;
|
||||
}
|
||||
|
||||
reference get2(reference j) const
|
||||
{
|
||||
pointer result = &j;
|
||||
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (result->m_type)
|
||||
{
|
||||
case value_t::null:
|
||||
{
|
||||
if (reference_token == "0")
|
||||
{
|
||||
result = &result->operator[](0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = &result->operator[](reference_token);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result = &result->operator[](reference_token);
|
||||
continue;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
|
||||
continue;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::domain_error("unresolved reference token '" + reference_token + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
const_reference get(const_reference j) const
|
||||
{
|
||||
const_pointer result = &j;
|
||||
|
@ -8352,6 +8394,35 @@ class basic_json
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@param[in] value flattened JSON
|
||||
|
||||
@return deflattened JSON
|
||||
*/
|
||||
static basic_json deflatten(const basic_json& value)
|
||||
{
|
||||
if (not value.is_object())
|
||||
{
|
||||
throw std::domain_error("only objects can be deflattened");
|
||||
}
|
||||
|
||||
basic_json result;
|
||||
|
||||
// iterate the JSON object values
|
||||
for (const auto& element : *value.m_value.object)
|
||||
{
|
||||
if (not element.second.is_primitive())
|
||||
{
|
||||
throw std::domain_error("values in object must be primitive");
|
||||
}
|
||||
|
||||
// assign value to reference pointed to by JSON pointer
|
||||
json_pointer(element.first).get2(result) = element.second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -8363,6 +8434,14 @@ class basic_json
|
|||
json_pointer::flatten("", *this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@return the original JSON from a flattened version
|
||||
*/
|
||||
basic_json deflatten() const
|
||||
{
|
||||
return json_pointer::deflatten(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -12213,7 +12213,24 @@ TEST_CASE("JSON pointers")
|
|||
{"/object/~01", "tilde1"}
|
||||
};
|
||||
|
||||
// check if flattened result is as expected
|
||||
CHECK(j.flatten() == j_flatten);
|
||||
|
||||
// check if deflattened result is as expected
|
||||
CHECK(j_flatten.deflatten() == j);
|
||||
|
||||
// explicit roundtrip check
|
||||
CHECK(j.flatten().deflatten() == j);
|
||||
|
||||
// roundtrip for primitive values
|
||||
json j_null;
|
||||
CHECK(j_null.flatten().deflatten() == j_null);
|
||||
json j_number = 42;
|
||||
CHECK(j_number.flatten().deflatten() == j_number);
|
||||
json j_boolean = false;
|
||||
CHECK(j_boolean.flatten().deflatten() == j_boolean);
|
||||
json j_string = "foo";
|
||||
CHECK(j_string.flatten().deflatten() == j_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue