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 |