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

Side by Side Diff: base/values.cc

Issue 2740143002: Change base::Value::ListStorage to std::vector<base::Value> (Closed)
Patch Set: Comment Updates Created 3 years, 9 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
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 17 matching lines...) Expand all
28 "kTypeNames Has Wrong Size"); 28 "kTypeNames Has Wrong Size");
29 29
30 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node); 30 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
31 31
32 // Make a deep copy of |node|, but don't include empty lists or dictionaries 32 // Make a deep copy of |node|, but don't include empty lists or dictionaries
33 // in the copy. It's possible for this function to return NULL and it 33 // in the copy. It's possible for this function to return NULL and it
34 // expects |node| to always be non-NULL. 34 // expects |node| to always be non-NULL.
35 std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) { 35 std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
36 std::unique_ptr<ListValue> copy; 36 std::unique_ptr<ListValue> copy;
37 for (const auto& entry : list) { 37 for (const auto& entry : list) {
38 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(*entry); 38 std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(entry);
39 if (child_copy) { 39 if (child_copy) {
40 if (!copy) 40 if (!copy)
41 copy.reset(new ListValue); 41 copy.reset(new ListValue);
42 copy->Append(std::move(child_copy)); 42 copy->Append(std::move(child_copy));
43 } 43 }
44 } 44 }
45 return copy; 45 return copy;
46 } 46 }
47 47
48 std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren( 48 std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} 165 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {}
166 166
167 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) { 167 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
168 binary_value_.Init(in_blob); 168 binary_value_.Init(in_blob);
169 } 169 }
170 170
171 Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) { 171 Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) {
172 binary_value_.Init(std::move(in_blob)); 172 binary_value_.Init(std::move(in_blob));
173 } 173 }
174 174
175 Value::Value(const ListStorage& in_list) : type_(Type::LIST) {
176 list_.Init(in_list);
177 }
178
179 Value::Value(ListStorage&& in_list) : type_(Type::LIST) {
180 list_.Init(std::move(in_list));
181 }
182
175 Value& Value::operator=(const Value& that) { 183 Value& Value::operator=(const Value& that) {
176 if (this != &that) { 184 if (this != &that) {
177 if (type_ == that.type_) { 185 if (type_ == that.type_) {
178 InternalCopyAssignFromSameType(that); 186 InternalCopyAssignFromSameType(that);
179 } else { 187 } else {
180 InternalCleanup(); 188 InternalCleanup();
181 InternalCopyConstructFrom(that); 189 InternalCopyConstructFrom(that);
182 } 190 }
183 } 191 }
184 192
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 DictionaryValue* result = new DictionaryValue; 381 DictionaryValue* result = new DictionaryValue;
374 382
375 for (const auto& current_entry : **dict_ptr_) { 383 for (const auto& current_entry : **dict_ptr_) {
376 result->SetWithoutPathExpansion(current_entry.first, 384 result->SetWithoutPathExpansion(current_entry.first,
377 current_entry.second->CreateDeepCopy()); 385 current_entry.second->CreateDeepCopy());
378 } 386 }
379 387
380 return result; 388 return result;
381 } 389 }
382 390
383 case Type::LIST: { 391 case Type::LIST:
384 ListValue* result = new ListValue; 392 return new Value(*list_);
385
386 for (const auto& entry : *list_)
387 result->Append(entry->CreateDeepCopy());
388
389 return result;
390 }
391 393
392 default: 394 default:
393 NOTREACHED(); 395 NOTREACHED();
394 return nullptr; 396 return nullptr;
395 } 397 }
396 } 398 }
397 399
398 std::unique_ptr<Value> Value::CreateDeepCopy() const { 400 std::unique_ptr<Value> Value::CreateDeepCopy() const {
399 return WrapUnique(DeepCopy()); 401 return WrapUnique(DeepCopy());
400 } 402 }
(...skipping 28 matching lines...) Expand all
429 if (lhs.first != rhs.first) 431 if (lhs.first != rhs.first)
430 return false; 432 return false;
431 433
432 return lhs.second->Equals(rhs.second.get()); 434 return lhs.second->Equals(rhs.second.get());
433 }); 435 });
434 } 436 }
435 case Type::LIST: { 437 case Type::LIST: {
436 if (list_->size() != other->list_->size()) 438 if (list_->size() != other->list_->size())
437 return false; 439 return false;
438 440
439 return std::equal(std::begin(*list_), std::end(*list_), 441 return std::equal(
440 std::begin(*(other->list_)), 442 std::begin(*list_), std::end(*list_), std::begin(*(other->list_)),
441 [](const ListStorage::value_type& lhs, 443 [](const ListStorage::value_type& lhs,
442 const ListStorage::value_type& rhs) { 444 const ListStorage::value_type& rhs) { return lhs.Equals(&rhs); });
443 return lhs->Equals(rhs.get());
444 });
445 } 445 }
446 } 446 }
447 447
448 NOTREACHED(); 448 NOTREACHED();
449 return false; 449 return false;
450 } 450 }
451 451
452 // static 452 // static
453 bool Value::Equals(const Value* a, const Value* b) { 453 bool Value::Equals(const Value* a, const Value* b) {
454 if ((a == NULL) && (b == NULL)) return true; 454 if ((a == NULL) && (b == NULL)) return true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 case Type::DOUBLE: 487 case Type::DOUBLE:
488 InternalCopyFundamentalValue(that); 488 InternalCopyFundamentalValue(that);
489 return; 489 return;
490 490
491 case Type::STRING: 491 case Type::STRING:
492 string_value_.Init(*that.string_value_); 492 string_value_.Init(*that.string_value_);
493 return; 493 return;
494 case Type::BINARY: 494 case Type::BINARY:
495 binary_value_.Init(*that.binary_value_); 495 binary_value_.Init(*that.binary_value_);
496 return; 496 return;
497 // DictStorage and ListStorage are move-only types due to the presence of 497 // DictStorage is a move-only type due to the presence of unique_ptrs. This
498 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 498 // is why the call to |CreateDeepCopy| is necessary here.
499 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 499 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
500 // can be copied directly. 500 // directly.
501 case Type::DICTIONARY: 501 case Type::DICTIONARY:
502 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); 502 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_));
brettw 2017/03/17 05:39:19 I suspect this line is causing the Android crash.
jdoerrie 2017/03/23 18:11:17 Unfortunately this didn't solve the issue. After m
503 return; 503 return;
504 case Type::LIST: 504 case Type::LIST:
505 list_.Init(std::move(*that.CreateDeepCopy()->list_)); 505 list_.Init(*that.list_);
506 return; 506 return;
507 } 507 }
508 } 508 }
509 509
510 void Value::InternalMoveConstructFrom(Value&& that) { 510 void Value::InternalMoveConstructFrom(Value&& that) {
511 type_ = that.type_; 511 type_ = that.type_;
512 512
513 switch (type_) { 513 switch (type_) {
514 case Type::NONE: 514 case Type::NONE:
515 case Type::BOOLEAN: 515 case Type::BOOLEAN:
(...skipping 27 matching lines...) Expand all
543 case Type::DOUBLE: 543 case Type::DOUBLE:
544 InternalCopyFundamentalValue(that); 544 InternalCopyFundamentalValue(that);
545 return; 545 return;
546 546
547 case Type::STRING: 547 case Type::STRING:
548 *string_value_ = *that.string_value_; 548 *string_value_ = *that.string_value_;
549 return; 549 return;
550 case Type::BINARY: 550 case Type::BINARY:
551 *binary_value_ = *that.binary_value_; 551 *binary_value_ = *that.binary_value_;
552 return; 552 return;
553 // DictStorage and ListStorage are move-only types due to the presence of 553 // DictStorage is a move-only type due to the presence of unique_ptrs. This
554 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 554 // is why the call to |CreateDeepCopy| is necessary here.
555 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 555 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
556 // can be copied directly. 556 // directly.
557 case Type::DICTIONARY: 557 case Type::DICTIONARY:
558 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); 558 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_);
brettw 2017/03/17 05:39:19 Ditto here.
559 return; 559 return;
560 case Type::LIST: 560 case Type::LIST:
561 *list_ = std::move(*that.CreateDeepCopy()->list_); 561 *list_ = *that.list_;
562 return; 562 return;
563 } 563 }
564 } 564 }
565 565
566 void Value::InternalMoveAssignFromSameType(Value&& that) { 566 void Value::InternalMoveAssignFromSameType(Value&& that) {
567 CHECK_EQ(type_, that.type_); 567 CHECK_EQ(type_, that.type_);
568 568
569 switch (type_) { 569 switch (type_) {
570 case Type::NONE: 570 case Type::NONE:
571 case Type::BOOLEAN: 571 case Type::BOOLEAN:
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 } 1088 }
1089 return nullptr; 1089 return nullptr;
1090 } 1090 }
1091 1091
1092 ListValue::ListValue() : Value(Type::LIST) {} 1092 ListValue::ListValue() : Value(Type::LIST) {}
1093 1093
1094 void ListValue::Clear() { 1094 void ListValue::Clear() {
1095 list_->clear(); 1095 list_->clear();
1096 } 1096 }
1097 1097
1098 void ListValue::Reserve(size_t n) {
1099 list_->reserve(n);
1100 }
1101
1098 bool ListValue::Set(size_t index, Value* in_value) { 1102 bool ListValue::Set(size_t index, Value* in_value) {
1099 return Set(index, WrapUnique(in_value)); 1103 return Set(index, WrapUnique(in_value));
1100 } 1104 }
1101 1105
1102 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) { 1106 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
1103 if (!in_value) 1107 if (!in_value)
1104 return false; 1108 return false;
1105 1109
1106 if (index >= list_->size()) { 1110 if (index >= list_->size()) {
1107 // Pad out any intermediate indexes with null settings 1111 // Pad out any intermediate indexes with null settings
1108 while (index > list_->size()) 1112 while (index > list_->size())
1109 Append(CreateNullValue()); 1113 Append(CreateNullValue());
1110 Append(std::move(in_value)); 1114 Append(std::move(in_value));
1111 } else { 1115 } else {
1112 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed? 1116 (*list_)[index] = std::move(*in_value);
1113 DCHECK((*list_)[index] != in_value);
1114 (*list_)[index] = std::move(in_value);
1115 } 1117 }
1116 return true; 1118 return true;
1117 } 1119 }
1118 1120
1119 bool ListValue::Get(size_t index, const Value** out_value) const { 1121 bool ListValue::Get(size_t index, const Value** out_value) const {
1120 if (index >= list_->size()) 1122 if (index >= list_->size())
1121 return false; 1123 return false;
1122 1124
1123 if (out_value) 1125 if (out_value)
1124 *out_value = (*list_)[index].get(); 1126 *out_value = &(*list_)[index];
1125 1127
1126 return true; 1128 return true;
1127 } 1129 }
1128 1130
1129 bool ListValue::Get(size_t index, Value** out_value) { 1131 bool ListValue::Get(size_t index, Value** out_value) {
1130 return static_cast<const ListValue&>(*this).Get( 1132 return static_cast<const ListValue&>(*this).Get(
1131 index, 1133 index,
1132 const_cast<const Value**>(out_value)); 1134 const_cast<const Value**>(out_value));
1133 } 1135 }
1134 1136
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 return static_cast<const ListValue&>(*this).GetList( 1227 return static_cast<const ListValue&>(*this).GetList(
1226 index, 1228 index,
1227 const_cast<const ListValue**>(out_value)); 1229 const_cast<const ListValue**>(out_value));
1228 } 1230 }
1229 1231
1230 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { 1232 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1231 if (index >= list_->size()) 1233 if (index >= list_->size())
1232 return false; 1234 return false;
1233 1235
1234 if (out_value) 1236 if (out_value)
1235 *out_value = std::move((*list_)[index]); 1237 *out_value = MakeUnique<Value>(std::move((*list_)[index]));
1236 1238
1237 list_->erase(list_->begin() + index); 1239 list_->erase(list_->begin() + index);
1238 return true; 1240 return true;
1239 } 1241 }
1240 1242
1241 bool ListValue::Remove(const Value& value, size_t* index) { 1243 bool ListValue::Remove(const Value& value, size_t* index) {
1242 for (auto it = list_->begin(); it != list_->end(); ++it) { 1244 auto it = std::find_if(
1243 if ((*it)->Equals(&value)) { 1245 list_->begin(), list_->end(),
1244 size_t previous_index = it - list_->begin(); 1246 [&value](const Value& entry) { return entry.Equals(&value); });
1245 list_->erase(it);
1246 1247
1247 if (index) 1248 if (it == list_->end())
1248 *index = previous_index; 1249 return false;
1249 return true; 1250
1250 } 1251 if (index)
1251 } 1252 *index = std::distance(list_->begin(), it);
1252 return false; 1253
1254 list_->erase(it);
1255 return true;
1253 } 1256 }
1254 1257
1255 ListValue::iterator ListValue::Erase(iterator iter, 1258 ListValue::iterator ListValue::Erase(iterator iter,
1256 std::unique_ptr<Value>* out_value) { 1259 std::unique_ptr<Value>* out_value) {
1257 if (out_value) 1260 if (out_value)
1258 *out_value = std::move(*ListStorage::iterator(iter)); 1261 *out_value = MakeUnique<Value>(std::move(*iter));
1259 1262
1260 return list_->erase(iter); 1263 return list_->erase(iter);
1261 } 1264 }
1262 1265
1263 void ListValue::Append(std::unique_ptr<Value> in_value) { 1266 void ListValue::Append(std::unique_ptr<Value> in_value) {
1264 list_->push_back(std::move(in_value)); 1267 list_->push_back(std::move(*in_value));
1265 } 1268 }
1266 1269
1267 #if !defined(OS_LINUX) 1270 #if !defined(OS_LINUX)
1268 void ListValue::Append(Value* in_value) { 1271 void ListValue::Append(Value* in_value) {
1269 DCHECK(in_value); 1272 DCHECK(in_value);
1270 Append(WrapUnique(in_value)); 1273 Append(WrapUnique(in_value));
1271 } 1274 }
1272 #endif 1275 #endif
1273 1276
1274 void ListValue::AppendBoolean(bool in_value) { 1277 void ListValue::AppendBoolean(bool in_value) {
(...skipping 26 matching lines...) Expand all
1301 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1304 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1302 for (std::vector<string16>::const_iterator it = in_values.begin(); 1305 for (std::vector<string16>::const_iterator it = in_values.begin();
1303 it != in_values.end(); ++it) { 1306 it != in_values.end(); ++it) {
1304 AppendString(*it); 1307 AppendString(*it);
1305 } 1308 }
1306 } 1309 }
1307 1310
1308 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { 1311 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
1309 DCHECK(in_value); 1312 DCHECK(in_value);
1310 for (const auto& entry : *list_) { 1313 for (const auto& entry : *list_) {
1311 if (entry->Equals(in_value.get())) { 1314 if (entry.Equals(in_value.get())) {
1312 return false; 1315 return false;
1313 } 1316 }
1314 } 1317 }
1315 list_->push_back(std::move(in_value)); 1318 list_->push_back(std::move(*in_value));
1316 return true; 1319 return true;
1317 } 1320 }
1318 1321
1319 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { 1322 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
1320 DCHECK(in_value); 1323 DCHECK(in_value);
1321 if (index > list_->size()) 1324 if (index > list_->size())
1322 return false; 1325 return false;
1323 1326
1324 list_->insert(list_->begin() + index, std::move(in_value)); 1327 list_->insert(list_->begin() + index, std::move(*in_value));
1325 return true; 1328 return true;
1326 } 1329 }
1327 1330
1328 ListValue::const_iterator ListValue::Find(const Value& value) const { 1331 ListValue::const_iterator ListValue::Find(const Value& value) const {
1329 return std::find_if(list_->begin(), list_->end(), 1332 return std::find_if(
1330 [&value](const std::unique_ptr<Value>& entry) { 1333 list_->begin(), list_->end(),
1331 return entry->Equals(&value); 1334 [&value](const Value& entry) { return entry.Equals(&value); });
1332 });
1333 } 1335 }
1334 1336
1335 void ListValue::Swap(ListValue* other) { 1337 void ListValue::Swap(ListValue* other) {
1336 CHECK(other->is_list()); 1338 CHECK(other->is_list());
1337 list_->swap(*(other->list_)); 1339 list_->swap(*(other->list_));
1338 } 1340 }
1339 1341
1340 ListValue* ListValue::DeepCopy() const { 1342 ListValue* ListValue::DeepCopy() const {
1341 return static_cast<ListValue*>(Value::DeepCopy()); 1343 return static_cast<ListValue*>(Value::DeepCopy());
1342 } 1344 }
(...skipping 15 matching lines...) Expand all
1358 } 1360 }
1359 1361
1360 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1362 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1361 if (static_cast<int>(type) < 0 || 1363 if (static_cast<int>(type) < 0 ||
1362 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1364 static_cast<size_t>(type) >= arraysize(kTypeNames))
1363 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1365 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1364 return out << Value::GetTypeName(type); 1366 return out << Value::GetTypeName(type);
1365 } 1367 }
1366 1368
1367 } // namespace base 1369 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698