From 1c8d5dc211be6da4ed97d12bb3cab3211551b6cd Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 12 Jul 2015 22:47:08 +0200 Subject: [PATCH] added another insert function --- doc/examples/insert__ilist.cpp | 16 +++++++++++++ doc/examples/insert__ilist.link | 1 + doc/examples/insert__ilist.output | 2 ++ src/json.hpp | 39 +++++++++++++++++++++++++++++++ src/json.hpp.re2c | 39 +++++++++++++++++++++++++++++++ test/unit.cpp | 32 +++++++++++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 doc/examples/insert__ilist.cpp create mode 100644 doc/examples/insert__ilist.link create mode 100644 doc/examples/insert__ilist.output diff --git a/doc/examples/insert__ilist.cpp b/doc/examples/insert__ilist.cpp new file mode 100644 index 00000000..02d83dae --- /dev/null +++ b/doc/examples/insert__ilist.cpp @@ -0,0 +1,16 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert range from v2 before the end of array v + auto new_pos = v.insert(v.end(), {7, 8, 9}); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} diff --git a/doc/examples/insert__ilist.link b/doc/examples/insert__ilist.link new file mode 100644 index 00000000..b7bfd25a --- /dev/null +++ b/doc/examples/insert__ilist.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/insert__ilist.output b/doc/examples/insert__ilist.output new file mode 100644 index 00000000..b2fc7eeb --- /dev/null +++ b/doc/examples/insert__ilist.output @@ -0,0 +1,2 @@ +7 +[1,2,3,4,7,8,9] diff --git a/src/json.hpp b/src/json.hpp index 344d5f7b..8922f96e 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -3876,6 +3876,45 @@ class basic_json return result; } + /*! + @brief inserts elements + + Inserts elements from initializer list @a ilist before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] ilist initializer list to insert the values from + + @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 + @return iterator pointing to the first element inserted, or @a pos if + `ilist` is empty + + @complexity Linear in `ilist.size()` plus linear in the distance between @a + pos and end of the container. + + @liveexample{The example shows how insert is used.,insert__ilist} + */ + iterator insert(const_iterator pos, std::initializer_list ilist) + { + // 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, ilist); + return result; + } + /*! @brief exchanges the values diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index e7624ea6..4dfab366 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -3876,6 +3876,45 @@ class basic_json return result; } + /*! + @brief inserts elements + + Inserts elements from initializer list @a ilist before iterator @a pos. + + @param[in] pos iterator before which the content will be inserted; may be + the end() iterator + @param[in] ilist initializer list to insert the values from + + @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 + @return iterator pointing to the first element inserted, or @a pos if + `ilist` is empty + + @complexity Linear in `ilist.size()` plus linear in the distance between @a + pos and end of the container. + + @liveexample{The example shows how insert is used.,insert__ilist} + */ + iterator insert(const_iterator pos, std::initializer_list ilist) + { + // 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, ilist); + return result; + } + /*! @brief exchanges the values diff --git a/test/unit.cpp b/test/unit.cpp index ebeecb36..e3830519 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -6743,6 +6743,36 @@ TEST_CASE("modifiers") } } + SECTION("initializer list at position") + { + SECTION("insert before begin()") + { + auto it = j_array.insert(j_array.begin(), {7, 8, 9}); + CHECK(j_array.size() == 7); + CHECK(*it == json(7)); + CHECK(j_array.begin() == it); + CHECK(j_array == json({7, 8, 9, 1, 2, 3, 4})); + } + + SECTION("insert in the middle") + { + auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9}); + CHECK(j_array.size() == 7); + CHECK(*it == json(7)); + CHECK((it - j_array.begin()) == 2); + CHECK(j_array == json({1, 2, 7, 8, 9, 3, 4})); + } + + SECTION("insert before end()") + { + auto it = j_array.insert(j_array.end(), {7, 8, 9}); + CHECK(j_array.size() == 7); + CHECK(*it == json(7)); + CHECK((j_array.end() - it) == 3); + CHECK(j_array == json({1, 2, 3, 4, 7, 8, 9})); + } + } + SECTION("invalid iterator") { // pass iterator to a different array @@ -6753,6 +6783,7 @@ TEST_CASE("modifiers") 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); + CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), std::domain_error); } SECTION("non-array type") @@ -6765,6 +6796,7 @@ TEST_CASE("modifiers") 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); + CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), std::domain_error); } }