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

Side by Side Diff: base/optional_unittest.cc

Issue 2000043002: Make base::Optional trivially destructible when possible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build on Windows. Created 4 years, 6 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/optional.h ('k') | base/template_util.h » ('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 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « base/optional.h ('k') | base/template_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698