summaryrefslogtreecommitdiff
path: root/base/values.cc
diff options
context:
space:
mode:
Diffstat (limited to 'base/values.cc')
-rw-r--r--base/values.cc91
1 files changed, 28 insertions, 63 deletions
diff --git a/base/values.cc b/base/values.cc
index fa90a57dbb..b5e44e68dd 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -69,7 +69,7 @@ std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
static_cast<const DictionaryValue&>(node));
default:
- return node.CreateDeepCopy();
+ return MakeUnique<Value>(node);
}
}
@@ -95,7 +95,7 @@ Value::Value(Value&& that) noexcept {
InternalMoveConstructFrom(std::move(that));
}
-Value::Value() : type_(Type::NONE) {}
+Value::Value() noexcept : type_(Type::NONE) {}
Value::Value(Type type) : type_(type) {
// Initialize with the default value.
@@ -149,7 +149,7 @@ Value::Value(const std::string& in_string) : type_(Type::STRING) {
DCHECK(IsStringUTF8(*string_value_));
}
-Value::Value(std::string&& in_string) : type_(Type::STRING) {
+Value::Value(std::string&& in_string) noexcept : type_(Type::STRING) {
string_value_.Init(std::move(in_string));
DCHECK(IsStringUTF8(*string_value_));
}
@@ -168,7 +168,7 @@ Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
binary_value_.Init(in_blob);
}
-Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) {
+Value::Value(std::vector<char>&& in_blob) noexcept : type_(Type::BINARY) {
binary_value_.Init(std::move(in_blob));
}
@@ -184,7 +184,7 @@ Value& Value::operator=(const Value& that) {
return *this;
}
-Value& Value::operator=(Value&& that) {
+Value& Value::operator=(Value&& that) noexcept {
DCHECK(this != &that) << "attempt to self move assign.";
InternalCleanup();
InternalMoveConstructFrom(std::move(that));
@@ -341,55 +341,11 @@ bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
}
Value* Value::DeepCopy() const {
- // This method should only be getting called for null Values--all subclasses
- // need to provide their own implementation;.
- switch (type()) {
- case Type::NONE:
- return CreateNullValue().release();
-
- case Type::BOOLEAN:
- return new Value(bool_value_);
- case Type::INTEGER:
- return new Value(int_value_);
- case Type::DOUBLE:
- return new Value(double_value_);
- case Type::STRING:
- return new Value(*string_value_);
- // For now, make BinaryValues for backward-compatibility. Convert to
- // Value when that code is deleted.
- case Type::BINARY:
- return new Value(*binary_value_);
-
- // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
- // are completely inlined.
- case Type::DICTIONARY: {
- DictionaryValue* result = new DictionaryValue;
-
- for (const auto& current_entry : **dict_ptr_) {
- result->SetWithoutPathExpansion(current_entry.first,
- current_entry.second->CreateDeepCopy());
- }
-
- return result;
- }
-
- case Type::LIST: {
- ListValue* result = new ListValue;
-
- for (const auto& entry : *list_)
- result->Append(entry->CreateDeepCopy());
-
- return result;
- }
-
- default:
- NOTREACHED();
- return nullptr;
- }
+ return new Value(*this);
}
std::unique_ptr<Value> Value::CreateDeepCopy() const {
- return WrapUnique(DeepCopy());
+ return MakeUnique<Value>(*this);
}
bool operator==(const Value& lhs, const Value& rhs) {
@@ -542,14 +498,23 @@ void Value::InternalCopyConstructFrom(const Value& that) {
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 call to |CreateDeepCopy| is necessary here.
+ // 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.
case Type::DICTIONARY:
- dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_));
+ dict_ptr_.Init(MakeUnique<DictStorage>());
+ for (const auto& it : **that.dict_ptr_) {
+ (*dict_ptr_)
+ ->emplace_hint((*dict_ptr_)->end(), it.first,
+ MakeUnique<Value>(*it.second));
+ }
return;
case Type::LIST:
- list_.Init(std::move(*that.CreateDeepCopy()->list_));
+ list_.Init();
+ list_->reserve(that.list_->size());
+ for (const auto& it : *that.list_)
+ list_->push_back(MakeUnique<Value>(*it));
return;
}
}
@@ -600,14 +565,15 @@ void Value::InternalCopyAssignFromSameType(const Value& that) {
*binary_value_ = *that.binary_value_;
return;
// DictStorage and ListStorage are move-only types due to the presence of
- // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here.
+ // 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(*that.CreateDeepCopy()->dict_ptr_);
+ *dict_ptr_ = std::move(*Value(that).dict_ptr_);
return;
case Type::LIST:
- *list_ = std::move(*that.CreateDeepCopy()->list_);
+ *list_ = std::move(*Value(that).list_);
return;
}
}
@@ -1073,8 +1039,7 @@ void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
}
}
// All other cases: Make a copy and hook it up.
- SetWithoutPathExpansion(it.key(),
- base::WrapUnique(merge_value->DeepCopy()));
+ SetWithoutPathExpansion(it.key(), MakeUnique<Value>(*merge_value));
}
}
@@ -1091,11 +1056,11 @@ DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
DictionaryValue::Iterator::~Iterator() {}
DictionaryValue* DictionaryValue::DeepCopy() const {
- return static_cast<DictionaryValue*>(Value::DeepCopy());
+ return new DictionaryValue(*this);
}
std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
- return WrapUnique(DeepCopy());
+ return MakeUnique<DictionaryValue>(*this);
}
///////////////////// ListValue ////////////////////
@@ -1358,11 +1323,11 @@ void ListValue::Swap(ListValue* other) {
}
ListValue* ListValue::DeepCopy() const {
- return static_cast<ListValue*>(Value::DeepCopy());
+ return new ListValue(*this);
}
std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
- return WrapUnique(DeepCopy());
+ return MakeUnique<ListValue>(*this);
}
ValueSerializer::~ValueSerializer() {