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

Side by Side Diff: base/values.cc

Issue 2000803003: Use std::unique_ptr for base::DictionaryValue and base::ListValue's internal store. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« base/values.h ('K') | « base/values.h ('k') | no next file » | 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 11 matching lines...) Expand all
22 22
23 namespace { 23 namespace {
24 24
25 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node); 25 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
26 26
27 // Make a deep copy of |node|, but don't include empty lists or dictionaries 27 // Make a deep copy of |node|, but don't include empty lists or dictionaries
28 // in the copy. It's possible for this function to return NULL and it 28 // in the copy. It's possible for this function to return NULL and it
29 // expects |node| to always be non-NULL. 29 // expects |node| to always be non-NULL.
30 std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) { 30 std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
31 std::unique_ptr<ListValue> copy; 31 std::unique_ptr<ListValue> copy;
32 for (ListValue::const_iterator it = list.begin(); it != list.end(); ++it) { 32 for (const auto& entry : list) {
33 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(**it); 33 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(*entry);
34 if (child_copy) { 34 if (child_copy) {
35 if (!copy) 35 if (!copy)
36 copy.reset(new ListValue); 36 copy.reset(new ListValue);
37 copy->Append(std::move(child_copy)); 37 copy->Append(std::move(child_copy));
38 } 38 }
39 } 39 }
40 return copy; 40 return copy;
41 } 41 }
42 42
43 std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren( 43 std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
(...skipping 17 matching lines...) Expand all
61 61
62 case Value::TYPE_DICTIONARY: 62 case Value::TYPE_DICTIONARY:
63 return CopyDictionaryWithoutEmptyChildren( 63 return CopyDictionaryWithoutEmptyChildren(
64 static_cast<const DictionaryValue&>(node)); 64 static_cast<const DictionaryValue&>(node));
65 65
66 default: 66 default:
67 return node.CreateDeepCopy(); 67 return node.CreateDeepCopy();
68 } 68 }
69 } 69 }
70 70
71 // A small functor for comparing Values for std::find_if and similar.
72 class ValueEquals {
73 public:
74 // Pass the value against which all consecutive calls of the () operator will
75 // compare their argument to. This Value object must not be destroyed while
76 // the ValueEquals is in use.
77 explicit ValueEquals(const Value* first) : first_(first) { }
78
79 bool operator ()(const Value* second) const {
80 return first_->Equals(second);
81 }
82
83 private:
84 const Value* first_;
85 };
86
87 } // namespace 71 } // namespace
88 72
89 Value::~Value() { 73 Value::~Value() {
90 } 74 }
91 75
92 // static 76 // static
93 std::unique_ptr<Value> Value::CreateNullValue() { 77 std::unique_ptr<Value> Value::CreateNullValue() {
94 return WrapUnique(new Value(TYPE_NULL)); 78 return WrapUnique(new Value(TYPE_NULL));
95 } 79 }
96 80
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 360 }
377 361
378 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const { 362 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
379 if (out_value) 363 if (out_value)
380 *out_value = this; 364 *out_value = this;
381 return true; 365 return true;
382 } 366 }
383 367
384 bool DictionaryValue::HasKey(const std::string& key) const { 368 bool DictionaryValue::HasKey(const std::string& key) const {
385 DCHECK(IsStringUTF8(key)); 369 DCHECK(IsStringUTF8(key));
386 ValueMap::const_iterator current_entry = dictionary_.find(key); 370 auto current_entry = dictionary_.find(key);
387 DCHECK((current_entry == dictionary_.end()) || current_entry->second); 371 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
388 return current_entry != dictionary_.end(); 372 return current_entry != dictionary_.end();
389 } 373 }
390 374
391 void DictionaryValue::Clear() { 375 void DictionaryValue::Clear() {
392 ValueMap::iterator dict_iterator = dictionary_.begin();
393 while (dict_iterator != dictionary_.end()) {
394 delete dict_iterator->second;
395 ++dict_iterator;
396 }
397
398 dictionary_.clear(); 376 dictionary_.clear();
399 } 377 }
400 378
401 void DictionaryValue::Set(const std::string& path, 379 void DictionaryValue::Set(const std::string& path,
402 std::unique_ptr<Value> in_value) { 380 std::unique_ptr<Value> in_value) {
403 DCHECK(IsStringUTF8(path)); 381 DCHECK(IsStringUTF8(path));
404 DCHECK(in_value); 382 DCHECK(in_value);
405 383
406 std::string current_path(path); 384 std::string current_path(path);
407 DictionaryValue* current_dictionary = this; 385 DictionaryValue* current_dictionary = this;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 Set(path, new StringValue(in_value)); 423 Set(path, new StringValue(in_value));
446 } 424 }
447 425
448 void DictionaryValue::SetString(const std::string& path, 426 void DictionaryValue::SetString(const std::string& path,
449 const string16& in_value) { 427 const string16& in_value) {
450 Set(path, new StringValue(in_value)); 428 Set(path, new StringValue(in_value));
451 } 429 }
452 430
453 void DictionaryValue::SetWithoutPathExpansion(const std::string& key, 431 void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
454 std::unique_ptr<Value> in_value) { 432 std::unique_ptr<Value> in_value) {
455 Value* bare_ptr = in_value.release(); 433 dictionary_[key] = std::move(in_value);
456 // If there's an existing value here, we need to delete it, because
457 // we own all our children.
458 std::pair<ValueMap::iterator, bool> ins_res =
459 dictionary_.insert(std::make_pair(key, bare_ptr));
460 if (!ins_res.second) {
461 DCHECK_NE(ins_res.first->second, bare_ptr); // This would be bogus
462 delete ins_res.first->second;
463 ins_res.first->second = bare_ptr;
464 }
465 } 434 }
466 435
467 void DictionaryValue::SetWithoutPathExpansion(const std::string& key, 436 void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
468 Value* in_value) { 437 Value* in_value) {
469 SetWithoutPathExpansion(key, WrapUnique(in_value)); 438 SetWithoutPathExpansion(key, WrapUnique(in_value));
470 } 439 }
471 440
472 void DictionaryValue::SetBooleanWithoutPathExpansion( 441 void DictionaryValue::SetBooleanWithoutPathExpansion(
473 const std::string& path, bool in_value) { 442 const std::string& path, bool in_value) {
474 SetWithoutPathExpansion(path, new FundamentalValue(in_value)); 443 SetWithoutPathExpansion(path, new FundamentalValue(in_value));
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 607
639 bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) { 608 bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
640 return static_cast<const DictionaryValue&>(*this).GetList( 609 return static_cast<const DictionaryValue&>(*this).GetList(
641 path, 610 path,
642 const_cast<const ListValue**>(out_value)); 611 const_cast<const ListValue**>(out_value));
643 } 612 }
644 613
645 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key, 614 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
646 const Value** out_value) const { 615 const Value** out_value) const {
647 DCHECK(IsStringUTF8(key)); 616 DCHECK(IsStringUTF8(key));
648 ValueMap::const_iterator entry_iterator = dictionary_.find(key); 617 auto entry_iterator = dictionary_.find(key);
649 if (entry_iterator == dictionary_.end()) 618 if (entry_iterator == dictionary_.end())
650 return false; 619 return false;
651 620
652 const Value* entry = entry_iterator->second;
653 if (out_value) 621 if (out_value)
654 *out_value = entry; 622 *out_value = entry_iterator->second.get();
655 return true; 623 return true;
656 } 624 }
657 625
658 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key, 626 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
659 Value** out_value) { 627 Value** out_value) {
660 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion( 628 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
661 key, 629 key,
662 const_cast<const Value**>(out_value)); 630 const_cast<const Value**>(out_value));
663 } 631 }
664 632
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 } 736 }
769 737
770 return current_dictionary->RemoveWithoutPathExpansion(current_path, 738 return current_dictionary->RemoveWithoutPathExpansion(current_path,
771 out_value); 739 out_value);
772 } 740 }
773 741
774 bool DictionaryValue::RemoveWithoutPathExpansion( 742 bool DictionaryValue::RemoveWithoutPathExpansion(
775 const std::string& key, 743 const std::string& key,
776 std::unique_ptr<Value>* out_value) { 744 std::unique_ptr<Value>* out_value) {
777 DCHECK(IsStringUTF8(key)); 745 DCHECK(IsStringUTF8(key));
778 ValueMap::iterator entry_iterator = dictionary_.find(key); 746 auto entry_iterator = dictionary_.find(key);
779 if (entry_iterator == dictionary_.end()) 747 if (entry_iterator == dictionary_.end())
780 return false; 748 return false;
781 749
782 Value* entry = entry_iterator->second;
783 if (out_value) 750 if (out_value)
784 out_value->reset(entry); 751 *out_value = std::move(entry_iterator->second);
785 else
786 delete entry;
787 dictionary_.erase(entry_iterator); 752 dictionary_.erase(entry_iterator);
788 return true; 753 return true;
789 } 754 }
790 755
791 bool DictionaryValue::RemovePath(const std::string& path, 756 bool DictionaryValue::RemovePath(const std::string& path,
792 std::unique_ptr<Value>* out_value) { 757 std::unique_ptr<Value>* out_value) {
793 bool result = false; 758 bool result = false;
794 size_t delimiter_position = path.find('.'); 759 size_t delimiter_position = path.find('.');
795 760
796 if (delimiter_position == std::string::npos) 761 if (delimiter_position == std::string::npos)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 : target_(target), 807 : target_(target),
843 it_(target.dictionary_.begin()) {} 808 it_(target.dictionary_.begin()) {}
844 809
845 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; 810 DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
846 811
847 DictionaryValue::Iterator::~Iterator() {} 812 DictionaryValue::Iterator::~Iterator() {}
848 813
849 DictionaryValue* DictionaryValue::DeepCopy() const { 814 DictionaryValue* DictionaryValue::DeepCopy() const {
850 DictionaryValue* result = new DictionaryValue; 815 DictionaryValue* result = new DictionaryValue;
851 816
852 for (ValueMap::const_iterator current_entry(dictionary_.begin()); 817 for (const auto& current_entry : dictionary_) {
853 current_entry != dictionary_.end(); ++current_entry) { 818 result->SetWithoutPathExpansion(current_entry.first,
854 result->SetWithoutPathExpansion(current_entry->first, 819 current_entry.second->CreateDeepCopy());
855 current_entry->second->DeepCopy());
856 } 820 }
857 821
858 return result; 822 return result;
859 } 823 }
860 824
861 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { 825 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
862 return WrapUnique(DeepCopy()); 826 return WrapUnique(DeepCopy());
863 } 827 }
864 828
865 bool DictionaryValue::Equals(const Value* other) const { 829 bool DictionaryValue::Equals(const Value* other) const {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 861 }
898 862
899 ListValue::ListValue() : Value(TYPE_LIST) { 863 ListValue::ListValue() : Value(TYPE_LIST) {
900 } 864 }
901 865
902 ListValue::~ListValue() { 866 ListValue::~ListValue() {
903 Clear(); 867 Clear();
904 } 868 }
905 869
906 void ListValue::Clear() { 870 void ListValue::Clear() {
907 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
908 delete *i;
909 list_.clear(); 871 list_.clear();
910 } 872 }
911 873
912 bool ListValue::Set(size_t index, Value* in_value) { 874 bool ListValue::Set(size_t index, Value* in_value) {
875 return Set(index, base::WrapUnique(in_value));
dcheng 2016/05/20 19:49:47 I changed a few of the obvious things I touched so
danakj 2016/05/20 20:51:38 nit: no base:: in base
dcheng 2016/05/20 22:41:55 Done.
876 }
877
878 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
913 if (!in_value) 879 if (!in_value)
914 return false; 880 return false;
915 881
916 if (index >= list_.size()) { 882 if (index >= list_.size()) {
917 // Pad out any intermediate indexes with null settings 883 // Pad out any intermediate indexes with null settings
918 while (index > list_.size()) 884 while (index > list_.size())
919 Append(CreateNullValue()); 885 Append(CreateNullValue());
920 Append(in_value); 886 Append(std::move(in_value));
921 } else { 887 } else {
888 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed?
922 DCHECK(list_[index] != in_value); 889 DCHECK(list_[index] != in_value);
923 delete list_[index]; 890 list_[index] = std::move(in_value);
924 list_[index] = in_value;
925 } 891 }
926 return true; 892 return true;
927 } 893 }
928 894
929 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
930 return Set(index, in_value.release());
931 }
932
933 bool ListValue::Get(size_t index, const Value** out_value) const { 895 bool ListValue::Get(size_t index, const Value** out_value) const {
934 if (index >= list_.size()) 896 if (index >= list_.size())
935 return false; 897 return false;
936 898
937 if (out_value) 899 if (out_value)
938 *out_value = list_[index]; 900 *out_value = list_[index].get();
939 901
940 return true; 902 return true;
941 } 903 }
942 904
943 bool ListValue::Get(size_t index, Value** out_value) { 905 bool ListValue::Get(size_t index, Value** out_value) {
944 return static_cast<const ListValue&>(*this).Get( 906 return static_cast<const ListValue&>(*this).Get(
945 index, 907 index,
946 const_cast<const Value**>(out_value)); 908 const_cast<const Value**>(out_value));
947 } 909 }
948 910
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 return static_cast<const ListValue&>(*this).GetList( 1001 return static_cast<const ListValue&>(*this).GetList(
1040 index, 1002 index,
1041 const_cast<const ListValue**>(out_value)); 1003 const_cast<const ListValue**>(out_value));
1042 } 1004 }
1043 1005
1044 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { 1006 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1045 if (index >= list_.size()) 1007 if (index >= list_.size())
1046 return false; 1008 return false;
1047 1009
1048 if (out_value) 1010 if (out_value)
1049 out_value->reset(list_[index]); 1011 *out_value = std::move(list_[index]);
1050 else
1051 delete list_[index];
1052 1012
1053 list_.erase(list_.begin() + index); 1013 list_.erase(list_.begin() + index);
1054 return true; 1014 return true;
1055 } 1015 }
1056 1016
1057 bool ListValue::Remove(const Value& value, size_t* index) { 1017 bool ListValue::Remove(const Value& value, size_t* index) {
1058 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) { 1018 for (auto it = list_.begin(); it != list_.end(); ++it) {
1059 if ((*i)->Equals(&value)) { 1019 if ((*it)->Equals(&value)) {
1060 size_t previous_index = i - list_.begin(); 1020 size_t previous_index = it - list_.begin();
1061 delete *i; 1021 list_.erase(it);
1062 list_.erase(i);
1063 1022
1064 if (index) 1023 if (index)
1065 *index = previous_index; 1024 *index = previous_index;
1066 return true; 1025 return true;
1067 } 1026 }
1068 } 1027 }
1069 return false; 1028 return false;
1070 } 1029 }
1071 1030
1072 ListValue::iterator ListValue::Erase(iterator iter, 1031 ListValue::iterator ListValue::Erase(iterator iter,
1073 std::unique_ptr<Value>* out_value) { 1032 std::unique_ptr<Value>* out_value) {
1074 if (out_value) 1033 if (out_value)
1075 out_value->reset(*iter); 1034 out_value->reset(*iter);
1076 else 1035 else
1077 delete *iter; 1036 delete *iter;
1078 1037
1079 return list_.erase(iter); 1038 return list_.erase(iter);
1080 } 1039 }
1081 1040
1082 void ListValue::Append(std::unique_ptr<Value> in_value) { 1041 void ListValue::Append(std::unique_ptr<Value> in_value) {
1083 Append(in_value.release()); 1042 list_.emplace_back(std::move(in_value));
1084 } 1043 }
1085 1044
1086 void ListValue::Append(Value* in_value) { 1045 void ListValue::Append(Value* in_value) {
1087 DCHECK(in_value); 1046 DCHECK(in_value);
1088 list_.push_back(in_value); 1047 Append(base::WrapUnique(in_value));
1089 } 1048 }
1090 1049
1091 void ListValue::AppendBoolean(bool in_value) { 1050 void ListValue::AppendBoolean(bool in_value) {
1092 Append(new FundamentalValue(in_value)); 1051 Append(new FundamentalValue(in_value));
1093 } 1052 }
1094 1053
1095 void ListValue::AppendInteger(int in_value) { 1054 void ListValue::AppendInteger(int in_value) {
1096 Append(new FundamentalValue(in_value)); 1055 Append(new FundamentalValue(in_value));
1097 } 1056 }
1098 1057
(...skipping 18 matching lines...) Expand all
1117 1076
1118 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1077 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1119 for (std::vector<string16>::const_iterator it = in_values.begin(); 1078 for (std::vector<string16>::const_iterator it = in_values.begin();
1120 it != in_values.end(); ++it) { 1079 it != in_values.end(); ++it) {
1121 AppendString(*it); 1080 AppendString(*it);
1122 } 1081 }
1123 } 1082 }
1124 1083
1125 bool ListValue::AppendIfNotPresent(Value* in_value) { 1084 bool ListValue::AppendIfNotPresent(Value* in_value) {
1126 DCHECK(in_value); 1085 DCHECK(in_value);
1127 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) { 1086 for (const auto& entry : list_) {
1128 if ((*i)->Equals(in_value)) { 1087 if (entry->Equals(in_value)) {
1129 delete in_value; 1088 delete in_value;
1130 return false; 1089 return false;
1131 } 1090 }
1132 } 1091 }
1133 list_.push_back(in_value); 1092 list_.emplace_back(in_value);
1134 return true; 1093 return true;
1135 } 1094 }
1136 1095
1137 bool ListValue::Insert(size_t index, Value* in_value) { 1096 bool ListValue::Insert(size_t index, Value* in_value) {
1138 DCHECK(in_value); 1097 DCHECK(in_value);
1139 if (index > list_.size()) 1098 if (index > list_.size())
1140 return false; 1099 return false;
1141 1100
1142 list_.insert(list_.begin() + index, in_value); 1101 list_.insert(list_.begin() + index, base::WrapUnique(in_value));
danakj 2016/05/20 20:51:38 nit -base::
dcheng 2016/05/20 22:41:55 Done.
1143 return true; 1102 return true;
1144 } 1103 }
1145 1104
1146 ListValue::const_iterator ListValue::Find(const Value& value) const { 1105 ListValue::const_iterator ListValue::Find(const Value& value) const {
1147 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value)); 1106 return std::find_if(list_.begin(), list_.end(),
1107 [&value](const std::unique_ptr<Value>& entry) {
1108 return entry->Equals(&value);
1109 });
1148 } 1110 }
1149 1111
1150 void ListValue::Swap(ListValue* other) { 1112 void ListValue::Swap(ListValue* other) {
1151 list_.swap(other->list_); 1113 list_.swap(other->list_);
1152 } 1114 }
1153 1115
1154 bool ListValue::GetAsList(ListValue** out_value) { 1116 bool ListValue::GetAsList(ListValue** out_value) {
1155 if (out_value) 1117 if (out_value)
1156 *out_value = this; 1118 *out_value = this;
1157 return true; 1119 return true;
1158 } 1120 }
1159 1121
1160 bool ListValue::GetAsList(const ListValue** out_value) const { 1122 bool ListValue::GetAsList(const ListValue** out_value) const {
1161 if (out_value) 1123 if (out_value)
1162 *out_value = this; 1124 *out_value = this;
1163 return true; 1125 return true;
1164 } 1126 }
1165 1127
1166 ListValue* ListValue::DeepCopy() const { 1128 ListValue* ListValue::DeepCopy() const {
1167 ListValue* result = new ListValue; 1129 ListValue* result = new ListValue;
1168 1130
1169 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) 1131 for (const auto& entry : list_)
1170 result->Append((*i)->DeepCopy()); 1132 result->Append(entry->CreateDeepCopy());
1171 1133
1172 return result; 1134 return result;
1173 } 1135 }
1174 1136
1175 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { 1137 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
1176 return WrapUnique(DeepCopy()); 1138 return WrapUnique(DeepCopy());
1177 } 1139 }
1178 1140
1179 bool ListValue::Equals(const Value* other) const { 1141 bool ListValue::Equals(const Value* other) const {
1180 if (other->GetType() != GetType()) 1142 if (other->GetType() != GetType())
1181 return false; 1143 return false;
1182 1144
1183 const ListValue* other_list = 1145 const ListValue* other_list =
1184 static_cast<const ListValue*>(other); 1146 static_cast<const ListValue*>(other);
1185 const_iterator lhs_it, rhs_it; 1147 Storage::const_iterator lhs_it, rhs_it;
1186 for (lhs_it = begin(), rhs_it = other_list->begin(); 1148 for (lhs_it = begin(), rhs_it = other_list->begin();
1187 lhs_it != end() && rhs_it != other_list->end(); 1149 lhs_it != end() && rhs_it != other_list->end();
1188 ++lhs_it, ++rhs_it) { 1150 ++lhs_it, ++rhs_it) {
1189 if (!(*lhs_it)->Equals(*rhs_it)) 1151 if (!(*lhs_it)->Equals(&**rhs_it))
danakj 2016/05/20 20:51:38 lol.. how about using &rhs_it->get() idk if that's
dcheng 2016/05/20 22:41:54 Hmm. I have no idea why I thought this was a usefu
1190 return false; 1152 return false;
1191 } 1153 }
1192 if (lhs_it != end() || rhs_it != other_list->end()) 1154 if (lhs_it != end() || rhs_it != other_list->end())
1193 return false; 1155 return false;
1194 1156
1195 return true; 1157 return true;
1196 } 1158 }
1197 1159
1198 ValueSerializer::~ValueSerializer() { 1160 ValueSerializer::~ValueSerializer() {
1199 } 1161 }
1200 1162
1201 ValueDeserializer::~ValueDeserializer() { 1163 ValueDeserializer::~ValueDeserializer() {
1202 } 1164 }
1203 1165
1204 std::ostream& operator<<(std::ostream& out, const Value& value) { 1166 std::ostream& operator<<(std::ostream& out, const Value& value) {
1205 std::string json; 1167 std::string json;
1206 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); 1168 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1207 return out << json; 1169 return out << json;
1208 } 1170 }
1209 1171
1210 } // namespace base 1172 } // namespace base
OLDNEW
« base/values.h ('K') | « base/values.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698