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

Side by Side Diff: base/values.cc

Issue 2740143002: Change base::Value::ListStorage to std::vector<base::Value> (Closed)
Patch Set: Rebase 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 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 if ((*lhs.dict_ptr_)->size() != (*rhs.dict_ptr_)->size()) 368 if ((*lhs.dict_ptr_)->size() != (*rhs.dict_ptr_)->size())
369 return false; 369 return false;
370 return std::equal(std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_), 370 return std::equal(std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
371 std::begin(**rhs.dict_ptr_), 371 std::begin(**rhs.dict_ptr_),
372 [](const Value::DictStorage::value_type& u, 372 [](const Value::DictStorage::value_type& u,
373 const Value::DictStorage::value_type& v) { 373 const Value::DictStorage::value_type& v) {
374 return std::tie(u.first, *u.second) == 374 return std::tie(u.first, *u.second) ==
375 std::tie(v.first, *v.second); 375 std::tie(v.first, *v.second);
376 }); 376 });
377 case Value::Type::LIST: 377 case Value::Type::LIST:
378 if (lhs.list_->size() != rhs.list_->size()) 378 return *lhs.list_ == *rhs.list_;
379 return false;
380 return std::equal(
381 std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
382 [](const Value::ListStorage::value_type& u,
383 const Value::ListStorage::value_type& v) { return *u == *v; });
384 } 379 }
385 380
386 NOTREACHED(); 381 NOTREACHED();
387 return false; 382 return false;
388 } 383 }
389 384
390 bool operator!=(const Value& lhs, const Value& rhs) { 385 bool operator!=(const Value& lhs, const Value& rhs) {
391 return !(lhs == rhs); 386 return !(lhs == rhs);
392 } 387 }
393 388
(...skipping 18 matching lines...) Expand all
412 // are completely inlined. 407 // are completely inlined.
413 case Value::Type::DICTIONARY: 408 case Value::Type::DICTIONARY:
414 return std::lexicographical_compare( 409 return std::lexicographical_compare(
415 std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_), 410 std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
416 std::begin(**rhs.dict_ptr_), std::end(**rhs.dict_ptr_), 411 std::begin(**rhs.dict_ptr_), std::end(**rhs.dict_ptr_),
417 [](const Value::DictStorage::value_type& u, 412 [](const Value::DictStorage::value_type& u,
418 const Value::DictStorage::value_type& v) { 413 const Value::DictStorage::value_type& v) {
419 return std::tie(u.first, *u.second) < std::tie(v.first, *v.second); 414 return std::tie(u.first, *u.second) < std::tie(v.first, *v.second);
420 }); 415 });
421 case Value::Type::LIST: 416 case Value::Type::LIST:
422 return std::lexicographical_compare( 417 return *lhs.list_ < *rhs.list_;
423 std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
424 std::end(*rhs.list_),
425 [](const Value::ListStorage::value_type& u,
426 const Value::ListStorage::value_type& v) { return *u < *v; });
427 } 418 }
428 419
429 NOTREACHED(); 420 NOTREACHED();
430 return false; 421 return false;
431 } 422 }
432 423
433 bool operator>(const Value& lhs, const Value& rhs) { 424 bool operator>(const Value& lhs, const Value& rhs) {
434 return rhs < lhs; 425 return rhs < lhs;
435 } 426 }
436 427
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 case Type::DOUBLE: 478 case Type::DOUBLE:
488 InternalCopyFundamentalValue(that); 479 InternalCopyFundamentalValue(that);
489 return; 480 return;
490 481
491 case Type::STRING: 482 case Type::STRING:
492 string_value_.Init(*that.string_value_); 483 string_value_.Init(*that.string_value_);
493 return; 484 return;
494 case Type::BINARY: 485 case Type::BINARY:
495 binary_value_.Init(*that.binary_value_); 486 binary_value_.Init(*that.binary_value_);
496 return; 487 return;
497 // DictStorage and ListStorage are move-only types due to the presence of 488 // DictStorage is a move-only type due to the presence of unique_ptrs. This
498 // unique_ptrs. This is why the explicit copy of every element is necessary 489 // is why the explicit copy of every element is necessary here.
499 // here. 490 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
500 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 491 // directly.
501 // can be copied directly.
502 case Type::DICTIONARY: 492 case Type::DICTIONARY:
503 dict_ptr_.Init(MakeUnique<DictStorage>()); 493 dict_ptr_.Init(MakeUnique<DictStorage>());
504 for (const auto& it : **that.dict_ptr_) { 494 for (const auto& it : **that.dict_ptr_) {
505 (*dict_ptr_) 495 (*dict_ptr_)
506 ->emplace_hint((*dict_ptr_)->end(), it.first, 496 ->emplace_hint((*dict_ptr_)->end(), it.first,
507 MakeUnique<Value>(*it.second)); 497 MakeUnique<Value>(*it.second));
508 } 498 }
509 return; 499 return;
510 case Type::LIST: 500 case Type::LIST:
511 list_.Init(); 501 list_.Init(*that.list_);
512 list_->reserve(that.list_->size());
513 for (const auto& it : *that.list_)
514 list_->push_back(MakeUnique<Value>(*it));
515 return; 502 return;
516 } 503 }
517 } 504 }
518 505
519 void Value::InternalMoveConstructFrom(Value&& that) { 506 void Value::InternalMoveConstructFrom(Value&& that) {
520 type_ = that.type_; 507 type_ = that.type_;
521 508
522 switch (type_) { 509 switch (type_) {
523 case Type::NONE: 510 case Type::NONE:
524 case Type::BOOLEAN: 511 case Type::BOOLEAN:
(...skipping 29 matching lines...) Expand all
554 case Type::DOUBLE: 541 case Type::DOUBLE:
555 InternalCopyFundamentalValue(that); 542 InternalCopyFundamentalValue(that);
556 return; 543 return;
557 544
558 case Type::STRING: 545 case Type::STRING:
559 *string_value_ = *that.string_value_; 546 *string_value_ = *that.string_value_;
560 return; 547 return;
561 case Type::BINARY: 548 case Type::BINARY:
562 *binary_value_ = *that.binary_value_; 549 *binary_value_ = *that.binary_value_;
563 return; 550 return;
564 // DictStorage and ListStorage are move-only types due to the presence of 551 // DictStorage is a move-only type due to the presence of unique_ptrs. This
565 // unique_ptrs. This is why the explicit call to the copy constructor is 552 // is why the explicit call to the copy constructor is necessary here.
566 // necessary here. 553 // TODO(crbug.com/646113): Clean this up when DictStorage can be copied
567 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 554 // directly.
568 // can be copied directly. 555 case Type::DICTIONARY: {
569 case Type::DICTIONARY: 556 Value copy = that;
570 *dict_ptr_ = std::move(*Value(that).dict_ptr_); 557 *dict_ptr_ = std::move(*copy.dict_ptr_);
571 return; 558 return;
559 }
572 case Type::LIST: 560 case Type::LIST:
573 *list_ = std::move(*Value(that).list_); 561 *list_ = *that.list_;
574 return; 562 return;
575 } 563 }
576 } 564 }
577 565
578 void Value::InternalCleanup() { 566 void Value::InternalCleanup() {
579 switch (type_) { 567 switch (type_) {
580 case Type::NONE: 568 case Type::NONE:
581 case Type::BOOLEAN: 569 case Type::BOOLEAN:
582 case Type::INTEGER: 570 case Type::INTEGER:
583 case Type::DOUBLE: 571 case Type::DOUBLE:
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 } 1058 }
1071 return nullptr; 1059 return nullptr;
1072 } 1060 }
1073 1061
1074 ListValue::ListValue() : Value(Type::LIST) {} 1062 ListValue::ListValue() : Value(Type::LIST) {}
1075 1063
1076 void ListValue::Clear() { 1064 void ListValue::Clear() {
1077 list_->clear(); 1065 list_->clear();
1078 } 1066 }
1079 1067
1068 void ListValue::Reserve(size_t n) {
1069 list_->reserve(n);
1070 }
1071
1080 bool ListValue::Set(size_t index, Value* in_value) { 1072 bool ListValue::Set(size_t index, Value* in_value) {
1081 return Set(index, WrapUnique(in_value)); 1073 return Set(index, WrapUnique(in_value));
1082 } 1074 }
1083 1075
1084 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) { 1076 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
1085 if (!in_value) 1077 if (!in_value)
1086 return false; 1078 return false;
1087 1079
1088 if (index >= list_->size()) { 1080 if (index >= list_->size()) {
1089 // Pad out any intermediate indexes with null settings 1081 // Pad out any intermediate indexes with null settings
1090 while (index > list_->size()) 1082 while (index > list_->size())
1091 Append(MakeUnique<Value>()); 1083 Append(MakeUnique<Value>());
1092 Append(std::move(in_value)); 1084 Append(std::move(in_value));
1093 } else { 1085 } else {
1094 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed? 1086 (*list_)[index] = std::move(*in_value);
1095 DCHECK((*list_)[index] != in_value);
1096 (*list_)[index] = std::move(in_value);
1097 } 1087 }
1098 return true; 1088 return true;
1099 } 1089 }
1100 1090
1101 bool ListValue::Get(size_t index, const Value** out_value) const { 1091 bool ListValue::Get(size_t index, const Value** out_value) const {
1102 if (index >= list_->size()) 1092 if (index >= list_->size())
1103 return false; 1093 return false;
1104 1094
1105 if (out_value) 1095 if (out_value)
1106 *out_value = (*list_)[index].get(); 1096 *out_value = &(*list_)[index];
1107 1097
1108 return true; 1098 return true;
1109 } 1099 }
1110 1100
1111 bool ListValue::Get(size_t index, Value** out_value) { 1101 bool ListValue::Get(size_t index, Value** out_value) {
1112 return static_cast<const ListValue&>(*this).Get( 1102 return static_cast<const ListValue&>(*this).Get(
1113 index, 1103 index,
1114 const_cast<const Value**>(out_value)); 1104 const_cast<const Value**>(out_value));
1115 } 1105 }
1116 1106
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 return static_cast<const ListValue&>(*this).GetList( 1196 return static_cast<const ListValue&>(*this).GetList(
1207 index, 1197 index,
1208 const_cast<const ListValue**>(out_value)); 1198 const_cast<const ListValue**>(out_value));
1209 } 1199 }
1210 1200
1211 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { 1201 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1212 if (index >= list_->size()) 1202 if (index >= list_->size())
1213 return false; 1203 return false;
1214 1204
1215 if (out_value) 1205 if (out_value)
1216 *out_value = std::move((*list_)[index]); 1206 *out_value = MakeUnique<Value>(std::move((*list_)[index]));
1217 1207
1218 list_->erase(list_->begin() + index); 1208 list_->erase(list_->begin() + index);
1219 return true; 1209 return true;
1220 } 1210 }
1221 1211
1222 bool ListValue::Remove(const Value& value, size_t* index) { 1212 bool ListValue::Remove(const Value& value, size_t* index) {
1223 for (auto it = list_->begin(); it != list_->end(); ++it) { 1213 auto it = std::find(list_->begin(), list_->end(), value);
1224 if (**it == value) {
1225 size_t previous_index = it - list_->begin();
1226 list_->erase(it);
1227 1214
1228 if (index) 1215 if (it == list_->end())
1229 *index = previous_index; 1216 return false;
1230 return true; 1217
1231 } 1218 if (index)
1232 } 1219 *index = std::distance(list_->begin(), it);
1233 return false; 1220
1221 list_->erase(it);
1222 return true;
1234 } 1223 }
1235 1224
1236 ListValue::iterator ListValue::Erase(iterator iter, 1225 ListValue::iterator ListValue::Erase(iterator iter,
1237 std::unique_ptr<Value>* out_value) { 1226 std::unique_ptr<Value>* out_value) {
1238 if (out_value) 1227 if (out_value)
1239 *out_value = std::move(*ListStorage::iterator(iter)); 1228 *out_value = MakeUnique<Value>(std::move(*iter));
1240 1229
1241 return list_->erase(iter); 1230 return list_->erase(iter);
1242 } 1231 }
1243 1232
1244 void ListValue::Append(std::unique_ptr<Value> in_value) { 1233 void ListValue::Append(std::unique_ptr<Value> in_value) {
1245 list_->push_back(std::move(in_value)); 1234 list_->push_back(std::move(*in_value));
1246 } 1235 }
1247 1236
1248 #if !defined(OS_LINUX) 1237 #if !defined(OS_LINUX)
1249 void ListValue::Append(Value* in_value) { 1238 void ListValue::Append(Value* in_value) {
1250 DCHECK(in_value); 1239 DCHECK(in_value);
1251 Append(WrapUnique(in_value)); 1240 Append(WrapUnique(in_value));
1252 } 1241 }
1253 #endif 1242 #endif
1254 1243
1255 void ListValue::AppendBoolean(bool in_value) { 1244 void ListValue::AppendBoolean(bool in_value) {
(...skipping 25 matching lines...) Expand all
1281 1270
1282 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1271 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1283 for (std::vector<string16>::const_iterator it = in_values.begin(); 1272 for (std::vector<string16>::const_iterator it = in_values.begin();
1284 it != in_values.end(); ++it) { 1273 it != in_values.end(); ++it) {
1285 AppendString(*it); 1274 AppendString(*it);
1286 } 1275 }
1287 } 1276 }
1288 1277
1289 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { 1278 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
1290 DCHECK(in_value); 1279 DCHECK(in_value);
1291 for (const auto& entry : *list_) { 1280 if (std::find(list_->begin(), list_->end(), *in_value) != list_->end())
1292 if (*entry == *in_value) 1281 return false;
1293 return false; 1282
1294 } 1283 list_->push_back(std::move(*in_value));
1295 list_->push_back(std::move(in_value));
1296 return true; 1284 return true;
1297 } 1285 }
1298 1286
1299 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { 1287 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
1300 DCHECK(in_value); 1288 DCHECK(in_value);
1301 if (index > list_->size()) 1289 if (index > list_->size())
1302 return false; 1290 return false;
1303 1291
1304 list_->insert(list_->begin() + index, std::move(in_value)); 1292 list_->insert(list_->begin() + index, std::move(*in_value));
1305 return true; 1293 return true;
1306 } 1294 }
1307 1295
1308 ListValue::const_iterator ListValue::Find(const Value& value) const { 1296 ListValue::const_iterator ListValue::Find(const Value& value) const {
1309 return std::find_if(list_->begin(), list_->end(), 1297 return std::find(list_->begin(), list_->end(), value);
1310 [&value](const std::unique_ptr<Value>& entry) {
1311 return *entry == value;
1312 });
1313 } 1298 }
1314 1299
1315 void ListValue::Swap(ListValue* other) { 1300 void ListValue::Swap(ListValue* other) {
1316 CHECK(other->is_list()); 1301 CHECK(other->is_list());
1317 list_->swap(*(other->list_)); 1302 list_->swap(*(other->list_));
1318 } 1303 }
1319 1304
1320 ListValue* ListValue::DeepCopy() const { 1305 ListValue* ListValue::DeepCopy() const {
1321 return new ListValue(*this); 1306 return new ListValue(*this);
1322 } 1307 }
(...skipping 15 matching lines...) Expand all
1338 } 1323 }
1339 1324
1340 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1325 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1341 if (static_cast<int>(type) < 0 || 1326 if (static_cast<int>(type) < 0 ||
1342 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1327 static_cast<size_t>(type) >= arraysize(kTypeNames))
1343 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1328 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1344 return out << Value::GetTypeName(type); 1329 return out << Value::GetTypeName(type);
1345 } 1330 }
1346 1331
1347 } // namespace base 1332 } // 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