proposal for #428

This implementation forwards the iterators to std::map::insert.
This commit is contained in:
Niels Lohmann 2017-04-07 18:29:09 +02:00
parent 90273e930c
commit 97a25de938
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
5 changed files with 150 additions and 1 deletions

View file

@ -0,0 +1,20 @@
#include <json.hpp>
using json = nlohmann::json;
int main()
{
// create two JSON objects
json j1 = {{"one", "eins"}, {"two", "zwei"}};
json j2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};
// output objects
std::cout << j1 << '\n';
std::cout << j2 << '\n';
// insert range from j2 to j1
j1.insert(j2.begin(), j2.end());
// output result of insert call
std::cout << j1 << '\n';
}

View file

@ -0,0 +1,3 @@
{"one":"eins","two":"zwei"}
{"eleven":"elf","seventeen":"siebzehn"}
{"eleven":"elf","one":"eins","seventeen":"siebzehn","two":"zwei"}

View file

@ -5978,6 +5978,52 @@ class basic_json
return result; return result;
} }
/*!
@brief inserts elements
Inserts elements from range `[first, last)`.
@param[in] first begin of the range of elements to insert
@param[in] last end of the range of elements to insert
@throw type_error.309 if called on JSON values other than objects; example:
`"cannot use insert() with string"`
@throw invalid_iterator.202 if iterator @a first or @a last does does not
point to an object; example: `"iterators first and last must point to
objects"`
@throw invalid_iterator.210 if @a first and @a last do not belong to the
same JSON value; example: `"iterators do not fit"`
@complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
of elements to insert.
@liveexample{The example shows how `insert()` is used.,insert__range_object}
@since version 3.0.0
*/
void insert(const_iterator first, const_iterator last)
{
// insert only works for objects
if (not is_object())
{
JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
}
// check if range iterators belong to the same JSON object
if (first.m_object != last.m_object)
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
}
// passed iterators must belong to objects
if (not first.m_object->is_object() or not first.m_object->is_object())
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
}
m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
}
/*! /*!
@brief exchanges the values @brief exchanges the values

View file

@ -5978,6 +5978,52 @@ class basic_json
return result; return result;
} }
/*!
@brief inserts elements
Inserts elements from range `[first, last)`.
@param[in] first begin of the range of elements to insert
@param[in] last end of the range of elements to insert
@throw type_error.309 if called on JSON values other than objects; example:
`"cannot use insert() with string"`
@throw invalid_iterator.202 if iterator @a first or @a last does does not
point to an object; example: `"iterators first and last must point to
objects"`
@throw invalid_iterator.210 if @a first and @a last do not belong to the
same JSON value; example: `"iterators do not fit"`
@complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
of elements to insert.
@liveexample{The example shows how `insert()` is used.,insert__range_object}
@since version 3.0.0
*/
void insert(const_iterator first, const_iterator last)
{
// insert only works for objects
if (not is_object())
{
JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
}
// check if range iterators belong to the same JSON object
if (first.m_object != last.m_object)
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
}
// passed iterators must belong to objects
if (not first.m_object->is_object() or not first.m_object->is_object())
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
}
m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
}
/*! /*!
@brief exchanges the values @brief exchanges the values

View file

@ -594,7 +594,7 @@ TEST_CASE("modifiers")
} }
} }
SECTION("range") SECTION("range for array")
{ {
json j_other_array = {"first", "second"}; json j_other_array = {"first", "second"};
@ -631,6 +631,40 @@ TEST_CASE("modifiers")
} }
} }
SECTION("range for object")
{
json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
json j_object2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};
SECTION("proper usage")
{
j_object1.insert(j_object2.begin(), j_object2.end());
CHECK(j_object1.size() == 4);
}
SECTION("empty range")
{
j_object1.insert(j_object2.begin(), j_object2.begin());
CHECK(j_object1.size() == 2);
}
SECTION("invalid iterators")
{
json j_other_array2 = {"first", "second"};
CHECK_THROWS_AS(j_array.insert(j_object2.begin(), j_object2.end()), json::type_error);
CHECK_THROWS_AS(j_object1.insert(j_object1.begin(), j_object2.end()), json::invalid_iterator);
CHECK_THROWS_AS(j_object1.insert(j_array.begin(), j_array.end()), json::invalid_iterator);
CHECK_THROWS_WITH(j_array.insert(j_object2.begin(), j_object2.end()),
"[json.exception.type_error.309] cannot use insert() with array");
CHECK_THROWS_WITH(j_object1.insert(j_object1.begin(), j_object2.end()),
"[json.exception.invalid_iterator.210] iterators do not fit");
CHECK_THROWS_WITH(j_object1.insert(j_array.begin(), j_array.end()),
"[json.exception.invalid_iterator.202] iterators first and last must point to objects");
}
}
SECTION("initializer list at position") SECTION("initializer list at position")
{ {
SECTION("insert before begin()") SECTION("insert before begin()")