diff --git a/src/json.hpp b/src/json.hpp index b83a0331..b83ae8b4 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -1190,7 +1190,7 @@ class basic_json /// remove element from an object given a key inline size_type erase(const typename object_t::key_type& key) { - // at only works for objects + // this erase only works for objects if (m_type != value_t::object) { throw std::runtime_error("cannot use erase with " + type_name()); @@ -1199,6 +1199,23 @@ class basic_json return m_value.object->erase(key); } + /// remove element from an array given an index + inline void erase(const size_type pos) + { + // this erase only works for arrays + if (m_type != value_t::array) + { + throw std::runtime_error("cannot use erase with " + type_name()); + } + + if (pos >= size()) + { + throw std::out_of_range("index out of range"); + } + + m_value.array->erase(m_value.array->begin() + static_cast(pos)); + } + /// find an element in an object inline iterator find(typename object_t::key_type key) { diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index a88facf7..6a23b51e 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -1190,7 +1190,7 @@ class basic_json /// remove element from an object given a key inline size_type erase(const typename object_t::key_type& key) { - // at only works for objects + // this erase only works for objects if (m_type != value_t::object) { throw std::runtime_error("cannot use erase with " + type_name()); @@ -1199,6 +1199,23 @@ class basic_json return m_value.object->erase(key); } + /// remove element from an array given an index + inline void erase(const size_type pos) + { + // this erase only works for arrays + if (m_type != value_t::array) + { + throw std::runtime_error("cannot use erase with " + type_name()); + } + + if (pos >= size()) + { + throw std::out_of_range("index out of range"); + } + + m_value.array->erase(m_value.array->begin() + static_cast(pos)); + } + /// find an element in an object inline iterator find(typename object_t::key_type key) { diff --git a/test/unit.cpp b/test/unit.cpp index f1c88f44..a5abe59e 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -2291,6 +2291,91 @@ TEST_CASE("element access") } } } + + SECTION("remove specified element") + { + SECTION("remove element") + { + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(0); + CHECK(jarray == json({true, nullptr, "string", 42.23, json::object(), {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(1); + CHECK(jarray == json({1, nullptr, "string", 42.23, json::object(), {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(2); + CHECK(jarray == json({1, true, "string", 42.23, json::object(), {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(3); + CHECK(jarray == json({1, true, nullptr, 42.23, json::object(), {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(4); + CHECK(jarray == json({1, true, nullptr, "string", json::object(), {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(5); + CHECK(jarray == json({1, true, nullptr, "string", 42.23, {1, 2, 3}})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + jarray.erase(6); + CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object()})); + } + { + json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; + CHECK_THROWS_AS(jarray.erase(7), std::out_of_range); + } + } + + SECTION("access on non-object type") + { + SECTION("null") + { + json j_nonobject(json::value_t::null); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + + SECTION("boolean") + { + json j_nonobject(json::value_t::boolean); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + + SECTION("string") + { + json j_nonobject(json::value_t::string); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + + SECTION("object") + { + json j_nonobject(json::value_t::object); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + + SECTION("number (integer)") + { + json j_nonobject(json::value_t::number_integer); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + + SECTION("number (floating-point)") + { + json j_nonobject(json::value_t::number_float); + CHECK_THROWS_AS(j_nonobject.erase(0), std::runtime_error); + } + } + } } SECTION("object")