added first insert functions
This commit is contained in:
parent
b2efd50a03
commit
186aefb8f2
13 changed files with 503 additions and 3 deletions
|
@ -400,7 +400,7 @@ $ make
|
|||
$ ./json_unit "*"
|
||||
|
||||
===============================================================================
|
||||
All tests passed (3341006 assertions in 22 test cases)
|
||||
All tests passed (3341759 assertions in 27 test cases)
|
||||
```
|
||||
|
||||
For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml).
|
||||
|
|
16
doc/examples/insert.cpp
Normal file
16
doc/examples/insert.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON array
|
||||
json v = {1, 2, 3, 4};
|
||||
|
||||
// insert number 10 before number 3
|
||||
auto new_pos = v.insert(v.begin() + 2, 10);
|
||||
|
||||
// output new array and result of insert call
|
||||
std::cout << *new_pos << '\n';
|
||||
std::cout << v << '\n';
|
||||
}
|
1
doc/examples/insert.link
Normal file
1
doc/examples/insert.link
Normal file
|
@ -0,0 +1 @@
|
|||
<a target="_blank" href="http://melpon.org/wandbox/permlink/s0562du3uk9eMpos"><b>online</b></a>
|
2
doc/examples/insert.output
Normal file
2
doc/examples/insert.output
Normal file
|
@ -0,0 +1,2 @@
|
|||
10
|
||||
[1,2,10,3,4]
|
16
doc/examples/insert__count.cpp
Normal file
16
doc/examples/insert__count.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON array
|
||||
json v = {1, 2, 3, 4};
|
||||
|
||||
// insert number 7 copies of number 7 before number 3
|
||||
auto new_pos = v.insert(v.begin() + 2, 7, 7);
|
||||
|
||||
// output new array and result of insert call
|
||||
std::cout << *new_pos << '\n';
|
||||
std::cout << v << '\n';
|
||||
}
|
1
doc/examples/insert__count.link
Normal file
1
doc/examples/insert__count.link
Normal file
|
@ -0,0 +1 @@
|
|||
<a target="_blank" href="http://melpon.org/wandbox/permlink/kZCcDOrWRsmOCjOn"><b>online</b></a>
|
2
doc/examples/insert__count.output
Normal file
2
doc/examples/insert__count.output
Normal file
|
@ -0,0 +1,2 @@
|
|||
7
|
||||
[1,2,7,7,7,7,7,7,7,3,4]
|
19
doc/examples/insert__range.cpp
Normal file
19
doc/examples/insert__range.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include <json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
int main()
|
||||
{
|
||||
// create a JSON array
|
||||
json v = {1, 2, 3, 4};
|
||||
|
||||
// create a JSON array to copy values from
|
||||
json v2 = {"one", "two", "three", "four"};
|
||||
|
||||
// insert range from v2 before the end of array v
|
||||
auto new_pos = v.insert(v.end(), v2.begin(), v2.end());
|
||||
|
||||
// output new array and result of insert call
|
||||
std::cout << *new_pos << '\n';
|
||||
std::cout << v << '\n';
|
||||
}
|
1
doc/examples/insert__range.link
Normal file
1
doc/examples/insert__range.link
Normal file
|
@ -0,0 +1 @@
|
|||
<a target="_blank" href="http://melpon.org/wandbox/permlink/lZeC91nMjP3Npmx7"><b>online</b></a>
|
2
doc/examples/insert__range.output
Normal file
2
doc/examples/insert__range.output
Normal file
|
@ -0,0 +1,2 @@
|
|||
"one"
|
||||
[1,2,3,4,"one","two","three","four"]
|
144
src/json.hpp
144
src/json.hpp
|
@ -3694,7 +3694,7 @@ class basic_json
|
|||
called on a JSON null value, an empty object is created before inserting @a
|
||||
value.
|
||||
|
||||
@param value the value to add to the JSON object
|
||||
@param[in] value the value to add to the JSON object
|
||||
|
||||
@throw std::domain_error when called on a type other than JSON object or
|
||||
null
|
||||
|
@ -3734,6 +3734,148 @@ class basic_json
|
|||
return operator[](value.first);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts element
|
||||
|
||||
Inserts element @a value before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] value element to insert
|
||||
@return iterator pointing to the inserted @a value.
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
|
||||
@complexity Constant plus linear in the distance between pos and end of the
|
||||
container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert}
|
||||
*/
|
||||
iterator insert(const_iterator pos, const basic_json& value)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts element
|
||||
@copydoc insert(const_iterator, const basic_json&)
|
||||
*/
|
||||
iterator insert(const_iterator pos, basic_json&& value)
|
||||
{
|
||||
return insert(pos, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts elements
|
||||
|
||||
Inserts @a count copies of @a value before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] count number of copies of @a value to insert
|
||||
@param[in] value element to insert
|
||||
@return iterator pointing to the first element inserted, or @a pos if
|
||||
`count==0`
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
|
||||
@complexity Linear in @a count plus linear in the distance between @a pos
|
||||
and end of the container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert__count}
|
||||
*/
|
||||
iterator insert(const_iterator pos, size_type count, const basic_json& value)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, count, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts elements
|
||||
|
||||
Inserts elements from range `[first, last)` before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] first begin of the range of elements to insert
|
||||
@param[in] last end of the range of elements to insert
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
@throw std::domain_error if @a first and @a last do not belong to the same
|
||||
JSON value
|
||||
@throw std::domain_error if @a first or @a last are iterators into
|
||||
container for which insert is called
|
||||
@return iterator pointing to the first element inserted, or @a pos if
|
||||
`first==last`
|
||||
|
||||
@complexity Linear in `std::distance(first, last)` plus linear in the
|
||||
distance between @a pos and end of the container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert__range}
|
||||
*/
|
||||
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
if (first.m_object != last.m_object)
|
||||
{
|
||||
throw std::domain_error("iterators does not fit");
|
||||
}
|
||||
|
||||
if (first.m_object == this or last.m_object == this)
|
||||
{
|
||||
throw std::domain_error("passed iterators may not belong to container");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator,
|
||||
first.m_it.array_iterator, last.m_it.array_iterator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief exchanges the values
|
||||
|
||||
|
|
|
@ -3694,7 +3694,7 @@ class basic_json
|
|||
called on a JSON null value, an empty object is created before inserting @a
|
||||
value.
|
||||
|
||||
@param value the value to add to the JSON object
|
||||
@param[in] value the value to add to the JSON object
|
||||
|
||||
@throw std::domain_error when called on a type other than JSON object or
|
||||
null
|
||||
|
@ -3734,6 +3734,148 @@ class basic_json
|
|||
return operator[](value.first);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts element
|
||||
|
||||
Inserts element @a value before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] value element to insert
|
||||
@return iterator pointing to the inserted @a value.
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
|
||||
@complexity Constant plus linear in the distance between pos and end of the
|
||||
container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert}
|
||||
*/
|
||||
iterator insert(const_iterator pos, const basic_json& value)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts element
|
||||
@copydoc insert(const_iterator, const basic_json&)
|
||||
*/
|
||||
iterator insert(const_iterator pos, basic_json&& value)
|
||||
{
|
||||
return insert(pos, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts elements
|
||||
|
||||
Inserts @a count copies of @a value before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] count number of copies of @a value to insert
|
||||
@param[in] value element to insert
|
||||
@return iterator pointing to the first element inserted, or @a pos if
|
||||
`count==0`
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
|
||||
@complexity Linear in @a count plus linear in the distance between @a pos
|
||||
and end of the container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert__count}
|
||||
*/
|
||||
iterator insert(const_iterator pos, size_type count, const basic_json& value)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, count, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief inserts elements
|
||||
|
||||
Inserts elements from range `[first, last)` before iterator @a pos.
|
||||
|
||||
@param[in] pos iterator before which the content will be inserted; may be
|
||||
the end() iterator
|
||||
@param[in] first begin of the range of elements to insert
|
||||
@param[in] last end of the range of elements to insert
|
||||
|
||||
@throw std::domain_error if called on JSON values other than arrays
|
||||
@throw std::domain_error if @a pos is not an iterator of *this
|
||||
@throw std::domain_error if @a first and @a last do not belong to the same
|
||||
JSON value
|
||||
@throw std::domain_error if @a first or @a last are iterators into
|
||||
container for which insert is called
|
||||
@return iterator pointing to the first element inserted, or @a pos if
|
||||
`first==last`
|
||||
|
||||
@complexity Linear in `std::distance(first, last)` plus linear in the
|
||||
distance between @a pos and end of the container.
|
||||
|
||||
@liveexample{The example shows how insert is used.,insert__range}
|
||||
*/
|
||||
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
|
||||
{
|
||||
// insert only works for arrays
|
||||
if (m_type != value_t::array)
|
||||
{
|
||||
throw std::domain_error("cannot use insert() with " + type_name());
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (pos.m_object != this)
|
||||
{
|
||||
throw std::domain_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
if (first.m_object != last.m_object)
|
||||
{
|
||||
throw std::domain_error("iterators does not fit");
|
||||
}
|
||||
|
||||
if (first.m_object == this or last.m_object == this)
|
||||
{
|
||||
throw std::domain_error("passed iterators may not belong to container");
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
iterator result(this);
|
||||
result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator,
|
||||
first.m_it.array_iterator, last.m_it.array_iterator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief exchanges the values
|
||||
|
||||
|
|
156
test/unit.cpp
156
test/unit.cpp
|
@ -6608,6 +6608,162 @@ TEST_CASE("modifiers")
|
|||
}
|
||||
}
|
||||
|
||||
SECTION("insert")
|
||||
{
|
||||
json j_array = {1, 2, 3, 4};
|
||||
json j_value = 5;
|
||||
|
||||
SECTION("value at position")
|
||||
{
|
||||
SECTION("insert before begin()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), j_value);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK(j_array.begin() == it);
|
||||
CHECK(j_array == json({5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert in the middle")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, j_value);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((it - j_array.begin()) == 2);
|
||||
CHECK(j_array == json({1, 2, 5, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert before end()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_value);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((j_array.end() - it) == 1);
|
||||
CHECK(j_array == json({1, 2, 3, 4, 5}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("rvalue at position")
|
||||
{
|
||||
SECTION("insert before begin()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), 5);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK(j_array.begin() == it);
|
||||
CHECK(j_array == json({5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert in the middle")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, 5);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((it - j_array.begin()) == 2);
|
||||
CHECK(j_array == json({1, 2, 5, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert before end()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), 5);
|
||||
CHECK(j_array.size() == 5);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((j_array.end() - it) == 1);
|
||||
CHECK(j_array == json({1, 2, 3, 4, 5}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("copies at position")
|
||||
{
|
||||
SECTION("insert before begin()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), 3, 5);
|
||||
CHECK(j_array.size() == 7);
|
||||
CHECK(*it == j_value);
|
||||
CHECK(j_array.begin() == it);
|
||||
CHECK(j_array == json({5, 5, 5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert in the middle")
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, 3, 5);
|
||||
CHECK(j_array.size() == 7);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((it - j_array.begin()) == 2);
|
||||
CHECK(j_array == json({1, 2, 5, 5, 5, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("insert before end()")
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), 3, 5);
|
||||
CHECK(j_array.size() == 7);
|
||||
CHECK(*it == j_value);
|
||||
CHECK((j_array.end() - it) == 3);
|
||||
CHECK(j_array == json({1, 2, 3, 4, 5, 5, 5}));
|
||||
}
|
||||
|
||||
SECTION("insert nothing (count = 0)")
|
||||
{
|
||||
auto pos = j_array.end();
|
||||
auto it = j_array.insert(j_array.end(), 0, 5);
|
||||
CHECK(j_array.size() == 4);
|
||||
CHECK(it == pos);
|
||||
CHECK(j_array == json({1, 2, 3, 4}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("range")
|
||||
{
|
||||
json j_other_array = {"first", "second"};
|
||||
|
||||
SECTION("proper usage")
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());
|
||||
CHECK(j_array.size() == 6);
|
||||
CHECK(*it == *j_other_array.begin());
|
||||
CHECK((j_array.end() - it) == 2);
|
||||
CHECK(j_array == json({1, 2, 3, 4, "first", "second"}));
|
||||
}
|
||||
|
||||
SECTION("empty range")
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());
|
||||
CHECK(j_array.size() == 4);
|
||||
CHECK(it == j_array.end());
|
||||
CHECK(j_array == json({1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
SECTION("invalid iterators")
|
||||
{
|
||||
CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("invalid iterator")
|
||||
{
|
||||
// pass iterator to a different array
|
||||
json j_another_array = {1, 2};
|
||||
json j_yet_another_array = {"first", "second"};
|
||||
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10), std::domain_error);
|
||||
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_value), std::domain_error);
|
||||
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), 10, 11), std::domain_error);
|
||||
CHECK_THROWS_AS(j_array.insert(j_another_array.end(), j_yet_another_array.begin(),
|
||||
j_yet_another_array.end()), std::domain_error);
|
||||
}
|
||||
|
||||
SECTION("non-array type")
|
||||
{
|
||||
// call insert on a non-array type
|
||||
json j_nonarray = 3;
|
||||
json j_yet_another_array = {"first", "second"};
|
||||
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10), std::domain_error);
|
||||
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_value), std::domain_error);
|
||||
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), 10, 11), std::domain_error);
|
||||
CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
|
||||
j_yet_another_array.end()), std::domain_error);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("swap()")
|
||||
{
|
||||
SECTION("json")
|
||||
|
|
Loading…
Reference in a new issue