Commit 9065545e authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[base] Add Value::Insert

In order to prepare for the switch of the return value of
Value::GetList() from Value::ListStorage& to span<Value> this change
adds an Insert API to Value, allowing callers to insert Values at
arbitrary positiions in the list. The signature of the API is inspired
by std::vector::insert, taking a insertion position and a Value, and
returning an iterator pointing to the just inserted element.

Bug: 646113
Change-Id: Ibacc9e1c22ee60b6f35661b66de951746e978b76
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1887694
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710725}
parent b16f20dd
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <utility> #include <utility>
#include "base/bit_cast.h" #include "base/bit_cast.h"
#include "base/containers/checked_iterators.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
...@@ -402,6 +403,21 @@ void Value::Append(Value&& value) { ...@@ -402,6 +403,21 @@ void Value::Append(Value&& value) {
list_.emplace_back(std::move(value)); list_.emplace_back(std::move(value));
} }
Value::ListStorage::iterator Value::Insert(ListStorage::const_iterator pos,
Value&& value) {
CHECK(is_list());
return list_.insert(pos, std::move(value));
}
CheckedContiguousIterator<Value> Value::Insert(
CheckedContiguousConstIterator<Value> pos,
Value&& value) {
CHECK(is_list());
const auto offset = pos - make_span(list_).begin();
list_.insert(list_.begin() + offset, std::move(value));
return make_span(list_).begin() + offset;
}
bool Value::EraseListIter(ListStorage::const_iterator iter) { bool Value::EraseListIter(ListStorage::const_iterator iter) {
CHECK(is_list()); CHECK(is_list());
if (iter == list_.end()) if (iter == list_.end())
......
...@@ -198,9 +198,20 @@ class BASE_EXPORT Value { ...@@ -198,9 +198,20 @@ class BASE_EXPORT Value {
void Append(StringPiece16 value); void Append(StringPiece16 value);
void Append(Value&& value); void Append(Value&& value);
// Inserts |value| before |pos|.
// Note: These CHECK that type() is Type::LIST.
// TODO(crbug.com/990059): Remove ListStorage::const_iterator overload once
// mutable GetList() returns a base::span.
ListStorage::iterator Insert(ListStorage::const_iterator pos, Value&& value);
CheckedContiguousIterator<Value> Insert(
CheckedContiguousConstIterator<Value> pos,
Value&& value);
// Erases the Value pointed to by |iter|. Returns false if |iter| is out of // Erases the Value pointed to by |iter|. Returns false if |iter| is out of
// bounds. // bounds.
// Note: This CHECKs that type() is Type::LIST. // Note: This CHECKs that type() is Type::LIST.
// TODO(crbug.com/990059): Remove ListStorage::const_iterator overload once
// mutable GetList() returns a base::span.
bool EraseListIter(ListStorage::const_iterator iter); bool EraseListIter(ListStorage::const_iterator iter);
bool EraseListIter(CheckedContiguousConstIterator<Value> iter); bool EraseListIter(CheckedContiguousConstIterator<Value> iter);
...@@ -866,9 +877,10 @@ class BASE_EXPORT ListValue : public Value { ...@@ -866,9 +877,10 @@ class BASE_EXPORT ListValue : public Value {
// DEPRECATED, use std::find() with Value::Append() instead. // DEPRECATED, use std::find() with Value::Append() instead.
bool AppendIfNotPresent(std::unique_ptr<Value> in_value); bool AppendIfNotPresent(std::unique_ptr<Value> in_value);
using Value::Insert;
// Insert a Value at index. // Insert a Value at index.
// Returns true if successful, or false if the index was out of range. // Returns true if successful, or false if the index was out of range.
// DEPRECATED, use GetList()::insert() instead. // DEPRECATED, use Value::Insert() instead.
bool Insert(size_t index, std::unique_ptr<Value> in_value); bool Insert(size_t index, std::unique_ptr<Value> in_value);
// Searches for the first instance of |value| in the list using the Equals // Searches for the first instance of |value| in the list using the Equals
......
...@@ -524,6 +524,23 @@ TEST(ValuesTest, Append) { ...@@ -524,6 +524,23 @@ TEST(ValuesTest, Append) {
EXPECT_TRUE(value.GetList().back().is_list()); EXPECT_TRUE(value.GetList().back().is_list());
} }
TEST(ValuesTest, Insert) {
ListValue value;
auto GetList = [&value]() -> decltype(auto) { return value.GetList(); };
auto GetConstList = [&value] {
const ListValue& const_value = value;
return const_value.GetList();
};
auto storage_iter = value.Insert(GetList().end(), Value(true));
EXPECT_TRUE(GetList().begin() == storage_iter);
EXPECT_TRUE(storage_iter->is_bool());
auto span_iter = value.Insert(GetConstList().begin(), Value(123));
EXPECT_TRUE(GetConstList().begin() == span_iter);
EXPECT_TRUE(span_iter->is_int());
}
TEST(ValuesTest, EraseListIter) { TEST(ValuesTest, EraseListIter) {
ListValue value; ListValue value;
value.Append(1); value.Append(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment