implemented issue #57: erase with iterators
This commit is contained in:
parent
d7d0509161
commit
6dceab583c
3 changed files with 707 additions and 50 deletions
146
src/json.hpp
146
src/json.hpp
|
@ -7,26 +7,6 @@
|
|||
@see https://github.com/nlohmann/json
|
||||
*/
|
||||
|
||||
/*!
|
||||
@defgroup container Container
|
||||
@brief C++ Container concept
|
||||
|
||||
A Container is an object used to store other objects and taking care of the
|
||||
management of the memory used by the objects it contains.
|
||||
|
||||
@see http://en.cppreference.com/w/cpp/concept/Container
|
||||
|
||||
@defgroup reversiblecontainer Reversible Container
|
||||
@brief C++ Reversible Container concept
|
||||
@ingroup container
|
||||
|
||||
A ReversibleContainer is a Container that has iterators that meet the
|
||||
requirements of either BidirectionalIterator or RandomAccessIterator. Such
|
||||
iterators allow a ReversibleContainer to be iterated over in reverse.
|
||||
|
||||
@see http://en.cppreference.com/w/cpp/concept/ReversibleContainer
|
||||
*/
|
||||
|
||||
#ifndef _NLOHMANN_JSON
|
||||
#define _NLOHMANN_JSON
|
||||
|
||||
|
@ -871,15 +851,12 @@ class basic_json
|
|||
case (value_t::array):
|
||||
{
|
||||
T to_vector;
|
||||
//to_vector.reserve(m_value.array->size());
|
||||
std::transform(m_value.array->begin(), m_value.array->end(),
|
||||
std::inserter(to_vector, to_vector.end()), [](basic_json i)
|
||||
{
|
||||
return i.get<typename T::value_type>();
|
||||
});
|
||||
return to_vector;
|
||||
|
||||
// return T(m_value.array->begin(), m_value.array->end());
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -1187,6 +1164,129 @@ class basic_json
|
|||
return m_value.object->operator[](key);
|
||||
}
|
||||
|
||||
/// remove element given an iterator
|
||||
template <class T, typename
|
||||
std::enable_if<
|
||||
std::is_same<T, basic_json::iterator>::value or
|
||||
std::is_same<T, basic_json::const_iterator>::value
|
||||
, int>::type
|
||||
= 0>
|
||||
inline T erase(T pos)
|
||||
{
|
||||
// make sure iterator fits the current value
|
||||
if (this != pos.m_object or m_type != pos.m_object->m_type)
|
||||
{
|
||||
throw std::runtime_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
T result = end();
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case value_t::number_integer:
|
||||
case value_t::number_float:
|
||||
case value_t::boolean:
|
||||
case value_t::string:
|
||||
{
|
||||
if (pos.m_it.generic_iterator != 0)
|
||||
{
|
||||
throw std::out_of_range("iterator out of range");
|
||||
}
|
||||
|
||||
if (m_type == value_t::string)
|
||||
{
|
||||
delete m_value.string;
|
||||
m_value.string = nullptr;
|
||||
}
|
||||
|
||||
m_type = value_t::null;
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error("cannot use erase with " + type_name());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// remove elements given an iterator range
|
||||
template <class T, typename
|
||||
std::enable_if<
|
||||
std::is_same<T, basic_json::iterator>::value or
|
||||
std::is_same<T, basic_json::const_iterator>::value
|
||||
, int>::type
|
||||
= 0>
|
||||
inline T erase(T first, T last)
|
||||
{
|
||||
// make sure iterator fits the current value
|
||||
if (this != first.m_object or this != last.m_object or
|
||||
m_type != first.m_object->m_type or m_type != last.m_object->m_type)
|
||||
{
|
||||
throw std::runtime_error("iterators do not fit current value");
|
||||
}
|
||||
|
||||
T result = end();
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case value_t::number_integer:
|
||||
case value_t::number_float:
|
||||
case value_t::boolean:
|
||||
case value_t::string:
|
||||
{
|
||||
if (first.m_it.generic_iterator != 0 or last.m_it.generic_iterator != 1)
|
||||
{
|
||||
throw std::out_of_range("iterators out of range");
|
||||
}
|
||||
|
||||
if (m_type == value_t::string)
|
||||
{
|
||||
delete m_value.string;
|
||||
m_value.string = nullptr;
|
||||
}
|
||||
|
||||
m_type = value_t::null;
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
|
||||
last.m_it.object_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
|
||||
last.m_it.array_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error("cannot use erase with " + type_name());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// remove element from an object given a key
|
||||
inline size_type erase(const typename object_t::key_type& key)
|
||||
{
|
||||
|
|
|
@ -7,26 +7,6 @@
|
|||
@see https://github.com/nlohmann/json
|
||||
*/
|
||||
|
||||
/*!
|
||||
@defgroup container Container
|
||||
@brief C++ Container concept
|
||||
|
||||
A Container is an object used to store other objects and taking care of the
|
||||
management of the memory used by the objects it contains.
|
||||
|
||||
@see http://en.cppreference.com/w/cpp/concept/Container
|
||||
|
||||
@defgroup reversiblecontainer Reversible Container
|
||||
@brief C++ Reversible Container concept
|
||||
@ingroup container
|
||||
|
||||
A ReversibleContainer is a Container that has iterators that meet the
|
||||
requirements of either BidirectionalIterator or RandomAccessIterator. Such
|
||||
iterators allow a ReversibleContainer to be iterated over in reverse.
|
||||
|
||||
@see http://en.cppreference.com/w/cpp/concept/ReversibleContainer
|
||||
*/
|
||||
|
||||
#ifndef _NLOHMANN_JSON
|
||||
#define _NLOHMANN_JSON
|
||||
|
||||
|
@ -871,15 +851,12 @@ class basic_json
|
|||
case (value_t::array):
|
||||
{
|
||||
T to_vector;
|
||||
//to_vector.reserve(m_value.array->size());
|
||||
std::transform(m_value.array->begin(), m_value.array->end(),
|
||||
std::inserter(to_vector, to_vector.end()), [](basic_json i)
|
||||
{
|
||||
return i.get<typename T::value_type>();
|
||||
});
|
||||
return to_vector;
|
||||
|
||||
// return T(m_value.array->begin(), m_value.array->end());
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -1187,6 +1164,129 @@ class basic_json
|
|||
return m_value.object->operator[](key);
|
||||
}
|
||||
|
||||
/// remove element given an iterator
|
||||
template <class T, typename
|
||||
std::enable_if<
|
||||
std::is_same<T, basic_json::iterator>::value or
|
||||
std::is_same<T, basic_json::const_iterator>::value
|
||||
, int>::type
|
||||
= 0>
|
||||
inline T erase(T pos)
|
||||
{
|
||||
// make sure iterator fits the current value
|
||||
if (this != pos.m_object or m_type != pos.m_object->m_type)
|
||||
{
|
||||
throw std::runtime_error("iterator does not fit current value");
|
||||
}
|
||||
|
||||
T result = end();
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case value_t::number_integer:
|
||||
case value_t::number_float:
|
||||
case value_t::boolean:
|
||||
case value_t::string:
|
||||
{
|
||||
if (pos.m_it.generic_iterator != 0)
|
||||
{
|
||||
throw std::out_of_range("iterator out of range");
|
||||
}
|
||||
|
||||
if (m_type == value_t::string)
|
||||
{
|
||||
delete m_value.string;
|
||||
m_value.string = nullptr;
|
||||
}
|
||||
|
||||
m_type = value_t::null;
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error("cannot use erase with " + type_name());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// remove elements given an iterator range
|
||||
template <class T, typename
|
||||
std::enable_if<
|
||||
std::is_same<T, basic_json::iterator>::value or
|
||||
std::is_same<T, basic_json::const_iterator>::value
|
||||
, int>::type
|
||||
= 0>
|
||||
inline T erase(T first, T last)
|
||||
{
|
||||
// make sure iterator fits the current value
|
||||
if (this != first.m_object or this != last.m_object or
|
||||
m_type != first.m_object->m_type or m_type != last.m_object->m_type)
|
||||
{
|
||||
throw std::runtime_error("iterators do not fit current value");
|
||||
}
|
||||
|
||||
T result = end();
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case value_t::number_integer:
|
||||
case value_t::number_float:
|
||||
case value_t::boolean:
|
||||
case value_t::string:
|
||||
{
|
||||
if (first.m_it.generic_iterator != 0 or last.m_it.generic_iterator != 1)
|
||||
{
|
||||
throw std::out_of_range("iterators out of range");
|
||||
}
|
||||
|
||||
if (m_type == value_t::string)
|
||||
{
|
||||
delete m_value.string;
|
||||
m_value.string = nullptr;
|
||||
}
|
||||
|
||||
m_type = value_t::null;
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
|
||||
last.m_it.object_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
|
||||
last.m_it.array_iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error("cannot use erase with " + type_name());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// remove element from an object given a key
|
||||
inline size_type erase(const typename object_t::key_type& key)
|
||||
{
|
||||
|
|
465
test/unit.cpp
465
test/unit.cpp
|
@ -2294,7 +2294,7 @@ TEST_CASE("element access")
|
|||
|
||||
SECTION("remove specified element")
|
||||
{
|
||||
SECTION("remove element")
|
||||
SECTION("remove element by index")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
|
@ -2337,7 +2337,112 @@ TEST_CASE("element access")
|
|||
}
|
||||
}
|
||||
|
||||
SECTION("access on non-object type")
|
||||
SECTION("remove element by iterator")
|
||||
{
|
||||
SECTION("erase(begin())")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::iterator it2 = jarray.erase(jarray.begin());
|
||||
CHECK(jarray == json({true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(true));
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::const_iterator it2 = jarray.erase(jarray.cbegin());
|
||||
CHECK(jarray == json({true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(true));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase(begin(), end())")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());
|
||||
CHECK(jarray == json::array());
|
||||
CHECK(it2 == jarray.end());
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());
|
||||
CHECK(jarray == json::array());
|
||||
CHECK(it2 == jarray.cend());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase(begin(), begin())")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());
|
||||
CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(1));
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());
|
||||
CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(1));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase at offset")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::iterator it = jarray.begin() + 3;
|
||||
json::iterator it2 = jarray.erase(it);
|
||||
CHECK(jarray == json({1, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(42.23));
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::const_iterator it = jarray.cbegin() + 3;
|
||||
json::const_iterator it2 = jarray.erase(it);
|
||||
CHECK(jarray == json({1, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json(42.23));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase subrange")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::iterator it2 = jarray.erase(jarray.begin() + 2, jarray.begin() + 5);
|
||||
CHECK(jarray == json({1, true, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json::object());
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json::const_iterator it2 = jarray.erase(jarray.cbegin() + 2, jarray.cbegin() + 5);
|
||||
CHECK(jarray == json({1, true, json::object(), {1, 2, 3}}));
|
||||
CHECK(*it2 == json::object());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("different arrays")
|
||||
{
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json jarray2 = {"foo", "bar"};
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.begin()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::runtime_error);
|
||||
}
|
||||
{
|
||||
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
json jarray2 = {"foo", "bar"};
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::runtime_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("remove element by index in non-array type")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
|
@ -2569,7 +2674,7 @@ TEST_CASE("element access")
|
|||
|
||||
SECTION("remove specified element")
|
||||
{
|
||||
SECTION("remove element")
|
||||
SECTION("remove element by key")
|
||||
{
|
||||
CHECK(j.find("integer") != j.end());
|
||||
CHECK(j.erase("integer") == 1);
|
||||
|
@ -2607,7 +2712,112 @@ TEST_CASE("element access")
|
|||
CHECK(j.erase("array") == 0);
|
||||
}
|
||||
|
||||
SECTION("access on non-object type")
|
||||
SECTION("remove element by iterator")
|
||||
{
|
||||
SECTION("erase(begin())")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::iterator it2 = jobject.erase(jobject.begin());
|
||||
CHECK(jobject == json({{"b", 1}, {"c", 17}}));
|
||||
CHECK(*it2 == json(1));
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::const_iterator it2 = jobject.erase(jobject.cbegin());
|
||||
CHECK(jobject == json({{"b", 1}, {"c", 17}}));
|
||||
CHECK(*it2 == json(1));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase(begin(), end())")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::iterator it2 = jobject.erase(jobject.begin(), jobject.end());
|
||||
CHECK(jobject == json::object());
|
||||
CHECK(it2 == jobject.end());
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend());
|
||||
CHECK(jobject == json::object());
|
||||
CHECK(it2 == jobject.cend());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase(begin(), begin())")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin());
|
||||
CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17}}));
|
||||
CHECK(*it2 == json("a"));
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin());
|
||||
CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17}}));
|
||||
CHECK(*it2 == json("a"));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase at offset")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::iterator it = jobject.find("b");
|
||||
json::iterator it2 = jobject.erase(it);
|
||||
CHECK(jobject == json({{"a", "a"}, {"c", 17}}));
|
||||
CHECK(*it2 == json(17));
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
json::const_iterator it = jobject.find("b");
|
||||
json::const_iterator it2 = jobject.erase(it);
|
||||
CHECK(jobject == json({{"a", "a"}, {"c", 17}}));
|
||||
CHECK(*it2 == json(17));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase subrange")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
|
||||
json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
|
||||
CHECK(jobject == json({{"a", "a"}, {"e", true}}));
|
||||
CHECK(*it2 == json(true));
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
|
||||
json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
|
||||
CHECK(jobject == json({{"a", "a"}, {"e", true}}));
|
||||
CHECK(*it2 == json(true));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("different arrays")
|
||||
{
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
|
||||
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.begin()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::runtime_error);
|
||||
}
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
|
||||
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::runtime_error);
|
||||
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::runtime_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("remove element by key in non-object type")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
|
@ -2807,6 +3017,253 @@ TEST_CASE("element access")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("other values")
|
||||
{
|
||||
SECTION("erase with one valid iterator")
|
||||
{
|
||||
SECTION("string")
|
||||
{
|
||||
{
|
||||
json j = "foo";
|
||||
json::iterator it = j.erase(j.begin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = "bar";
|
||||
json::const_iterator it = j.erase(j.cbegin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (boolean)")
|
||||
{
|
||||
{
|
||||
json j = false;
|
||||
json::iterator it = j.erase(j.begin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = true;
|
||||
json::const_iterator it = j.erase(j.cbegin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
{
|
||||
json j = 17;
|
||||
json::iterator it = j.erase(j.begin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = 17;
|
||||
json::const_iterator it = j.erase(j.cbegin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (floating point)")
|
||||
{
|
||||
{
|
||||
json j = 23.42;
|
||||
json::iterator it = j.erase(j.begin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = 23.42;
|
||||
json::const_iterator it = j.erase(j.cbegin());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase with one invalid iterator")
|
||||
{
|
||||
SECTION("string")
|
||||
{
|
||||
{
|
||||
json j = "foo";
|
||||
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = "bar";
|
||||
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (boolean)")
|
||||
{
|
||||
{
|
||||
json j = false;
|
||||
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = true;
|
||||
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
{
|
||||
json j = 17;
|
||||
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = 17;
|
||||
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (floating point)")
|
||||
{
|
||||
{
|
||||
json j = 23.42;
|
||||
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = 23.42;
|
||||
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase with two valid iterators")
|
||||
{
|
||||
SECTION("string")
|
||||
{
|
||||
{
|
||||
json j = "foo";
|
||||
json::iterator it = j.erase(j.begin(), j.end());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = "bar";
|
||||
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (boolean)")
|
||||
{
|
||||
{
|
||||
json j = false;
|
||||
json::iterator it = j.erase(j.begin(), j.end());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = true;
|
||||
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
{
|
||||
json j = 17;
|
||||
json::iterator it = j.erase(j.begin(), j.end());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = 17;
|
||||
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (floating point)")
|
||||
{
|
||||
{
|
||||
json j = 23.42;
|
||||
json::iterator it = j.erase(j.begin(), j.end());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
{
|
||||
json j = 23.42;
|
||||
json::const_iterator it = j.erase(j.cbegin(), j.cend());
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
CHECK(it == j.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase with two invalid iterators")
|
||||
{
|
||||
SECTION("string")
|
||||
{
|
||||
{
|
||||
json j = "foo";
|
||||
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = "bar";
|
||||
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (boolean)")
|
||||
{
|
||||
{
|
||||
json j = false;
|
||||
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = true;
|
||||
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
{
|
||||
json j = 17;
|
||||
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = 17;
|
||||
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (floating point)")
|
||||
{
|
||||
{
|
||||
json j = 23.42;
|
||||
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
|
||||
}
|
||||
{
|
||||
json j = 23.42;
|
||||
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
|
||||
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("iterators")
|
||||
|
|
Loading…
Reference in a new issue