Skip to content

add a new method to insert a new value in an array at specific index. #949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Oct 16, 2019
Merged
2 changes: 2 additions & 0 deletions include/json/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ class JSON_API Value {
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value& append(const Value& value);
Value& append(Value&& value);
/// \brief Insert value in array at specific index
bool insert(ArrayIndex index, Value newValue);

/// Access an object value by name, create a null member if it does not exist.
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
Expand Down
16 changes: 16 additions & 0 deletions src/lib_json/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,7 @@ Value const& Value::operator[](CppTL::ConstString const& key) const {
#endif

Value& Value::append(const Value& value) { return append(Value(value)); }

Value& Value::append(Value&& value) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
"in Json::Value::append: requires arrayValue");
Expand All @@ -1157,6 +1158,21 @@ Value& Value::append(Value&& value) {
return this->value_.map_->emplace(size(), std::move(value)).first->second;
}

bool Value::insert(ArrayIndex index, Value newValue) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
"in Json::Value::insert: requires arrayValue");
ArrayIndex length = size();
if (index > length) {
return false;
} else {
for (ArrayIndex i = length; i > index; i--) {
(*this)[i] = std::move((*this)[i - 1]);
}
(*this)[index] = std::move(newValue);
return true;
}
}

Value Value::get(char const* begin, char const* end,
Value const& defaultValue) const {
Value const* found = find(begin, end);
Expand Down
57 changes: 57 additions & 0 deletions src/test_lib_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,63 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayIssue252) {
// JSONTEST_ASSERT_EQUAL(5, root["array"].size());
}

JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) {
Json::Value array;
const Json::Value str0("index2");
const Json::Value str1("index3");
array.append("index0"); // append rvalue
array.append("index1");
array.append(str0); // append lvalue

std::vector<Json::Value*> vec; // storage value address for checking
for (int i = 0; i < 3; i++) {
vec.push_back(&array[i]);
}
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]); // check append
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]);

// insert lvalue at the head
JSONTEST_ASSERT(array.insert(0, str1));
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[3]);
// checking address
for (int i = 0; i < 3; i++) {
JSONTEST_ASSERT_EQUAL(vec[i], &array[i]);
}
vec.push_back(&array[3]);
// insert rvalue at middle
JSONTEST_ASSERT(array.insert(2, "index4"));
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]);
// checking address
for (int i = 0; i < 4; i++) {
JSONTEST_ASSERT_EQUAL(vec[i], &array[i]);
}
vec.push_back(&array[4]);
// insert rvalue at the tail
Json::Value index5("index5");
JSONTEST_ASSERT(array.insert(5, std::move(index5)));
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]);
JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[5]);
// checking address
for (int i = 0; i < 5; i++) {
JSONTEST_ASSERT_EQUAL(vec[i], &array[i]);
}
vec.push_back(&array[5]);
// beyond max array size, it should not be allowed to insert into its tail
JSONTEST_ASSERT(!array.insert(10, "index10"));
}

JSONTEST_FIXTURE_LOCAL(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type());

Expand Down