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

Side by Side Diff: base/values.cc

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