| OLD | NEW |
| 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 default: | 385 default: |
| 386 NOTREACHED(); | 386 NOTREACHED(); |
| 387 return nullptr; | 387 return nullptr; |
| 388 } | 388 } |
| 389 } | 389 } |
| 390 | 390 |
| 391 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 391 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
| 392 return WrapUnique(DeepCopy()); | 392 return WrapUnique(DeepCopy()); |
| 393 } | 393 } |
| 394 | 394 |
| 395 bool Value::Equals(const Value* other) const { | 395 bool operator==(const Value& lhs, const Value& rhs) { |
| 396 if (other->type() != type()) | 396 if (lhs.type_ != rhs.type_) |
| 397 return false; | 397 return false; |
| 398 | 398 |
| 399 switch (type()) { | 399 switch (lhs.type_) { |
| 400 case Type::NONE: | 400 case Value::Type::NONE: |
| 401 return true; | 401 return true; |
| 402 case Type::BOOLEAN: | 402 case Value::Type::BOOLEAN: |
| 403 return bool_value_ == other->bool_value_; | 403 return lhs.bool_value_ == rhs.bool_value_; |
| 404 case Type::INTEGER: | 404 case Value::Type::INTEGER: |
| 405 return int_value_ == other->int_value_; | 405 return lhs.int_value_ == rhs.int_value_; |
| 406 case Type::DOUBLE: | 406 case Value::Type::DOUBLE: |
| 407 return double_value_ == other->double_value_; | 407 return lhs.double_value_ == rhs.double_value_; |
| 408 case Type::STRING: | 408 case Value::Type::STRING: |
| 409 return *string_value_ == *(other->string_value_); | 409 return *lhs.string_value_ == *rhs.string_value_; |
| 410 case Type::BINARY: | 410 case Value::Type::BINARY: |
| 411 return *binary_value_ == *(other->binary_value_); | 411 return *lhs.binary_value_ == *rhs.binary_value_; |
| 412 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue | 412 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue |
| 413 // are completely inlined. | 413 // are completely inlined. |
| 414 case Type::DICTIONARY: { | 414 case Value::Type::DICTIONARY: |
| 415 if ((*dict_ptr_)->size() != (*other->dict_ptr_)->size()) | 415 if ((*lhs.dict_ptr_)->size() != (*rhs.dict_ptr_)->size()) |
| 416 return false; | 416 return false; |
| 417 | 417 return std::equal(std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_), |
| 418 return std::equal(std::begin(**dict_ptr_), std::end(**dict_ptr_), | 418 std::begin(**rhs.dict_ptr_), |
| 419 std::begin(**(other->dict_ptr_)), | 419 [](const Value::DictStorage::value_type& u, |
| 420 [](const DictStorage::value_type& lhs, | 420 const Value::DictStorage::value_type& v) { |
| 421 const DictStorage::value_type& rhs) { | 421 return std::tie(u.first, *u.second) == |
| 422 if (lhs.first != rhs.first) | 422 std::tie(v.first, *v.second); |
| 423 return false; | |
| 424 | |
| 425 return lhs.second->Equals(rhs.second.get()); | |
| 426 }); | 423 }); |
| 427 } | 424 case Value::Type::LIST: |
| 428 case Type::LIST: { | 425 if (lhs.list_->size() != rhs.list_->size()) |
| 429 if (list_->size() != other->list_->size()) | |
| 430 return false; | 426 return false; |
| 431 | 427 return std::equal( |
| 432 return std::equal(std::begin(*list_), std::end(*list_), | 428 std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_), |
| 433 std::begin(*(other->list_)), | 429 [](const Value::ListStorage::value_type& u, |
| 434 [](const ListStorage::value_type& lhs, | 430 const Value::ListStorage::value_type& v) { return *u == *v; }); |
| 435 const ListStorage::value_type& rhs) { | |
| 436 return lhs->Equals(rhs.get()); | |
| 437 }); | |
| 438 } | |
| 439 } | 431 } |
| 440 | 432 |
| 441 NOTREACHED(); | 433 NOTREACHED(); |
| 442 return false; | 434 return false; |
| 443 } | 435 } |
| 444 | 436 |
| 437 bool operator!=(const Value& lhs, const Value& rhs) { |
| 438 return !(lhs == rhs); |
| 439 } |
| 440 |
| 441 bool operator<(const Value& lhs, const Value& rhs) { |
| 442 if (lhs.type_ != rhs.type_) |
| 443 return lhs.type_ < rhs.type_; |
| 444 |
| 445 switch (lhs.type_) { |
| 446 case Value::Type::NONE: |
| 447 return false; |
| 448 case Value::Type::BOOLEAN: |
| 449 return lhs.bool_value_ < rhs.bool_value_; |
| 450 case Value::Type::INTEGER: |
| 451 return lhs.int_value_ < rhs.int_value_; |
| 452 case Value::Type::DOUBLE: |
| 453 return lhs.double_value_ < rhs.double_value_; |
| 454 case Value::Type::STRING: |
| 455 return *lhs.string_value_ < *rhs.string_value_; |
| 456 case Value::Type::BINARY: |
| 457 return *lhs.binary_value_ < *rhs.binary_value_; |
| 458 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue |
| 459 // are completely inlined. |
| 460 case Value::Type::DICTIONARY: |
| 461 return std::lexicographical_compare( |
| 462 std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_), |
| 463 std::begin(**rhs.dict_ptr_), std::end(**rhs.dict_ptr_), |
| 464 [](const Value::DictStorage::value_type& u, |
| 465 const Value::DictStorage::value_type& v) { |
| 466 return std::tie(u.first, *u.second) < std::tie(v.first, *v.second); |
| 467 }); |
| 468 case Value::Type::LIST: |
| 469 return std::lexicographical_compare( |
| 470 std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_), |
| 471 std::end(*rhs.list_), |
| 472 [](const Value::ListStorage::value_type& u, |
| 473 const Value::ListStorage::value_type& v) { return *u < *v; }); |
| 474 } |
| 475 |
| 476 NOTREACHED(); |
| 477 return false; |
| 478 } |
| 479 |
| 480 bool operator>(const Value& lhs, const Value& rhs) { |
| 481 return rhs < lhs; |
| 482 } |
| 483 |
| 484 bool operator<=(const Value& lhs, const Value& rhs) { |
| 485 return !(rhs < lhs); |
| 486 } |
| 487 |
| 488 bool operator>=(const Value& lhs, const Value& rhs) { |
| 489 return !(lhs < rhs); |
| 490 } |
| 491 |
| 492 bool Value::Equals(const Value* other) const { |
| 493 DCHECK(other); |
| 494 return *this == *other; |
| 495 } |
| 496 |
| 445 // static | 497 // static |
| 446 bool Value::Equals(const Value* a, const Value* b) { | 498 bool Value::Equals(const Value* a, const Value* b) { |
| 447 if ((a == NULL) && (b == NULL)) return true; | 499 if ((a == NULL) && (b == NULL)) |
| 448 if ((a == NULL) ^ (b == NULL)) return false; | 500 return true; |
| 449 return a->Equals(b); | 501 if ((a == NULL) ^ (b == NULL)) |
| 502 return false; |
| 503 return *a == *b; |
| 450 } | 504 } |
| 451 | 505 |
| 452 void Value::InternalCopyFundamentalValue(const Value& that) { | 506 void Value::InternalCopyFundamentalValue(const Value& that) { |
| 453 switch (type_) { | 507 switch (type_) { |
| 454 case Type::NONE: | 508 case Type::NONE: |
| 455 // Nothing to do. | 509 // Nothing to do. |
| 456 return; | 510 return; |
| 457 | 511 |
| 458 case Type::BOOLEAN: | 512 case Type::BOOLEAN: |
| 459 bool_value_ = that.bool_value_; | 513 bool_value_ = that.bool_value_; |
| (...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 | 1254 |
| 1201 if (out_value) | 1255 if (out_value) |
| 1202 *out_value = std::move((*list_)[index]); | 1256 *out_value = std::move((*list_)[index]); |
| 1203 | 1257 |
| 1204 list_->erase(list_->begin() + index); | 1258 list_->erase(list_->begin() + index); |
| 1205 return true; | 1259 return true; |
| 1206 } | 1260 } |
| 1207 | 1261 |
| 1208 bool ListValue::Remove(const Value& value, size_t* index) { | 1262 bool ListValue::Remove(const Value& value, size_t* index) { |
| 1209 for (auto it = list_->begin(); it != list_->end(); ++it) { | 1263 for (auto it = list_->begin(); it != list_->end(); ++it) { |
| 1210 if ((*it)->Equals(&value)) { | 1264 if (**it == value) { |
| 1211 size_t previous_index = it - list_->begin(); | 1265 size_t previous_index = it - list_->begin(); |
| 1212 list_->erase(it); | 1266 list_->erase(it); |
| 1213 | 1267 |
| 1214 if (index) | 1268 if (index) |
| 1215 *index = previous_index; | 1269 *index = previous_index; |
| 1216 return true; | 1270 return true; |
| 1217 } | 1271 } |
| 1218 } | 1272 } |
| 1219 return false; | 1273 return false; |
| 1220 } | 1274 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 void ListValue::AppendStrings(const std::vector<string16>& in_values) { | 1322 void ListValue::AppendStrings(const std::vector<string16>& in_values) { |
| 1269 for (std::vector<string16>::const_iterator it = in_values.begin(); | 1323 for (std::vector<string16>::const_iterator it = in_values.begin(); |
| 1270 it != in_values.end(); ++it) { | 1324 it != in_values.end(); ++it) { |
| 1271 AppendString(*it); | 1325 AppendString(*it); |
| 1272 } | 1326 } |
| 1273 } | 1327 } |
| 1274 | 1328 |
| 1275 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { | 1329 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { |
| 1276 DCHECK(in_value); | 1330 DCHECK(in_value); |
| 1277 for (const auto& entry : *list_) { | 1331 for (const auto& entry : *list_) { |
| 1278 if (entry->Equals(in_value.get())) { | 1332 if (*entry == *in_value) |
| 1279 return false; | 1333 return false; |
| 1280 } | |
| 1281 } | 1334 } |
| 1282 list_->push_back(std::move(in_value)); | 1335 list_->push_back(std::move(in_value)); |
| 1283 return true; | 1336 return true; |
| 1284 } | 1337 } |
| 1285 | 1338 |
| 1286 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { | 1339 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { |
| 1287 DCHECK(in_value); | 1340 DCHECK(in_value); |
| 1288 if (index > list_->size()) | 1341 if (index > list_->size()) |
| 1289 return false; | 1342 return false; |
| 1290 | 1343 |
| 1291 list_->insert(list_->begin() + index, std::move(in_value)); | 1344 list_->insert(list_->begin() + index, std::move(in_value)); |
| 1292 return true; | 1345 return true; |
| 1293 } | 1346 } |
| 1294 | 1347 |
| 1295 ListValue::const_iterator ListValue::Find(const Value& value) const { | 1348 ListValue::const_iterator ListValue::Find(const Value& value) const { |
| 1296 return std::find_if(list_->begin(), list_->end(), | 1349 return std::find_if(list_->begin(), list_->end(), |
| 1297 [&value](const std::unique_ptr<Value>& entry) { | 1350 [&value](const std::unique_ptr<Value>& entry) { |
| 1298 return entry->Equals(&value); | 1351 return *entry == value; |
| 1299 }); | 1352 }); |
| 1300 } | 1353 } |
| 1301 | 1354 |
| 1302 void ListValue::Swap(ListValue* other) { | 1355 void ListValue::Swap(ListValue* other) { |
| 1303 CHECK(other->is_list()); | 1356 CHECK(other->is_list()); |
| 1304 list_->swap(*(other->list_)); | 1357 list_->swap(*(other->list_)); |
| 1305 } | 1358 } |
| 1306 | 1359 |
| 1307 ListValue* ListValue::DeepCopy() const { | 1360 ListValue* ListValue::DeepCopy() const { |
| 1308 return static_cast<ListValue*>(Value::DeepCopy()); | 1361 return static_cast<ListValue*>(Value::DeepCopy()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1325 } | 1378 } |
| 1326 | 1379 |
| 1327 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1380 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
| 1328 if (static_cast<int>(type) < 0 || | 1381 if (static_cast<int>(type) < 0 || |
| 1329 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1382 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
| 1330 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1383 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
| 1331 return out << Value::GetTypeName(type); | 1384 return out << Value::GetTypeName(type); |
| 1332 } | 1385 } |
| 1333 | 1386 |
| 1334 } // namespace base | 1387 } // namespace base |
| OLD | NEW |