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

Side by Side Diff: base/values.cc

Issue 2740143002: Change base::Value::ListStorage to std::vector<base::Value> (Closed)
Patch Set: Fix Android Compilation Error 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
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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 for (const auto& current_entry : **dict_ptr_) { 368 for (const auto& current_entry : **dict_ptr_) {
369 result->SetWithoutPathExpansion(current_entry.first, 369 result->SetWithoutPathExpansion(current_entry.first,
370 current_entry.second->CreateDeepCopy()); 370 current_entry.second->CreateDeepCopy());
371 } 371 }
372 372
373 return result; 373 return result;
374 } 374 }
375 375
376 case Type::LIST: { 376 case Type::LIST: {
377 ListValue* result = new ListValue; 377 ListValue* result = new ListValue;
378 378 *result->list_ = *list_;
379 for (const auto& entry : *list_)
380 result->Append(entry->CreateDeepCopy());
381
382 return result; 379 return result;
383 } 380 }
384 381
385 default: 382 default:
386 NOTREACHED(); 383 NOTREACHED();
387 return nullptr; 384 return nullptr;
388 } 385 }
389 } 386 }
390 387
391 std::unique_ptr<Value> Value::CreateDeepCopy() const { 388 std::unique_ptr<Value> Value::CreateDeepCopy() const {
(...skipping 30 matching lines...) Expand all
422 if (lhs.first != rhs.first) 419 if (lhs.first != rhs.first)
423 return false; 420 return false;
424 421
425 return lhs.second->Equals(rhs.second.get()); 422 return lhs.second->Equals(rhs.second.get());
426 }); 423 });
427 } 424 }
428 case Type::LIST: { 425 case Type::LIST: {
429 if (list_->size() != other->list_->size()) 426 if (list_->size() != other->list_->size())
430 return false; 427 return false;
431 428
432 return std::equal(std::begin(*list_), std::end(*list_), 429 return std::equal(
433 std::begin(*(other->list_)), 430 std::begin(*list_), std::end(*list_), std::begin(*(other->list_)),
434 [](const ListStorage::value_type& lhs, 431 [](const ListStorage::value_type& lhs,
435 const ListStorage::value_type& rhs) { 432 const ListStorage::value_type& rhs) { return lhs.Equals(&rhs); });
436 return lhs->Equals(rhs.get());
437 });
438 } 433 }
439 } 434 }
440 435
441 NOTREACHED(); 436 NOTREACHED();
442 return false; 437 return false;
443 } 438 }
444 439
445 // static 440 // static
446 bool Value::Equals(const Value* a, const Value* b) { 441 bool Value::Equals(const Value* a, const Value* b) {
447 if ((a == NULL) && (b == NULL)) return true; 442 if ((a == NULL) && (b == NULL)) return true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 case Type::DOUBLE: 475 case Type::DOUBLE:
481 InternalCopyFundamentalValue(that); 476 InternalCopyFundamentalValue(that);
482 return; 477 return;
483 478
484 case Type::STRING: 479 case Type::STRING:
485 string_value_.Init(*that.string_value_); 480 string_value_.Init(*that.string_value_);
486 return; 481 return;
487 case Type::BINARY: 482 case Type::BINARY:
488 binary_value_.Init(*that.binary_value_); 483 binary_value_.Init(*that.binary_value_);
489 return; 484 return;
490 // DictStorage and ListStorage are move-only types due to the presence of 485 // DictStorage is a move-only type due to the presence of unique_ptrs. This
491 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 486 // is why the call to |CreateDeepCopy| is necessary here.
492 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 487 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
493 // can be copied directly. 488 // directly.
494 case Type::DICTIONARY: 489 case Type::DICTIONARY: {
495 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); 490 auto deep_copy = that.CreateDeepCopy();
491 dict_ptr_.Init(std::move(*deep_copy->dict_ptr_));
496 return; 492 return;
493 }
497 case Type::LIST: 494 case Type::LIST:
498 list_.Init(std::move(*that.CreateDeepCopy()->list_)); 495 list_.Init(*that.list_);
499 return; 496 return;
500 } 497 }
501 } 498 }
502 499
503 void Value::InternalMoveConstructFrom(Value&& that) { 500 void Value::InternalMoveConstructFrom(Value&& that) {
504 type_ = that.type_; 501 type_ = that.type_;
505 502
506 switch (type_) { 503 switch (type_) {
507 case Type::NONE: 504 case Type::NONE:
508 case Type::BOOLEAN: 505 case Type::BOOLEAN:
(...skipping 29 matching lines...) Expand all
538 case Type::DOUBLE: 535 case Type::DOUBLE:
539 InternalCopyFundamentalValue(that); 536 InternalCopyFundamentalValue(that);
540 return; 537 return;
541 538
542 case Type::STRING: 539 case Type::STRING:
543 *string_value_ = *that.string_value_; 540 *string_value_ = *that.string_value_;
544 return; 541 return;
545 case Type::BINARY: 542 case Type::BINARY:
546 *binary_value_ = *that.binary_value_; 543 *binary_value_ = *that.binary_value_;
547 return; 544 return;
548 // DictStorage and ListStorage are move-only types due to the presence of 545 // DictStorage is a move-only type due to the presence of unique_ptrs. This
549 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 546 // is why the call to |CreateDeepCopy| is necessary here.
550 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 547 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
551 // can be copied directly. 548 // directly.
552 case Type::DICTIONARY: 549 case Type::DICTIONARY: {
553 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); 550 auto deep_copy = that.CreateDeepCopy();
551 *dict_ptr_ = std::move(*deep_copy->dict_ptr_);
554 return; 552 return;
553 }
555 case Type::LIST: 554 case Type::LIST:
556 *list_ = std::move(*that.CreateDeepCopy()->list_); 555 *list_ = *that.list_;
557 return; 556 return;
558 } 557 }
559 } 558 }
560 559
561 void Value::InternalCleanup() { 560 void Value::InternalCleanup() {
562 switch (type_) { 561 switch (type_) {
563 case Type::NONE: 562 case Type::NONE:
564 case Type::BOOLEAN: 563 case Type::BOOLEAN:
565 case Type::INTEGER: 564 case Type::INTEGER:
566 case Type::DOUBLE: 565 case Type::DOUBLE:
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 } 1054 }
1056 return nullptr; 1055 return nullptr;
1057 } 1056 }
1058 1057
1059 ListValue::ListValue() : Value(Type::LIST) {} 1058 ListValue::ListValue() : Value(Type::LIST) {}
1060 1059
1061 void ListValue::Clear() { 1060 void ListValue::Clear() {
1062 list_->clear(); 1061 list_->clear();
1063 } 1062 }
1064 1063
1064 void ListValue::Reserve(size_t n) {
1065 list_->reserve(n);
1066 }
1067
1065 bool ListValue::Set(size_t index, Value* in_value) { 1068 bool ListValue::Set(size_t index, Value* in_value) {
1066 return Set(index, WrapUnique(in_value)); 1069 return Set(index, WrapUnique(in_value));
1067 } 1070 }
1068 1071
1069 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) { 1072 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
1070 if (!in_value) 1073 if (!in_value)
1071 return false; 1074 return false;
1072 1075
1073 if (index >= list_->size()) { 1076 if (index >= list_->size()) {
1074 // Pad out any intermediate indexes with null settings 1077 // Pad out any intermediate indexes with null settings
1075 while (index > list_->size()) 1078 while (index > list_->size())
1076 Append(CreateNullValue()); 1079 Append(CreateNullValue());
1077 Append(std::move(in_value)); 1080 Append(std::move(in_value));
1078 } else { 1081 } else {
1079 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed? 1082 (*list_)[index] = std::move(*in_value);
1080 DCHECK((*list_)[index] != in_value);
1081 (*list_)[index] = std::move(in_value);
1082 } 1083 }
1083 return true; 1084 return true;
1084 } 1085 }
1085 1086
1086 bool ListValue::Get(size_t index, const Value** out_value) const { 1087 bool ListValue::Get(size_t index, const Value** out_value) const {
1087 if (index >= list_->size()) 1088 if (index >= list_->size())
1088 return false; 1089 return false;
1089 1090
1090 if (out_value) 1091 if (out_value)
1091 *out_value = (*list_)[index].get(); 1092 *out_value = &(*list_)[index];
1092 1093
1093 return true; 1094 return true;
1094 } 1095 }
1095 1096
1096 bool ListValue::Get(size_t index, Value** out_value) { 1097 bool ListValue::Get(size_t index, Value** out_value) {
1097 return static_cast<const ListValue&>(*this).Get( 1098 return static_cast<const ListValue&>(*this).Get(
1098 index, 1099 index,
1099 const_cast<const Value**>(out_value)); 1100 const_cast<const Value**>(out_value));
1100 } 1101 }
1101 1102
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 return static_cast<const ListValue&>(*this).GetList( 1193 return static_cast<const ListValue&>(*this).GetList(
1193 index, 1194 index,
1194 const_cast<const ListValue**>(out_value)); 1195 const_cast<const ListValue**>(out_value));
1195 } 1196 }
1196 1197
1197 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { 1198 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1198 if (index >= list_->size()) 1199 if (index >= list_->size())
1199 return false; 1200 return false;
1200 1201
1201 if (out_value) 1202 if (out_value)
1202 *out_value = std::move((*list_)[index]); 1203 *out_value = MakeUnique<Value>(std::move((*list_)[index]));
1203 1204
1204 list_->erase(list_->begin() + index); 1205 list_->erase(list_->begin() + index);
1205 return true; 1206 return true;
1206 } 1207 }
1207 1208
1208 bool ListValue::Remove(const Value& value, size_t* index) { 1209 bool ListValue::Remove(const Value& value, size_t* index) {
1209 for (auto it = list_->begin(); it != list_->end(); ++it) { 1210 auto it = std::find_if(
1210 if ((*it)->Equals(&value)) { 1211 list_->begin(), list_->end(),
1211 size_t previous_index = it - list_->begin(); 1212 [&value](const Value& entry) { return entry.Equals(&value); });
1212 list_->erase(it);
1213 1213
1214 if (index) 1214 if (it == list_->end())
1215 *index = previous_index; 1215 return false;
1216 return true; 1216
1217 } 1217 if (index)
1218 } 1218 *index = std::distance(list_->begin(), it);
1219 return false; 1219
1220 list_->erase(it);
1221 return true;
1220 } 1222 }
1221 1223
1222 ListValue::iterator ListValue::Erase(iterator iter, 1224 ListValue::iterator ListValue::Erase(iterator iter,
1223 std::unique_ptr<Value>* out_value) { 1225 std::unique_ptr<Value>* out_value) {
1224 if (out_value) 1226 if (out_value)
1225 *out_value = std::move(*ListStorage::iterator(iter)); 1227 *out_value = MakeUnique<Value>(std::move(*iter));
1226 1228
1227 return list_->erase(iter); 1229 return list_->erase(iter);
1228 } 1230 }
1229 1231
1230 void ListValue::Append(std::unique_ptr<Value> in_value) { 1232 void ListValue::Append(std::unique_ptr<Value> in_value) {
1231 list_->push_back(std::move(in_value)); 1233 list_->push_back(std::move(*in_value));
1232 } 1234 }
1233 1235
1234 #if !defined(OS_LINUX) 1236 #if !defined(OS_LINUX)
1235 void ListValue::Append(Value* in_value) { 1237 void ListValue::Append(Value* in_value) {
1236 DCHECK(in_value); 1238 DCHECK(in_value);
1237 Append(WrapUnique(in_value)); 1239 Append(WrapUnique(in_value));
1238 } 1240 }
1239 #endif 1241 #endif
1240 1242
1241 void ListValue::AppendBoolean(bool in_value) { 1243 void ListValue::AppendBoolean(bool in_value) {
(...skipping 26 matching lines...) Expand all
1268 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1270 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1269 for (std::vector<string16>::const_iterator it = in_values.begin(); 1271 for (std::vector<string16>::const_iterator it = in_values.begin();
1270 it != in_values.end(); ++it) { 1272 it != in_values.end(); ++it) {
1271 AppendString(*it); 1273 AppendString(*it);
1272 } 1274 }
1273 } 1275 }
1274 1276
1275 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { 1277 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
1276 DCHECK(in_value); 1278 DCHECK(in_value);
1277 for (const auto& entry : *list_) { 1279 for (const auto& entry : *list_) {
1278 if (entry->Equals(in_value.get())) { 1280 if (entry.Equals(in_value.get())) {
1279 return false; 1281 return false;
1280 } 1282 }
1281 } 1283 }
1282 list_->push_back(std::move(in_value)); 1284 list_->push_back(std::move(*in_value));
1283 return true; 1285 return true;
1284 } 1286 }
1285 1287
1286 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { 1288 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
1287 DCHECK(in_value); 1289 DCHECK(in_value);
1288 if (index > list_->size()) 1290 if (index > list_->size())
1289 return false; 1291 return false;
1290 1292
1291 list_->insert(list_->begin() + index, std::move(in_value)); 1293 list_->insert(list_->begin() + index, std::move(*in_value));
1292 return true; 1294 return true;
1293 } 1295 }
1294 1296
1295 ListValue::const_iterator ListValue::Find(const Value& value) const { 1297 ListValue::const_iterator ListValue::Find(const Value& value) const {
1296 return std::find_if(list_->begin(), list_->end(), 1298 return std::find_if(
1297 [&value](const std::unique_ptr<Value>& entry) { 1299 list_->begin(), list_->end(),
1298 return entry->Equals(&value); 1300 [&value](const Value& entry) { return entry.Equals(&value); });
1299 });
1300 } 1301 }
1301 1302
1302 void ListValue::Swap(ListValue* other) { 1303 void ListValue::Swap(ListValue* other) {
1303 CHECK(other->is_list()); 1304 CHECK(other->is_list());
1304 list_->swap(*(other->list_)); 1305 list_->swap(*(other->list_));
1305 } 1306 }
1306 1307
1307 ListValue* ListValue::DeepCopy() const { 1308 ListValue* ListValue::DeepCopy() const {
1308 return static_cast<ListValue*>(Value::DeepCopy()); 1309 return static_cast<ListValue*>(Value::DeepCopy());
1309 } 1310 }
(...skipping 15 matching lines...) Expand all
1325 } 1326 }
1326 1327
1327 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1328 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1328 if (static_cast<int>(type) < 0 || 1329 if (static_cast<int>(type) < 0 ||
1329 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1330 static_cast<size_t>(type) >= arraysize(kTypeNames))
1330 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1331 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1331 return out << Value::GetTypeName(type); 1332 return out << Value::GetTypeName(type);
1332 } 1333 }
1333 1334
1334 } // namespace base 1335 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698