Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/json/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ 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, const Value& newValue);
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
23 changes: 23 additions & 0 deletions src/lib_json/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,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 @@ -1165,6 +1166,28 @@ Value& Value::append(Value&& value) {
return this->value_.map_->emplace(size(), std::move(value)).first->second;
}

/// \brief Insert value in array at specific index
bool Value::insert(ArrayIndex index, const Value& newValue) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
"in Json::Value::insert(ArrayIndex index, const Value& "
"newValue): requires arrayValue");
return insert(index, Value(newValue));
}
bool Value::insert(ArrayIndex index, Value&& newValue) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
"in Json::Value::insert(ArrayIndex index, Value&& "
"newValue): 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 {
Expand Down
56 changes: 56 additions & 0 deletions src/test_lib_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,61 @@ JSONTEST_FIXTURE(ValueTest, arrayIssue252) {
// JSONTEST_ASSERT_EQUAL(5, root["array"].size());
}

JSONTEST_FIXTURE(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
JSONTEST_ASSERT(array.insert(5, "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(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type());

Expand Down Expand Up @@ -2697,6 +2752,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, objects);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrays);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayIssue252);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayInsertAtRandomIndex);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, null);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, strings);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, bools);
Expand Down