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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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::operator=(const Value& that) { | 175 Value& Value::operator=(const Value& that) { |
176 if (this != &that) { | 176 if (type_ == that.type_) { |
177 if (type_ == that.type_) { | 177 InternalCopyAssignFromSameType(that); |
178 InternalCopyAssignFromSameType(that); | 178 } else { |
179 } else { | 179 // this is not a self assignment because the type_ doesn't match. |
vabr (Chromium)
2017/03/13 10:56:01
this -> This
dyaroshev
2017/03/13 21:15:42
Done.
| |
180 InternalCleanup(); | 180 InternalCleanup(); |
181 InternalCopyConstructFrom(that); | 181 InternalCopyConstructFrom(that); |
182 } | |
183 } | 182 } |
184 | 183 |
185 return *this; | 184 return *this; |
186 } | 185 } |
187 | 186 |
188 Value& Value::operator=(Value&& that) { | 187 Value& Value::operator=(Value&& that) { |
189 if (this != &that) { | 188 DCHECK(this != &that) << " attempt to self move assign."; |
dcheng
2017/03/11 06:30:07
Super minor nit: no space at the beginning of the
dyaroshev
2017/03/13 21:15:42
Done.
| |
190 if (type_ == that.type_) { | 189 InternalCleanup(); |
191 InternalMoveAssignFromSameType(std::move(that)); | 190 InternalMoveConstructFrom(std::move(that)); |
192 } else { | |
193 InternalCleanup(); | |
194 InternalMoveConstructFrom(std::move(that)); | |
195 } | |
196 } | |
197 | 191 |
198 return *this; | 192 return *this; |
199 } | 193 } |
200 | 194 |
201 Value::~Value() { | 195 Value::~Value() { |
202 InternalCleanup(); | 196 InternalCleanup(); |
203 } | 197 } |
204 | 198 |
205 // static | 199 // static |
206 const char* Value::GetTypeName(Value::Type type) { | 200 const char* Value::GetTypeName(Value::Type type) { |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 case Type::DICTIONARY: | 520 case Type::DICTIONARY: |
527 dict_ptr_.InitFromMove(std::move(that.dict_ptr_)); | 521 dict_ptr_.InitFromMove(std::move(that.dict_ptr_)); |
528 return; | 522 return; |
529 case Type::LIST: | 523 case Type::LIST: |
530 list_.InitFromMove(std::move(that.list_)); | 524 list_.InitFromMove(std::move(that.list_)); |
531 return; | 525 return; |
532 } | 526 } |
533 } | 527 } |
534 | 528 |
535 void Value::InternalCopyAssignFromSameType(const Value& that) { | 529 void Value::InternalCopyAssignFromSameType(const Value& that) { |
536 CHECK_EQ(type_, that.type_); | 530 CHECK_EQ(type_, that.type_); |
dcheng
2017/03/11 06:30:07
While you're fixing this, do mind changing these t
vabr (Chromium)
2017/03/13 10:56:01
The reason is potential execution of random pieces
dyaroshev
2017/03/13 21:15:42
I see - you worried about slicing causing executio
dcheng
2017/03/14 05:08:01
While it's true that we should be using CHECK when
| |
537 | 531 |
538 switch (type_) { | 532 switch (type_) { |
539 case Type::NONE: | 533 case Type::NONE: |
540 case Type::BOOLEAN: | 534 case Type::BOOLEAN: |
541 case Type::INTEGER: | 535 case Type::INTEGER: |
542 case Type::DOUBLE: | 536 case Type::DOUBLE: |
543 InternalCopyFundamentalValue(that); | 537 InternalCopyFundamentalValue(that); |
544 return; | 538 return; |
545 | 539 |
546 case Type::STRING: | 540 case Type::STRING: |
547 *string_value_ = *that.string_value_; | 541 *string_value_ = *that.string_value_; |
548 return; | 542 return; |
549 case Type::BINARY: | 543 case Type::BINARY: |
550 *binary_value_ = *that.binary_value_; | 544 *binary_value_ = *that.binary_value_; |
551 return; | 545 return; |
552 // DictStorage and ListStorage are move-only types due to the presence of | 546 // DictStorage and ListStorage are move-only types due to the presence of |
553 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. | 547 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. |
554 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage | 548 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage |
555 // can be copied directly. | 549 // can be copied directly. |
556 case Type::DICTIONARY: | 550 case Type::DICTIONARY: |
557 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); | 551 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); |
558 return; | 552 return; |
559 case Type::LIST: | 553 case Type::LIST: |
560 *list_ = std::move(*that.CreateDeepCopy()->list_); | 554 *list_ = std::move(*that.CreateDeepCopy()->list_); |
561 return; | 555 return; |
562 } | 556 } |
563 } | 557 } |
564 | 558 |
565 void Value::InternalMoveAssignFromSameType(Value&& that) { | |
566 CHECK_EQ(type_, that.type_); | |
567 | |
568 switch (type_) { | |
569 case Type::NONE: | |
570 case Type::BOOLEAN: | |
571 case Type::INTEGER: | |
572 case Type::DOUBLE: | |
573 InternalCopyFundamentalValue(that); | |
574 return; | |
575 | |
576 case Type::STRING: | |
577 *string_value_ = std::move(*that.string_value_); | |
578 return; | |
579 case Type::BINARY: | |
580 *binary_value_ = std::move(*that.binary_value_); | |
581 return; | |
582 case Type::DICTIONARY: | |
583 *dict_ptr_ = std::move(*that.dict_ptr_); | |
584 return; | |
585 case Type::LIST: | |
586 *list_ = std::move(*that.list_); | |
587 return; | |
588 } | |
589 } | |
590 | |
591 void Value::InternalCleanup() { | 559 void Value::InternalCleanup() { |
592 switch (type_) { | 560 switch (type_) { |
593 case Type::NONE: | 561 case Type::NONE: |
594 case Type::BOOLEAN: | 562 case Type::BOOLEAN: |
595 case Type::INTEGER: | 563 case Type::INTEGER: |
596 case Type::DOUBLE: | 564 case Type::DOUBLE: |
597 // Nothing to do | 565 // Nothing to do |
598 return; | 566 return; |
599 | 567 |
600 case Type::STRING: | 568 case Type::STRING: |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1355 } | 1323 } |
1356 | 1324 |
1357 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1325 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
1358 if (static_cast<int>(type) < 0 || | 1326 if (static_cast<int>(type) < 0 || |
1359 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1327 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
1360 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1328 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
1361 return out << Value::GetTypeName(type); | 1329 return out << Value::GetTypeName(type); |
1362 } | 1330 } |
1363 | 1331 |
1364 } // namespace base | 1332 } // namespace base |
OLD | NEW |