Change base::Value::ListStorage to std::vector<base::Value>
This CL is a first step to inlining base::ListValue. It is proposed to use an
std::vector<base::Value> as the underlying ListStorage. This CL implements the
change and updates the code accordingly.
TBR=bajones@chromium.org, dbeam@chromium.org, stevenjb@chromium.org
BUG=646113
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel
Review-Url: https://codereview.chromium.org/2740143002
Cr-Commit-Position: refs/heads/master@{#463618}
CrOS-Libchrome-Original-Commit: ebab0defaea3aed024283a64088ebc0cd352b47f
diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc
index 07b9d50..19f28f2 100644
--- a/base/json/json_writer.cc
+++ b/base/json/json_writer.cc
@@ -128,7 +128,7 @@
bool result = node.GetAsList(&list);
DCHECK(result);
for (const auto& value : *list) {
- if (omit_binary_values_ && value->GetType() == Value::Type::BINARY)
+ if (omit_binary_values_ && value.GetType() == Value::Type::BINARY)
continue;
if (first_value_has_been_output) {
@@ -137,7 +137,7 @@
json_string_->push_back(' ');
}
- if (!BuildJSONString(*value, depth))
+ if (!BuildJSONString(value, depth))
result = false;
first_value_has_been_output = true;
diff --git a/base/test/gtest_util.cc b/base/test/gtest_util.cc
index 6da902d..1552c1a 100644
--- a/base/test/gtest_util.cc
+++ b/base/test/gtest_util.cc
@@ -85,7 +85,7 @@
std::vector<base::TestIdentifier> result;
for (base::ListValue::iterator i = tests->begin(); i != tests->end(); ++i) {
base::DictionaryValue* test = nullptr;
- if (!(*i)->GetAsDictionary(&test))
+ if (!i->GetAsDictionary(&test))
return false;
TestIdentifier test_data;
diff --git a/base/trace_event/trace_event_argument.cc b/base/trace_event/trace_event_argument.cc
index db702b6..646b1f2 100644
--- a/base/trace_event/trace_event_argument.cc
+++ b/base/trace_event/trace_event_argument.cc
@@ -289,7 +289,7 @@
value.GetAsList(&list_value);
BeginArrayWithCopiedName(name);
for (const auto& base_value : *list_value)
- AppendBaseValue(*base_value);
+ AppendBaseValue(base_value);
EndArray();
} break;
}
@@ -343,7 +343,7 @@
value.GetAsList(&list_value);
BeginArray();
for (const auto& base_value : *list_value)
- AppendBaseValue(*base_value);
+ AppendBaseValue(base_value);
EndArray();
} break;
}
@@ -369,9 +369,11 @@
cur_dict = new_dict;
} else {
cur_list->Append(WrapUnique(new_dict));
+ // |new_dict| is invalidated at this point, so |cur_dict| needs to be
+ // reset.
+ cur_list->GetDictionary(cur_list->GetSize() - 1, &cur_dict);
stack.push_back(cur_list);
cur_list = nullptr;
- cur_dict = new_dict;
}
} break;
@@ -396,7 +398,8 @@
} else {
cur_list->Append(WrapUnique(new_list));
stack.push_back(cur_list);
- cur_list = new_list;
+ // |cur_list| is invalidated at this point, so it needs to be reset.
+ cur_list->GetList(cur_list->GetSize() - 1, &cur_list);
}
} break;
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc
index ffc4c08..99f0240 100644
--- a/base/trace_event/trace_event_memory_overhead.cc
+++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -105,7 +105,7 @@
value.GetAsList(&list_value);
Add("ListValue", sizeof(ListValue));
for (const auto& v : *list_value)
- AddValue(*v);
+ AddValue(v);
} break;
default:
diff --git a/base/values.cc b/base/values.cc
index ca12edc..74e83b9 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -35,7 +35,7 @@
std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
std::unique_ptr<ListValue> copy;
for (const auto& entry : list) {
- std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(*entry);
+ std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(entry);
if (child_copy) {
if (!copy)
copy.reset(new ListValue);
@@ -375,12 +375,7 @@
std::tie(v.first, *v.second);
});
case Value::Type::LIST:
- if (lhs.list_->size() != rhs.list_->size())
- return false;
- return std::equal(
- std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
- [](const Value::ListStorage::value_type& u,
- const Value::ListStorage::value_type& v) { return *u == *v; });
+ return *lhs.list_ == *rhs.list_;
}
NOTREACHED();
@@ -419,11 +414,7 @@
return std::tie(u.first, *u.second) < std::tie(v.first, *v.second);
});
case Value::Type::LIST:
- return std::lexicographical_compare(
- std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
- std::end(*rhs.list_),
- [](const Value::ListStorage::value_type& u,
- const Value::ListStorage::value_type& v) { return *u < *v; });
+ return *lhs.list_ < *rhs.list_;
}
NOTREACHED();
@@ -494,11 +485,10 @@
case Type::BINARY:
binary_value_.Init(*that.binary_value_);
return;
- // DictStorage and ListStorage are move-only types due to the presence of
- // unique_ptrs. This is why the explicit copy of every element is necessary
- // here.
- // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
- // can be copied directly.
+ // DictStorage is a move-only type due to the presence of unique_ptrs. This
+ // is why the explicit copy of every element is necessary here.
+ // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
+ // directly.
case Type::DICTIONARY:
dict_ptr_.Init(MakeUnique<DictStorage>());
for (const auto& it : **that.dict_ptr_) {
@@ -508,10 +498,7 @@
}
return;
case Type::LIST:
- list_.Init();
- list_->reserve(that.list_->size());
- for (const auto& it : *that.list_)
- list_->push_back(MakeUnique<Value>(*it));
+ list_.Init(*that.list_);
return;
}
}
@@ -561,16 +548,17 @@
case Type::BINARY:
*binary_value_ = *that.binary_value_;
return;
- // DictStorage and ListStorage are move-only types due to the presence of
- // unique_ptrs. This is why the explicit call to the copy constructor is
- // necessary here.
- // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
- // can be copied directly.
- case Type::DICTIONARY:
- *dict_ptr_ = std::move(*Value(that).dict_ptr_);
+ // DictStorage is a move-only type due to the presence of unique_ptrs. This
+ // is why the explicit call to the copy constructor is necessary here.
+ // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
+ // directly.
+ case Type::DICTIONARY: {
+ Value copy = that;
+ *dict_ptr_ = std::move(*copy.dict_ptr_);
return;
+ }
case Type::LIST:
- *list_ = std::move(*Value(that).list_);
+ *list_ = *that.list_;
return;
}
}
@@ -1077,6 +1065,10 @@
list_->clear();
}
+void ListValue::Reserve(size_t n) {
+ list_->reserve(n);
+}
+
bool ListValue::Set(size_t index, Value* in_value) {
return Set(index, WrapUnique(in_value));
}
@@ -1091,9 +1083,7 @@
Append(MakeUnique<Value>());
Append(std::move(in_value));
} else {
- // TODO(dcheng): remove this DCHECK once the raw pointer version is removed?
- DCHECK((*list_)[index] != in_value);
- (*list_)[index] = std::move(in_value);
+ (*list_)[index] = std::move(*in_value);
}
return true;
}
@@ -1103,7 +1093,7 @@
return false;
if (out_value)
- *out_value = (*list_)[index].get();
+ *out_value = &(*list_)[index];
return true;
}
@@ -1213,36 +1203,35 @@
return false;
if (out_value)
- *out_value = std::move((*list_)[index]);
+ *out_value = MakeUnique<Value>(std::move((*list_)[index]));
list_->erase(list_->begin() + index);
return true;
}
bool ListValue::Remove(const Value& value, size_t* index) {
- for (auto it = list_->begin(); it != list_->end(); ++it) {
- if (**it == value) {
- size_t previous_index = it - list_->begin();
- list_->erase(it);
+ auto it = std::find(list_->begin(), list_->end(), value);
- if (index)
- *index = previous_index;
- return true;
- }
- }
- return false;
+ if (it == list_->end())
+ return false;
+
+ if (index)
+ *index = std::distance(list_->begin(), it);
+
+ list_->erase(it);
+ return true;
}
ListValue::iterator ListValue::Erase(iterator iter,
std::unique_ptr<Value>* out_value) {
if (out_value)
- *out_value = std::move(*ListStorage::iterator(iter));
+ *out_value = MakeUnique<Value>(std::move(*iter));
return list_->erase(iter);
}
void ListValue::Append(std::unique_ptr<Value> in_value) {
- list_->push_back(std::move(in_value));
+ list_->push_back(std::move(*in_value));
}
#if !defined(OS_LINUX)
@@ -1288,11 +1277,10 @@
bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
DCHECK(in_value);
- for (const auto& entry : *list_) {
- if (*entry == *in_value)
- return false;
- }
- list_->push_back(std::move(in_value));
+ if (std::find(list_->begin(), list_->end(), *in_value) != list_->end())
+ return false;
+
+ list_->push_back(std::move(*in_value));
return true;
}
@@ -1301,15 +1289,12 @@
if (index > list_->size())
return false;
- list_->insert(list_->begin() + index, std::move(in_value));
+ list_->insert(list_->begin() + index, std::move(*in_value));
return true;
}
ListValue::const_iterator ListValue::Find(const Value& value) const {
- return std::find_if(list_->begin(), list_->end(),
- [&value](const std::unique_ptr<Value>& entry) {
- return *entry == value;
- });
+ return std::find(list_->begin(), list_->end(), value);
}
void ListValue::Swap(ListValue* other) {
diff --git a/base/values.h b/base/values.h
index ace8b43..075bc9f 100644
--- a/base/values.h
+++ b/base/values.h
@@ -49,7 +49,7 @@
class BASE_EXPORT Value {
public:
using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
- using ListStorage = std::vector<std::unique_ptr<Value>>;
+ using ListStorage = std::vector<Value>;
enum class Type {
NONE = 0,
@@ -390,9 +390,15 @@
// Returns the number of Values in this list.
size_t GetSize() const { return list_->size(); }
+ // Returns the capacity of storage for Values in this list.
+ size_t capacity() const { return list_->capacity(); }
+
// Returns whether the list is empty.
bool empty() const { return list_->empty(); }
+ // Reserves storage for at least |n| values.
+ void Reserve(size_t n);
+
// Sets the list item at the given index to be the Value specified by
// the value given. If the index beyond the current end of the list, null
// Values will be used to pad out the list.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 077f54c..ae91658 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -437,7 +437,7 @@
base::Value not_found_value(false);
ASSERT_NE(mixed_list->end(), mixed_list->Find(sought_value));
- ASSERT_TRUE((*mixed_list->Find(sought_value))->GetAsInteger(&int_value));
+ ASSERT_TRUE((*mixed_list->Find(sought_value)).GetAsInteger(&int_value));
ASSERT_EQ(42, int_value);
ASSERT_EQ(mixed_list->end(), mixed_list->Find(not_found_value));
}
@@ -540,10 +540,10 @@
{
ListValue list;
auto value = MakeUnique<Value>();
- Value* original_value = value.get();
+ Value original_value = *value;
list.Append(std::move(value));
size_t index = 0;
- list.Remove(*original_value, &index);
+ list.Remove(original_value, &index);
EXPECT_EQ(0U, index);
EXPECT_EQ(0U, list.GetSize());
}
diff --git a/components/policy/core/common/policy_test_utils.cc b/components/policy/core/common/policy_test_utils.cc
index 7f4e597..fcf89f9 100644
--- a/components/policy/core/common/policy_test_utils.cc
+++ b/components/policy/core/common/policy_test_utils.cc
@@ -126,7 +126,7 @@
// CFArrayAppendValue() retains |cf_value|, so make sure the reference
// created by ValueToProperty() is released.
base::ScopedCFTypeRef<CFPropertyListRef> cf_value(
- ValueToProperty(*entry));
+ ValueToProperty(entry));
if (cf_value)
CFArrayAppendValue(array, cf_value);
}
diff --git a/components/policy/core/common/registry_dict.cc b/components/policy/core/common/registry_dict.cc
index f421904..124a2cd 100644
--- a/components/policy/core/common/registry_dict.cc
+++ b/components/policy/core/common/registry_dict.cc
@@ -62,7 +62,7 @@
for (base::ListValue::const_iterator entry(list->begin());
entry != list->end(); ++entry) {
std::unique_ptr<base::Value> converted =
- ConvertValue(**entry, schema.GetItems());
+ ConvertValue(*entry, schema.GetItems());
if (converted)
result->Append(std::move(converted));
}
diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc
index 330848c..31dae8e 100644
--- a/components/policy/core/common/schema.cc
+++ b/components/policy/core/common/schema.cc
@@ -619,7 +619,7 @@
int value;
for (base::ListValue::const_iterator it = possible_values->begin();
it != possible_values->end(); ++it) {
- if (!(*it)->GetAsInteger(&value)) {
+ if (!it->GetAsInteger(&value)) {
*error = "Invalid enumeration member type";
return false;
}
@@ -631,7 +631,7 @@
std::string value;
for (base::ListValue::const_iterator it = possible_values->begin();
it != possible_values->end(); ++it) {
- if (!(*it)->GetAsString(&value)) {
+ if (!it->GetAsString(&value)) {
*error = "Invalid enumeration member type";
return false;
}
@@ -826,10 +826,7 @@
} else if (value.GetAsList(&list)) {
for (base::ListValue::const_iterator it = list->begin(); it != list->end();
++it) {
- if (!*it ||
- !GetItems().Validate(**it,
- StrategyForNextLevel(strategy),
- error_path,
+ if (!GetItems().Validate(*it, StrategyForNextLevel(strategy), error_path,
error)) {
// Invalid list item was detected.
AddListIndexPrefixToPath(it - list->begin(), error_path);
diff --git a/dbus/values_util.cc b/dbus/values_util.cc
index 1e035c9..e57380d 100644
--- a/dbus/values_util.cc
+++ b/dbus/values_util.cc
@@ -282,7 +282,7 @@
dbus::MessageWriter array_writer(NULL);
writer->OpenArray("v", &array_writer);
for (const auto& value : *list) {
- AppendValueDataAsVariant(&array_writer, *value);
+ AppendValueDataAsVariant(&array_writer, value);
}
writer->CloseContainer(&array_writer);
break;
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index c17c8be..23cfd13 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -128,7 +128,7 @@
sizer->AddInt();
const base::ListValue* list = static_cast<const base::ListValue*>(value);
for (const auto& entry : *list) {
- GetValueSize(sizer, entry.get(), recursion + 1);
+ GetValueSize(sizer, &entry, recursion + 1);
}
break;
}
@@ -198,7 +198,7 @@
const base::ListValue* list = static_cast<const base::ListValue*>(value);
WriteParam(m, static_cast<int>(list->GetSize()));
for (const auto& entry : *list) {
- WriteValue(m, entry.get(), recursion + 1);
+ WriteValue(m, &entry, recursion + 1);
}
break;
}
diff --git a/mojo/common/values_struct_traits.h b/mojo/common/values_struct_traits.h
index 4139ce6..7d8c2ed 100644
--- a/mojo/common/values_struct_traits.h
+++ b/mojo/common/values_struct_traits.h
@@ -17,7 +17,7 @@
template <>
struct ArrayTraits<base::ListValue> {
- using Element = std::unique_ptr<base::Value>;
+ using Element = base::Value;
using ConstIterator = base::ListValue::const_iterator;
static size_t GetSize(const base::ListValue& input) {