Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: base/values.cc

Issue 2781983003: Deprecate Value::(Create)DeepCopy (Closed)
Patch Set: Braces Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/values.h" 5 #include "base/values.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) { 62 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
63 switch (node.GetType()) { 63 switch (node.GetType()) {
64 case Value::Type::LIST: 64 case Value::Type::LIST:
65 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node)); 65 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
66 66
67 case Value::Type::DICTIONARY: 67 case Value::Type::DICTIONARY:
68 return CopyDictionaryWithoutEmptyChildren( 68 return CopyDictionaryWithoutEmptyChildren(
69 static_cast<const DictionaryValue&>(node)); 69 static_cast<const DictionaryValue&>(node));
70 70
71 default: 71 default:
72 return node.CreateDeepCopy(); 72 return MakeUnique<Value>(node);
73 } 73 }
74 } 74 }
75 75
76 } // namespace 76 } // namespace
77 77
78 // static 78 // static
79 std::unique_ptr<Value> Value::CreateNullValue() { 79 std::unique_ptr<Value> Value::CreateNullValue() {
80 return WrapUnique(new Value(Type::NONE)); 80 return WrapUnique(new Value(Type::NONE));
81 } 81 }
82 82
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 334
335 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 335 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
336 if (out_value && is_dict()) { 336 if (out_value && is_dict()) {
337 *out_value = static_cast<const DictionaryValue*>(this); 337 *out_value = static_cast<const DictionaryValue*>(this);
338 return true; 338 return true;
339 } 339 }
340 return is_dict(); 340 return is_dict();
341 } 341 }
342 342
343 Value* Value::DeepCopy() const { 343 Value* Value::DeepCopy() const {
344 // This method should only be getting called for null Values--all subclasses 344 return new Value(*this);
345 // need to provide their own implementation;.
346 switch (type()) {
347 case Type::NONE:
348 return CreateNullValue().release();
349
350 case Type::BOOLEAN:
351 return new Value(bool_value_);
352 case Type::INTEGER:
353 return new Value(int_value_);
354 case Type::DOUBLE:
355 return new Value(double_value_);
356 case Type::STRING:
357 return new Value(*string_value_);
358 // For now, make BinaryValues for backward-compatibility. Convert to
359 // Value when that code is deleted.
360 case Type::BINARY:
361 return new Value(*binary_value_);
362
363 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
364 // are completely inlined.
365 case Type::DICTIONARY: {
366 DictionaryValue* result = new DictionaryValue;
367
368 for (const auto& current_entry : **dict_ptr_) {
369 result->SetWithoutPathExpansion(current_entry.first,
370 current_entry.second->CreateDeepCopy());
371 }
372
373 return result;
374 }
375
376 case Type::LIST: {
377 ListValue* result = new ListValue;
378
379 for (const auto& entry : *list_)
380 result->Append(entry->CreateDeepCopy());
381
382 return result;
383 }
384
385 default:
386 NOTREACHED();
387 return nullptr;
388 }
389 } 345 }
390 346
391 std::unique_ptr<Value> Value::CreateDeepCopy() const { 347 std::unique_ptr<Value> Value::CreateDeepCopy() const {
392 return WrapUnique(DeepCopy()); 348 return MakeUnique<Value>(*this);
393 } 349 }
394 350
395 bool operator==(const Value& lhs, const Value& rhs) { 351 bool operator==(const Value& lhs, const Value& rhs) {
396 if (lhs.type_ != rhs.type_) 352 if (lhs.type_ != rhs.type_)
397 return false; 353 return false;
398 354
399 switch (lhs.type_) { 355 switch (lhs.type_) {
400 case Value::Type::NONE: 356 case Value::Type::NONE:
401 return true; 357 return true;
402 case Value::Type::BOOLEAN: 358 case Value::Type::BOOLEAN:
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 InternalCopyFundamentalValue(that); 491 InternalCopyFundamentalValue(that);
536 return; 492 return;
537 493
538 case Type::STRING: 494 case Type::STRING:
539 string_value_.Init(*that.string_value_); 495 string_value_.Init(*that.string_value_);
540 return; 496 return;
541 case Type::BINARY: 497 case Type::BINARY:
542 binary_value_.Init(*that.binary_value_); 498 binary_value_.Init(*that.binary_value_);
543 return; 499 return;
544 // DictStorage and ListStorage are move-only types due to the presence of 500 // DictStorage and ListStorage are move-only types due to the presence of
545 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 501 // unique_ptrs. This is why the explicit copy of every element is necessary
502 // here.
546 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 503 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
547 // can be copied directly. 504 // can be copied directly.
548 case Type::DICTIONARY: 505 case Type::DICTIONARY:
549 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); 506 dict_ptr_.Init(MakeUnique<DictStorage>());
507 for (const auto& it : **that.dict_ptr_) {
508 (*dict_ptr_)
509 ->emplace_hint((*dict_ptr_)->end(), it.first,
510 MakeUnique<Value>(*it.second));
511 }
550 return; 512 return;
551 case Type::LIST: 513 case Type::LIST:
552 list_.Init(std::move(*that.CreateDeepCopy()->list_)); 514 list_.Init();
515 list_->reserve(that.list_->size());
516 for (const auto& it : *that.list_)
517 list_->push_back(MakeUnique<Value>(*it));
553 return; 518 return;
554 } 519 }
555 } 520 }
556 521
557 void Value::InternalMoveConstructFrom(Value&& that) { 522 void Value::InternalMoveConstructFrom(Value&& that) {
558 type_ = that.type_; 523 type_ = that.type_;
559 524
560 switch (type_) { 525 switch (type_) {
561 case Type::NONE: 526 case Type::NONE:
562 case Type::BOOLEAN: 527 case Type::BOOLEAN:
(...skipping 30 matching lines...) Expand all
593 InternalCopyFundamentalValue(that); 558 InternalCopyFundamentalValue(that);
594 return; 559 return;
595 560
596 case Type::STRING: 561 case Type::STRING:
597 *string_value_ = *that.string_value_; 562 *string_value_ = *that.string_value_;
598 return; 563 return;
599 case Type::BINARY: 564 case Type::BINARY:
600 *binary_value_ = *that.binary_value_; 565 *binary_value_ = *that.binary_value_;
601 return; 566 return;
602 // DictStorage and ListStorage are move-only types due to the presence of 567 // DictStorage and ListStorage are move-only types due to the presence of
603 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 568 // unique_ptrs. This is why the explicit call to the copy constructor is
569 // necessary here.
604 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 570 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
605 // can be copied directly. 571 // can be copied directly.
606 case Type::DICTIONARY: 572 case Type::DICTIONARY:
607 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); 573 *dict_ptr_ = std::move(*Value(that).dict_ptr_);
608 return; 574 return;
609 case Type::LIST: 575 case Type::LIST:
610 *list_ = std::move(*that.CreateDeepCopy()->list_); 576 *list_ = std::move(*Value(that).list_);
611 return; 577 return;
612 } 578 }
613 } 579 }
614 580
615 void Value::InternalCleanup() { 581 void Value::InternalCleanup() {
616 switch (type_) { 582 switch (type_) {
617 case Type::NONE: 583 case Type::NONE:
618 case Type::BOOLEAN: 584 case Type::BOOLEAN:
619 case Type::INTEGER: 585 case Type::INTEGER:
620 case Type::DOUBLE: 586 case Type::DOUBLE:
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 // Check whether we have to merge dictionaries. 1032 // Check whether we have to merge dictionaries.
1067 if (merge_value->IsType(Value::Type::DICTIONARY)) { 1033 if (merge_value->IsType(Value::Type::DICTIONARY)) {
1068 DictionaryValue* sub_dict; 1034 DictionaryValue* sub_dict;
1069 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { 1035 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
1070 sub_dict->MergeDictionary( 1036 sub_dict->MergeDictionary(
1071 static_cast<const DictionaryValue*>(merge_value)); 1037 static_cast<const DictionaryValue*>(merge_value));
1072 continue; 1038 continue;
1073 } 1039 }
1074 } 1040 }
1075 // All other cases: Make a copy and hook it up. 1041 // All other cases: Make a copy and hook it up.
1076 SetWithoutPathExpansion(it.key(), 1042 SetWithoutPathExpansion(it.key(), MakeUnique<Value>(*merge_value));
1077 base::WrapUnique(merge_value->DeepCopy()));
1078 } 1043 }
1079 } 1044 }
1080 1045
1081 void DictionaryValue::Swap(DictionaryValue* other) { 1046 void DictionaryValue::Swap(DictionaryValue* other) {
1082 CHECK(other->is_dict()); 1047 CHECK(other->is_dict());
1083 dict_ptr_->swap(*(other->dict_ptr_)); 1048 dict_ptr_->swap(*(other->dict_ptr_));
1084 } 1049 }
1085 1050
1086 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) 1051 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
1087 : target_(target), it_((*target.dict_ptr_)->begin()) {} 1052 : target_(target), it_((*target.dict_ptr_)->begin()) {}
1088 1053
1089 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; 1054 DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
1090 1055
1091 DictionaryValue::Iterator::~Iterator() {} 1056 DictionaryValue::Iterator::~Iterator() {}
1092 1057
1093 DictionaryValue* DictionaryValue::DeepCopy() const { 1058 DictionaryValue* DictionaryValue::DeepCopy() const {
1094 return static_cast<DictionaryValue*>(Value::DeepCopy()); 1059 return new DictionaryValue(*this);
1095 } 1060 }
1096 1061
1097 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { 1062 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
1098 return WrapUnique(DeepCopy()); 1063 return MakeUnique<DictionaryValue>(*this);
1099 } 1064 }
1100 1065
1101 ///////////////////// ListValue //////////////////// 1066 ///////////////////// ListValue ////////////////////
1102 1067
1103 // static 1068 // static
1104 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { 1069 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
1105 ListValue* out; 1070 ListValue* out;
1106 if (value && value->GetAsList(&out)) { 1071 if (value && value->GetAsList(&out)) {
1107 ignore_result(value.release()); 1072 ignore_result(value.release());
1108 return WrapUnique(out); 1073 return WrapUnique(out);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 return *entry == value; 1316 return *entry == value;
1352 }); 1317 });
1353 } 1318 }
1354 1319
1355 void ListValue::Swap(ListValue* other) { 1320 void ListValue::Swap(ListValue* other) {
1356 CHECK(other->is_list()); 1321 CHECK(other->is_list());
1357 list_->swap(*(other->list_)); 1322 list_->swap(*(other->list_));
1358 } 1323 }
1359 1324
1360 ListValue* ListValue::DeepCopy() const { 1325 ListValue* ListValue::DeepCopy() const {
1361 return static_cast<ListValue*>(Value::DeepCopy()); 1326 return new ListValue(*this);
1362 } 1327 }
1363 1328
1364 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { 1329 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
1365 return WrapUnique(DeepCopy()); 1330 return MakeUnique<ListValue>(*this);
1366 } 1331 }
1367 1332
1368 ValueSerializer::~ValueSerializer() { 1333 ValueSerializer::~ValueSerializer() {
1369 } 1334 }
1370 1335
1371 ValueDeserializer::~ValueDeserializer() { 1336 ValueDeserializer::~ValueDeserializer() {
1372 } 1337 }
1373 1338
1374 std::ostream& operator<<(std::ostream& out, const Value& value) { 1339 std::ostream& operator<<(std::ostream& out, const Value& value) {
1375 std::string json; 1340 std::string json;
1376 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); 1341 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1377 return out << json; 1342 return out << json;
1378 } 1343 }
1379 1344
1380 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1345 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1381 if (static_cast<int>(type) < 0 || 1346 if (static_cast<int>(type) < 0 ||
1382 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1347 static_cast<size_t>(type) >= arraysize(kTypeNames))
1383 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1348 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1384 return out << Value::GetTypeName(type); 1349 return out << Value::GetTypeName(type);
1385 } 1350 }
1386 1351
1387 } // namespace base 1352 } // namespace base
OLDNEW
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698