| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/optional.h" | 5 #include "base/optional.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 10 |
| 11 namespace base { | 11 namespace base { |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // Object used to test complex object with Optional<T> in addition of the move | 15 // Object used to test complex object with Optional<T> in addition of the move |
| 16 // semantics. | 16 // semantics. |
| 17 class TestObject { | 17 class TestObject { |
| 18 public: | 18 public: |
| 19 enum class State { | 19 enum class State { |
| 20 DEFAULT_CONSTRUCTED, | 20 DEFAULT_CONSTRUCTED, |
| 21 VALUE_CONSTRUCTED, | 21 VALUE_CONSTRUCTED, |
| 22 COPY_CONSTRUCTED, | 22 COPY_CONSTRUCTED, |
| 23 MOVE_CONSTRUCTED, | 23 MOVE_CONSTRUCTED, |
| 24 MOVED_FROM, | 24 MOVED_FROM, |
| 25 COPY_ASSIGNED, |
| 26 MOVE_ASSIGNED, |
| 27 SWAPPED, |
| 25 }; | 28 }; |
| 26 | 29 |
| 27 TestObject() : foo_(0), bar_(0.0), state_(State::DEFAULT_CONSTRUCTED) {} | 30 TestObject() : foo_(0), bar_(0.0), state_(State::DEFAULT_CONSTRUCTED) {} |
| 28 | 31 |
| 29 TestObject(int foo, double bar) | 32 TestObject(int foo, double bar) |
| 30 : foo_(foo), bar_(bar), state_(State::VALUE_CONSTRUCTED) {} | 33 : foo_(foo), bar_(bar), state_(State::VALUE_CONSTRUCTED) {} |
| 31 | 34 |
| 32 TestObject(const TestObject& other) | 35 TestObject(const TestObject& other) |
| 33 : foo_(other.foo_), bar_(other.bar_), state_(State::COPY_CONSTRUCTED) {} | 36 : foo_(other.foo_), bar_(other.bar_), state_(State::COPY_CONSTRUCTED) {} |
| 34 | 37 |
| 35 TestObject(TestObject&& other) | 38 TestObject(TestObject&& other) |
| 36 : foo_(std::move(other.foo_)), | 39 : foo_(std::move(other.foo_)), |
| 37 bar_(std::move(other.bar_)), | 40 bar_(std::move(other.bar_)), |
| 38 state_(State::MOVE_CONSTRUCTED) { | 41 state_(State::MOVE_CONSTRUCTED) { |
| 39 other.state_ = State::MOVED_FROM; | 42 other.state_ = State::MOVED_FROM; |
| 40 } | 43 } |
| 41 | 44 |
| 42 TestObject& operator=(const TestObject& other) { | 45 TestObject& operator=(const TestObject& other) { |
| 43 foo_ = other.foo_; | 46 foo_ = other.foo_; |
| 44 bar_ = other.bar_; | 47 bar_ = other.bar_; |
| 45 state_ = State::COPY_CONSTRUCTED; | 48 state_ = State::COPY_ASSIGNED; |
| 46 return *this; | 49 return *this; |
| 47 } | 50 } |
| 48 | 51 |
| 52 TestObject& operator=(TestObject&& other) { |
| 53 foo_ = other.foo_; |
| 54 bar_ = other.bar_; |
| 55 state_ = State::MOVE_ASSIGNED; |
| 56 other.state_ = State::MOVED_FROM; |
| 57 return *this; |
| 58 } |
| 59 |
| 60 void Swap(TestObject* other) { |
| 61 using std::swap; |
| 62 swap(foo_, other->foo_); |
| 63 swap(bar_, other->bar_); |
| 64 state_ = State::SWAPPED; |
| 65 other->state_ = State::SWAPPED; |
| 66 } |
| 67 |
| 49 bool operator==(const TestObject& other) const { | 68 bool operator==(const TestObject& other) const { |
| 50 return foo_ == other.foo_ && bar_ == other.bar_; | 69 return foo_ == other.foo_ && bar_ == other.bar_; |
| 51 } | 70 } |
| 52 | 71 |
| 53 int foo() const { return foo_; } | 72 int foo() const { return foo_; } |
| 54 State state() const { return state_; } | 73 State state() const { return state_; } |
| 55 | 74 |
| 56 private: | 75 private: |
| 57 int foo_; | 76 int foo_; |
| 58 double bar_; | 77 double bar_; |
| 59 State state_; | 78 State state_; |
| 60 }; | 79 }; |
| 61 | 80 |
| 81 // Implementing Swappable concept. |
| 82 void swap(TestObject& lhs, TestObject& rhs) { |
| 83 lhs.Swap(&rhs); |
| 84 } |
| 85 |
| 86 class NonTriviallyDestructible { |
| 87 ~NonTriviallyDestructible() {} |
| 88 }; |
| 89 |
| 62 } // anonymous namespace | 90 } // anonymous namespace |
| 63 | 91 |
| 92 static_assert(is_trivially_destructible<Optional<int>>::value, |
| 93 "OptionalIsTriviallyDestructible"); |
| 94 |
| 95 static_assert( |
| 96 !is_trivially_destructible<Optional<NonTriviallyDestructible>>::value, |
| 97 "OptionalIsTriviallyDestructible"); |
| 98 |
| 64 TEST(OptionalTest, DefaultConstructor) { | 99 TEST(OptionalTest, DefaultConstructor) { |
| 65 { | 100 { |
| 66 Optional<float> o; | 101 Optional<float> o; |
| 67 EXPECT_FALSE(o); | 102 EXPECT_FALSE(o); |
| 68 } | 103 } |
| 69 | 104 |
| 70 { | 105 { |
| 71 Optional<std::string> o; | 106 Optional<std::string> o; |
| 72 EXPECT_FALSE(o); | 107 EXPECT_FALSE(o); |
| 73 } | 108 } |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 EXPECT_EQ("foo", a.value()); | 243 EXPECT_EQ("foo", a.value()); |
| 209 } | 244 } |
| 210 | 245 |
| 211 { | 246 { |
| 212 Optional<TestObject> a(base::in_place, 0, 0.1); | 247 Optional<TestObject> a(base::in_place, 0, 0.1); |
| 213 EXPECT_TRUE(!!a); | 248 EXPECT_TRUE(!!a); |
| 214 EXPECT_TRUE(TestObject(0, 0.1) == a.value()); | 249 EXPECT_TRUE(TestObject(0, 0.1) == a.value()); |
| 215 } | 250 } |
| 216 } | 251 } |
| 217 | 252 |
| 253 TEST(OptionalTest, NulloptConstructor) { |
| 254 Optional<int> a = base::nullopt; |
| 255 EXPECT_FALSE(a); |
| 256 } |
| 257 |
| 218 TEST(OptionalTest, AssignValue) { | 258 TEST(OptionalTest, AssignValue) { |
| 219 { | 259 { |
| 220 Optional<float> a; | 260 Optional<float> a; |
| 221 EXPECT_FALSE(a); | 261 EXPECT_FALSE(a); |
| 222 a = 0.1f; | 262 a = 0.1f; |
| 223 EXPECT_TRUE(a); | 263 EXPECT_TRUE(a); |
| 224 | 264 |
| 225 Optional<float> b(0.1f); | 265 Optional<float> b(0.1f); |
| 226 EXPECT_TRUE(a == b); | 266 EXPECT_TRUE(a == b); |
| 227 } | 267 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 238 | 278 |
| 239 { | 279 { |
| 240 Optional<TestObject> a; | 280 Optional<TestObject> a; |
| 241 EXPECT_FALSE(!!a); | 281 EXPECT_FALSE(!!a); |
| 242 a = TestObject(3, 0.1); | 282 a = TestObject(3, 0.1); |
| 243 EXPECT_TRUE(!!a); | 283 EXPECT_TRUE(!!a); |
| 244 | 284 |
| 245 Optional<TestObject> b(TestObject(3, 0.1)); | 285 Optional<TestObject> b(TestObject(3, 0.1)); |
| 246 EXPECT_TRUE(a == b); | 286 EXPECT_TRUE(a == b); |
| 247 } | 287 } |
| 288 |
| 289 { |
| 290 Optional<TestObject> a = TestObject(4, 1.0); |
| 291 EXPECT_TRUE(!!a); |
| 292 a = TestObject(3, 0.1); |
| 293 EXPECT_TRUE(!!a); |
| 294 |
| 295 Optional<TestObject> b(TestObject(3, 0.1)); |
| 296 EXPECT_TRUE(a == b); |
| 297 } |
| 248 } | 298 } |
| 249 | 299 |
| 250 TEST(OptionalTest, AssignObject) { | 300 TEST(OptionalTest, AssignObject) { |
| 251 { | 301 { |
| 252 Optional<float> a; | 302 Optional<float> a; |
| 253 Optional<float> b(0.1f); | 303 Optional<float> b(0.1f); |
| 254 a = b; | 304 a = b; |
| 255 | 305 |
| 256 EXPECT_TRUE(a); | 306 EXPECT_TRUE(a); |
| 257 EXPECT_EQ(a.value(), 0.1f); | 307 EXPECT_EQ(a.value(), 0.1f); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 270 | 320 |
| 271 { | 321 { |
| 272 Optional<TestObject> a; | 322 Optional<TestObject> a; |
| 273 Optional<TestObject> b(TestObject(3, 0.1)); | 323 Optional<TestObject> b(TestObject(3, 0.1)); |
| 274 a = b; | 324 a = b; |
| 275 | 325 |
| 276 EXPECT_TRUE(!!a); | 326 EXPECT_TRUE(!!a); |
| 277 EXPECT_TRUE(a.value() == TestObject(3, 0.1)); | 327 EXPECT_TRUE(a.value() == TestObject(3, 0.1)); |
| 278 EXPECT_TRUE(a == b); | 328 EXPECT_TRUE(a == b); |
| 279 } | 329 } |
| 330 |
| 331 { |
| 332 Optional<TestObject> a(TestObject(4, 1.0)); |
| 333 Optional<TestObject> b(TestObject(3, 0.1)); |
| 334 a = b; |
| 335 |
| 336 EXPECT_TRUE(!!a); |
| 337 EXPECT_TRUE(a.value() == TestObject(3, 0.1)); |
| 338 EXPECT_TRUE(a == b); |
| 339 } |
| 280 } | 340 } |
| 281 | 341 |
| 282 TEST(OptionalTest, AssignObject_rvalue) { | 342 TEST(OptionalTest, AssignObject_rvalue) { |
| 283 { | 343 { |
| 284 Optional<float> a; | 344 Optional<float> a; |
| 285 Optional<float> b(0.1f); | 345 Optional<float> b(0.1f); |
| 286 a = std::move(b); | 346 a = std::move(b); |
| 287 | 347 |
| 288 EXPECT_TRUE(a); | 348 EXPECT_TRUE(a); |
| 289 EXPECT_TRUE(b); | 349 EXPECT_TRUE(b); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 305 Optional<TestObject> b(TestObject(3, 0.1)); | 365 Optional<TestObject> b(TestObject(3, 0.1)); |
| 306 a = std::move(b); | 366 a = std::move(b); |
| 307 | 367 |
| 308 EXPECT_TRUE(!!a); | 368 EXPECT_TRUE(!!a); |
| 309 EXPECT_TRUE(!!b); | 369 EXPECT_TRUE(!!b); |
| 310 EXPECT_TRUE(TestObject(3, 0.1) == a.value()); | 370 EXPECT_TRUE(TestObject(3, 0.1) == a.value()); |
| 311 | 371 |
| 312 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, a->state()); | 372 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, a->state()); |
| 313 EXPECT_EQ(TestObject::State::MOVED_FROM, b->state()); | 373 EXPECT_EQ(TestObject::State::MOVED_FROM, b->state()); |
| 314 } | 374 } |
| 375 |
| 376 { |
| 377 Optional<TestObject> a(TestObject(4, 1.0)); |
| 378 Optional<TestObject> b(TestObject(3, 0.1)); |
| 379 a = std::move(b); |
| 380 |
| 381 EXPECT_TRUE(!!a); |
| 382 EXPECT_TRUE(!!b); |
| 383 EXPECT_TRUE(TestObject(3, 0.1) == a.value()); |
| 384 |
| 385 EXPECT_EQ(TestObject::State::MOVE_ASSIGNED, a->state()); |
| 386 EXPECT_EQ(TestObject::State::MOVED_FROM, b->state()); |
| 387 } |
| 315 } | 388 } |
| 316 | 389 |
| 317 TEST(OptionalTest, AssignNull) { | 390 TEST(OptionalTest, AssignNull) { |
| 318 { | 391 { |
| 319 Optional<float> a(0.1f); | 392 Optional<float> a(0.1f); |
| 320 Optional<float> b(0.2f); | 393 Optional<float> b(0.2f); |
| 321 a = base::nullopt; | 394 a = base::nullopt; |
| 322 b = base::nullopt; | 395 b = base::nullopt; |
| 323 EXPECT_EQ(a, b); | 396 EXPECT_EQ(a, b); |
| 324 } | 397 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 | 518 |
| 446 TEST(OptionalTest, Swap_bothValue) { | 519 TEST(OptionalTest, Swap_bothValue) { |
| 447 Optional<TestObject> a(TestObject(0, 0.1)); | 520 Optional<TestObject> a(TestObject(0, 0.1)); |
| 448 Optional<TestObject> b(TestObject(1, 0.3)); | 521 Optional<TestObject> b(TestObject(1, 0.3)); |
| 449 a.swap(b); | 522 a.swap(b); |
| 450 | 523 |
| 451 EXPECT_TRUE(!!a); | 524 EXPECT_TRUE(!!a); |
| 452 EXPECT_TRUE(!!b); | 525 EXPECT_TRUE(!!b); |
| 453 EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42))); | 526 EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42))); |
| 454 EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42))); | 527 EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42))); |
| 528 EXPECT_EQ(TestObject::State::SWAPPED, a->state()); |
| 529 EXPECT_EQ(TestObject::State::SWAPPED, b->state()); |
| 455 } | 530 } |
| 456 | 531 |
| 457 TEST(OptionalTest, Emplace) { | 532 TEST(OptionalTest, Emplace) { |
| 458 { | 533 { |
| 459 Optional<float> a(0.1f); | 534 Optional<float> a(0.1f); |
| 460 a.emplace(0.3f); | 535 a.emplace(0.3f); |
| 461 | 536 |
| 462 EXPECT_TRUE(a); | 537 EXPECT_TRUE(a); |
| 463 EXPECT_EQ(0.3f, a.value()); | 538 EXPECT_EQ(0.3f, a.value()); |
| 464 } | 539 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 { | 1204 { |
| 1130 Optional<TestObject> o = base::make_optional(TestObject(3, 0.1)); | 1205 Optional<TestObject> o = base::make_optional(TestObject(3, 0.1)); |
| 1131 EXPECT_TRUE(!!o); | 1206 EXPECT_TRUE(!!o); |
| 1132 EXPECT_TRUE(TestObject(3, 0.1) == *o); | 1207 EXPECT_TRUE(TestObject(3, 0.1) == *o); |
| 1133 | 1208 |
| 1134 TestObject value = TestObject(0, 0.42); | 1209 TestObject value = TestObject(0, 0.42); |
| 1135 o = base::make_optional(std::move(value)); | 1210 o = base::make_optional(std::move(value)); |
| 1136 EXPECT_TRUE(!!o); | 1211 EXPECT_TRUE(!!o); |
| 1137 EXPECT_TRUE(TestObject(0, 0.42) == *o); | 1212 EXPECT_TRUE(TestObject(0, 0.42) == *o); |
| 1138 EXPECT_EQ(TestObject::State::MOVED_FROM, value.state()); | 1213 EXPECT_EQ(TestObject::State::MOVED_FROM, value.state()); |
| 1139 EXPECT_EQ(TestObject::State::COPY_CONSTRUCTED, o->state()); | 1214 EXPECT_EQ(TestObject::State::MOVE_ASSIGNED, o->state()); |
| 1140 | 1215 |
| 1141 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, | 1216 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, |
| 1142 base::make_optional(std::move(value))->state()); | 1217 base::make_optional(std::move(value))->state()); |
| 1143 } | 1218 } |
| 1144 } | 1219 } |
| 1145 | 1220 |
| 1146 TEST(OptionalTest, NonMemberSwap_bothNoValue) { | 1221 TEST(OptionalTest, NonMemberSwap_bothNoValue) { |
| 1147 Optional<TestObject> a, b; | 1222 Optional<TestObject> a, b; |
| 1148 base::swap(a, b); | 1223 base::swap(a, b); |
| 1149 | 1224 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1177 | 1252 |
| 1178 TEST(OptionalTest, NonMemberSwap_bothValue) { | 1253 TEST(OptionalTest, NonMemberSwap_bothValue) { |
| 1179 Optional<TestObject> a(TestObject(0, 0.1)); | 1254 Optional<TestObject> a(TestObject(0, 0.1)); |
| 1180 Optional<TestObject> b(TestObject(1, 0.3)); | 1255 Optional<TestObject> b(TestObject(1, 0.3)); |
| 1181 base::swap(a, b); | 1256 base::swap(a, b); |
| 1182 | 1257 |
| 1183 EXPECT_TRUE(!!a); | 1258 EXPECT_TRUE(!!a); |
| 1184 EXPECT_TRUE(!!b); | 1259 EXPECT_TRUE(!!b); |
| 1185 EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42))); | 1260 EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42))); |
| 1186 EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42))); | 1261 EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42))); |
| 1262 EXPECT_EQ(TestObject::State::SWAPPED, a->state()); |
| 1263 EXPECT_EQ(TestObject::State::SWAPPED, b->state()); |
| 1187 } | 1264 } |
| 1188 | 1265 |
| 1189 TEST(OptionalTest, Hash_OptionalReflectsInternal) { | 1266 TEST(OptionalTest, Hash_OptionalReflectsInternal) { |
| 1190 { | 1267 { |
| 1191 std::hash<int> int_hash; | 1268 std::hash<int> int_hash; |
| 1192 std::hash<Optional<int>> opt_int_hash; | 1269 std::hash<Optional<int>> opt_int_hash; |
| 1193 | 1270 |
| 1194 EXPECT_EQ(int_hash(1), opt_int_hash(Optional<int>(1))); | 1271 EXPECT_EQ(int_hash(1), opt_int_hash(Optional<int>(1))); |
| 1195 } | 1272 } |
| 1196 | 1273 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1215 std::set<Optional<int>> setOptInt; | 1292 std::set<Optional<int>> setOptInt; |
| 1216 | 1293 |
| 1217 EXPECT_EQ(setOptInt.end(), setOptInt.find(42)); | 1294 EXPECT_EQ(setOptInt.end(), setOptInt.find(42)); |
| 1218 | 1295 |
| 1219 setOptInt.insert(Optional<int>(3)); | 1296 setOptInt.insert(Optional<int>(3)); |
| 1220 EXPECT_EQ(setOptInt.end(), setOptInt.find(42)); | 1297 EXPECT_EQ(setOptInt.end(), setOptInt.find(42)); |
| 1221 EXPECT_NE(setOptInt.end(), setOptInt.find(3)); | 1298 EXPECT_NE(setOptInt.end(), setOptInt.find(3)); |
| 1222 } | 1299 } |
| 1223 | 1300 |
| 1224 } // namespace base | 1301 } // namespace base |
| OLD | NEW |