1 | // Originally taken from |
2 | // https://raw.githubusercontent.com/cryfs/cryfs/14ad22570ddacef22d5ff139cdff68a54fc8234d/test/cpp-utils/either_test.cpp |
3 | |
4 | #include <c10/macros/Macros.h> |
5 | #include <c10/util/either.h> |
6 | #include <gmock/gmock.h> |
7 | #include <gtest/gtest.h> |
8 | #include <sstream> |
9 | #include <vector> |
10 | |
11 | using c10::either; |
12 | using c10::make_left; |
13 | using c10::make_right; |
14 | using std::ostringstream; |
15 | using std::pair; |
16 | using std::string; |
17 | using std::tuple; |
18 | using std::vector; |
19 | |
20 | namespace { |
21 | class MovableOnly final { |
22 | public: |
23 | explicit MovableOnly(int value) : _value(value) {} |
24 | MovableOnly(const MovableOnly&) = delete; |
25 | MovableOnly& operator=(const MovableOnly&) = delete; |
26 | |
27 | MovableOnly(MovableOnly&& rhs) : _value(rhs._value) { |
28 | rhs._value = 0; |
29 | } |
30 | |
31 | MovableOnly& operator=(MovableOnly&& rhs) { |
32 | _value = rhs._value; |
33 | rhs._value = 0; |
34 | return *this; |
35 | } |
36 | |
37 | int value() const { |
38 | return _value; |
39 | } |
40 | |
41 | private: |
42 | int _value; |
43 | }; |
44 | |
45 | bool operator==(const MovableOnly& lhs, const MovableOnly& rhs) { |
46 | return lhs.value() == rhs.value(); |
47 | } |
48 | |
49 | template <class T> |
50 | void test_with_matrix( |
51 | std::vector<std::function<void(std::function<void(T&)>)>> setups, |
52 | std::vector<std::function<void(T&)>> expectations) { |
53 | for (const auto& setup : setups) { |
54 | for (const auto& expectation : expectations) { |
55 | setup(expectation); |
56 | } |
57 | } |
58 | } |
59 | |
60 | template <class Left, class Right> |
61 | std::vector<std::function<void(either<Left, Right>&)>> EXPECT_IS_LEFT( |
62 | const Left& expected) { |
63 | return { |
64 | [&](either<Left, Right>& obj) { EXPECT_TRUE(obj.is_left()); }, |
65 | [&](either<Left, Right>& obj) { EXPECT_FALSE(obj.is_right()); }, |
66 | [&](either<Left, Right>& obj) { EXPECT_EQ(expected, obj.left()); }, |
67 | [&](either<Left, Right>& obj) { |
68 | EXPECT_EQ(expected, std::move(obj).left()); |
69 | }, |
70 | [&](either<Left, Right>& obj) { |
71 | // NOLINTNEXTLINE(hicpp-avoid-goto,cppcoreguidelines-avoid-goto) |
72 | EXPECT_ANY_THROW(obj.right()); |
73 | }, |
74 | [&](either<Left, Right>& obj) { |
75 | // NOLINTNEXTLINE(hicpp-avoid-goto,cppcoreguidelines-avoid-goto) |
76 | EXPECT_ANY_THROW(std::move(obj).right()); |
77 | }}; |
78 | } |
79 | |
80 | template <class Left, class Right> |
81 | std::vector<std::function<void(either<Left, Right>&)>> EXPECT_IS_RIGHT( |
82 | const Right& expected) { |
83 | return { |
84 | [&](either<Left, Right>& obj) { EXPECT_FALSE(obj.is_left()); }, |
85 | [&](either<Left, Right>& obj) { EXPECT_TRUE(obj.is_right()); }, |
86 | [&](either<Left, Right>& obj) { EXPECT_EQ(expected, obj.right()); }, |
87 | [&](either<Left, Right>& obj) { |
88 | EXPECT_EQ(expected, std::move(obj).right()); |
89 | }, |
90 | [&](either<Left, Right>& obj) { |
91 | // NOLINTNEXTLINE(hicpp-avoid-goto,cppcoreguidelines-avoid-goto) |
92 | EXPECT_ANY_THROW(obj.left()); |
93 | }, |
94 | [&](either<Left, Right>& obj) { |
95 | // NOLINTNEXTLINE(hicpp-avoid-goto,cppcoreguidelines-avoid-goto) |
96 | EXPECT_ANY_THROW(std::move(obj).left()); |
97 | }}; |
98 | } |
99 | |
100 | template <class Value> |
101 | std::vector<std::function<void(Value&)>> EXPECT_IS(const Value& v) { |
102 | return {[&](Value& obj) { return obj == v; }}; |
103 | } |
104 | |
105 | template <typename T> |
106 | struct StoreWith1ByteFlag { |
107 | T val; |
108 | char flag; |
109 | }; |
110 | |
111 | template <typename Left, typename Right> |
112 | void TestSpaceUsage() { |
113 | EXPECT_EQ( |
114 | std::max( |
115 | sizeof(StoreWith1ByteFlag<Left>), sizeof(StoreWith1ByteFlag<Right>)), |
116 | sizeof(either<Left, Right>)); |
117 | } |
118 | } // namespace |
119 | |
120 | TEST(EitherTest, SpaceUsage) { |
121 | TestSpaceUsage<char, int>(); |
122 | TestSpaceUsage<int, short>(); |
123 | TestSpaceUsage<char, short>(); |
124 | TestSpaceUsage<int, string>(); |
125 | TestSpaceUsage<string, vector<string>>(); |
126 | } |
127 | |
128 | TEST(EitherTest, givenLeft) { |
129 | test_with_matrix( |
130 | { |
131 | [](std::function<void(either<int, string>&)> test) { |
132 | either<int, string> a(4); |
133 | test(a); |
134 | }, |
135 | [](std::function<void(either<int, string>&)> test) { |
136 | either<int, string> a = 4; |
137 | test(a); |
138 | }, |
139 | }, |
140 | EXPECT_IS_LEFT<int, string>(4)); |
141 | } |
142 | |
143 | TEST(EitherTest, givenRight) { |
144 | test_with_matrix( |
145 | {[](std::function<void(either<int, string>&)> test) { |
146 | either<int, string> a("4" ); |
147 | test(a); |
148 | }, |
149 | [](std::function<void(either<int, string>&)> test) { |
150 | either<int, string> a = string("4" ); |
151 | test(a); |
152 | }}, |
153 | EXPECT_IS_RIGHT<int, string>("4" )); |
154 | } |
155 | |
156 | TEST(EitherTest, givenMakeLeft) { |
157 | test_with_matrix( |
158 | { |
159 | [](std::function<void(either<int, string>&)> test) { |
160 | either<int, string> a = make_left<int, string>(4); |
161 | test(a); |
162 | }, |
163 | [](std::function<void(either<int, string>&)> test) { |
164 | auto a = make_left<int, string>(4); |
165 | test(a); |
166 | }, |
167 | }, |
168 | EXPECT_IS_LEFT<int, string>(4)); |
169 | } |
170 | |
171 | TEST(EitherTest, givenMakeLeftWithSameType) { |
172 | test_with_matrix( |
173 | { |
174 | [](std::function<void(either<int, int>&)> test) { |
175 | either<int, int> a = make_left<int, int>(4); |
176 | test(a); |
177 | }, |
178 | [](std::function<void(either<int, int>&)> test) { |
179 | auto a = make_left<int, int>(4); |
180 | test(a); |
181 | }, |
182 | }, |
183 | EXPECT_IS_LEFT<int, int>(4)); |
184 | } |
185 | |
186 | TEST(EitherTest, givenMakeRight) { |
187 | test_with_matrix( |
188 | {[](std::function<void(either<int, string>&)> test) { |
189 | either<int, string> a = make_right<int, string>("4" ); |
190 | test(a); |
191 | }, |
192 | [](std::function<void(either<int, string>&)> test) { |
193 | auto a = make_right<int, string>("4" ); |
194 | test(a); |
195 | }}, |
196 | EXPECT_IS_RIGHT<int, string>("4" )); |
197 | } |
198 | |
199 | TEST(EitherTest, givenMakeRightWithSameType) { |
200 | test_with_matrix( |
201 | {[](std::function<void(either<string, string>&)> test) { |
202 | either<string, string> a = make_right<string, string>("4" ); |
203 | test(a); |
204 | }, |
205 | [](std::function<void(either<string, string>&)> test) { |
206 | auto a = make_right<string, string>("4" ); |
207 | test(a); |
208 | }}, |
209 | EXPECT_IS_RIGHT<string, string>("4" )); |
210 | } |
211 | |
212 | TEST(EitherTest, givenMovableOnlyMakeLeft) { |
213 | test_with_matrix( |
214 | { |
215 | [](std::function<void(either<MovableOnly, string>&)> test) { |
216 | either<MovableOnly, string> a = make_left<MovableOnly, string>(3); |
217 | test(a); |
218 | }, |
219 | [](std::function<void(either<MovableOnly, string>&)> test) { |
220 | auto a = make_left<MovableOnly, string>(3); |
221 | test(a); |
222 | }, |
223 | }, |
224 | EXPECT_IS_LEFT<MovableOnly, string>(MovableOnly(3))); |
225 | } |
226 | |
227 | TEST(EitherTest, givenMovableOnlyMakeRight) { |
228 | test_with_matrix( |
229 | {[](std::function<void(either<int, MovableOnly>&)> test) { |
230 | either<int, MovableOnly> a = make_right<int, MovableOnly>(3); |
231 | test(a); |
232 | }, |
233 | [](std::function<void(either<int, MovableOnly>&)> test) { |
234 | auto a = make_right<int, MovableOnly>(3); |
235 | test(a); |
236 | }}, |
237 | EXPECT_IS_RIGHT<int, MovableOnly>(MovableOnly(3))); |
238 | } |
239 | |
240 | TEST(EitherTest, givenMultiParamMakeLeft) { |
241 | test_with_matrix( |
242 | { |
243 | [](std::function<void(either<pair<int, int>, string>&)> test) { |
244 | either<pair<int, int>, string> a = |
245 | make_left<pair<int, int>, string>(5, 6); |
246 | test(a); |
247 | }, |
248 | [](std::function<void(either<pair<int, int>, string>&)> test) { |
249 | auto a = make_left<pair<int, int>, string>(5, 6); |
250 | test(a); |
251 | }, |
252 | }, |
253 | EXPECT_IS_LEFT<pair<int, int>, string>(pair<int, int>(5, 6))); |
254 | } |
255 | |
256 | TEST(EitherTest, givenMultiParamMakeRight) { |
257 | test_with_matrix( |
258 | {[](std::function<void(either<int, pair<int, int>>&)> test) { |
259 | either<int, pair<int, int>> a = make_right<int, pair<int, int>>(5, 6); |
260 | test(a); |
261 | }, |
262 | [](std::function<void(either<int, pair<int, int>>&)> test) { |
263 | auto a = make_right<int, pair<int, int>>(5, 6); |
264 | test(a); |
265 | }}, |
266 | EXPECT_IS_RIGHT<int, pair<int, int>>(pair<int, int>(5, 6))); |
267 | } |
268 | |
269 | TEST(EitherTest, givenLeftCopyConstructedFromValue_thenNewIsCorrect) { |
270 | test_with_matrix( |
271 | {[](std::function<void(either<string, int>&)> test) { |
272 | string a = "4" ; |
273 | either<string, int> b(a); |
274 | test(b); |
275 | }}, |
276 | EXPECT_IS_LEFT<string, int>("4" )); |
277 | } |
278 | |
279 | TEST(EitherTest, givenLeftCopyConstructedFromValue_thenOldIsCorrect) { |
280 | test_with_matrix( |
281 | {[](std::function<void(string&)> test) { |
282 | string a = "4" ; |
283 | either<string, int> b(a); |
284 | test(a); |
285 | }}, |
286 | EXPECT_IS<string>("4" )); |
287 | } |
288 | |
289 | TEST(EitherTest, givenRightCopyConstructedFromValue_thenNewIsCorrect) { |
290 | test_with_matrix( |
291 | {[](std::function<void(either<int, string>&)> test) { |
292 | string a = "4" ; |
293 | either<int, string> b(a); |
294 | test(b); |
295 | }}, |
296 | EXPECT_IS_RIGHT<int, string>("4" )); |
297 | } |
298 | |
299 | TEST(EitherTest, givenRightCopyConstructedFromValue_thenOldIsCorrect) { |
300 | test_with_matrix( |
301 | {[](std::function<void(string&)> test) { |
302 | string a = "4" ; |
303 | either<int, string> b(a); |
304 | test(a); |
305 | }}, |
306 | EXPECT_IS<string>("4" )); |
307 | } |
308 | |
309 | TEST(EitherTest, givenLeftMoveConstructedFromValue_thenNewIsCorrect) { |
310 | test_with_matrix( |
311 | {[](std::function<void(either<MovableOnly, int>&)> test) { |
312 | MovableOnly a(3); |
313 | either<MovableOnly, int> b(std::move(a)); |
314 | test(b); |
315 | }}, |
316 | EXPECT_IS_LEFT<MovableOnly, int>(MovableOnly(3))); |
317 | } |
318 | |
319 | TEST(EitherTest, givenLeftMoveConstructedFromValue_thenOldIsCorrect) { |
320 | test_with_matrix( |
321 | {[](std::function<void(MovableOnly&)> test) { |
322 | MovableOnly a(3); |
323 | either<MovableOnly, int> b(std::move(a)); |
324 | test(a); // NOLINT(bugprone-use-after-move) |
325 | }}, |
326 | EXPECT_IS<MovableOnly>(MovableOnly(0)) // 0 is moved-from value |
327 | ); |
328 | } |
329 | |
330 | TEST(EitherTest, givenRightMoveConstructedFromValue_thenNewIsCorrect) { |
331 | test_with_matrix( |
332 | {[](std::function<void(either<int, MovableOnly>&)> test) { |
333 | MovableOnly a(3); |
334 | either<int, MovableOnly> b(std::move(a)); |
335 | test(b); |
336 | }}, |
337 | EXPECT_IS_RIGHT<int, MovableOnly>(MovableOnly(3))); |
338 | } |
339 | |
340 | TEST(EitherTest, givenRightMoveConstructedFromValue_thenOldIsCorrect) { |
341 | test_with_matrix( |
342 | {[](std::function<void(MovableOnly&)> test) { |
343 | MovableOnly a(3); |
344 | either<int, MovableOnly> b(std::move(a)); |
345 | test(a); // NOLINT(bugprone-use-after-move) |
346 | }}, |
347 | EXPECT_IS<MovableOnly>(MovableOnly(0)) // 0 is moved-from value |
348 | ); |
349 | } |
350 | |
351 | TEST(EitherTest, givenLeftCopyAssignedFromValue_thenNewIsCorrect) { |
352 | test_with_matrix( |
353 | {[](std::function<void(either<string, int>&)> test) { |
354 | string a = "4" ; |
355 | either<string, int> b(2); |
356 | b = a; |
357 | test(b); |
358 | }, |
359 | [](std::function<void(either<string, int>&)> test) { |
360 | string a = "4" ; |
361 | either<string, int> b("2" ); |
362 | b = a; |
363 | test(b); |
364 | }}, |
365 | EXPECT_IS_LEFT<string, int>("4" )); |
366 | } |
367 | |
368 | TEST(EitherTest, givenLeftCopyAssignedFromValue_thenOldIsCorrect) { |
369 | test_with_matrix( |
370 | {[](std::function<void(string&)> test) { |
371 | string a = "4" ; |
372 | either<string, int> b(2); |
373 | b = a; |
374 | test(a); |
375 | }, |
376 | [](std::function<void(string&)> test) { |
377 | string a = "4" ; |
378 | either<string, int> b("2" ); |
379 | b = a; |
380 | test(a); |
381 | }}, |
382 | EXPECT_IS<string>("4" )); |
383 | } |
384 | |
385 | TEST(EitherTest, givenRightCopyAssignedFromValue_thenNewIsCorrect) { |
386 | test_with_matrix( |
387 | {[](std::function<void(either<int, string>&)> test) { |
388 | string a = "4" ; |
389 | either<int, string> b(2); |
390 | b = a; |
391 | test(b); |
392 | }, |
393 | [](std::function<void(either<int, string>&)> test) { |
394 | string a = "4" ; |
395 | either<int, string> b("2" ); |
396 | b = a; |
397 | test(b); |
398 | }}, |
399 | EXPECT_IS_RIGHT<int, string>("4" )); |
400 | } |
401 | |
402 | TEST(EitherTest, givenRightCopyAssignedFromValue_thenOldIsCorrect) { |
403 | test_with_matrix( |
404 | {[](std::function<void(string&)> test) { |
405 | string a = "4" ; |
406 | either<int, string> b(2); |
407 | b = a; |
408 | test(a); |
409 | }, |
410 | [](std::function<void(string&)> test) { |
411 | string a = "4" ; |
412 | either<int, string> b("2" ); |
413 | b = a; |
414 | test(a); |
415 | }}, |
416 | EXPECT_IS<string>("4" )); |
417 | } |
418 | |
419 | TEST(EitherTest, givenLeftMoveAssignedFromValue_thenNewIsCorrect) { |
420 | test_with_matrix( |
421 | {[](std::function<void(either<MovableOnly, string>&)> test) { |
422 | MovableOnly a(3); |
423 | either<MovableOnly, string> b(2); |
424 | b = std::move(a); |
425 | test(b); |
426 | }, |
427 | [](std::function<void(either<MovableOnly, string>&)> test) { |
428 | MovableOnly a(3); |
429 | either<MovableOnly, string> b(MovableOnly(2)); |
430 | b = std::move(a); |
431 | test(b); |
432 | }}, |
433 | EXPECT_IS_LEFT<MovableOnly, string>(MovableOnly(3))); |
434 | } |
435 | |
436 | TEST(EitherTest, givenLeftMoveAssignedFromValue_thenOldIsCorrect) { |
437 | test_with_matrix( |
438 | {[](std::function<void(MovableOnly&)> test) { |
439 | MovableOnly a(3); |
440 | either<MovableOnly, string> b("2" ); |
441 | b = std::move(a); |
442 | test(a); // NOLINT(bugprone-use-after-move) |
443 | }, |
444 | [](std::function<void(MovableOnly&)> test) { |
445 | MovableOnly a(3); |
446 | either<MovableOnly, string> b(MovableOnly(0)); |
447 | b = std::move(a); |
448 | test(a); // NOLINT(bugprone-use-after-move) |
449 | }}, |
450 | EXPECT_IS<MovableOnly>(MovableOnly(0))); |
451 | } |
452 | |
453 | TEST(EitherTest, givenRightMoveAssignedFromValue_thenNewIsCorrect) { |
454 | test_with_matrix( |
455 | {[](std::function<void(either<string, MovableOnly>&)> test) { |
456 | MovableOnly a(3); |
457 | either<string, MovableOnly> b("2" ); |
458 | b = std::move(a); |
459 | test(b); |
460 | }, |
461 | [](std::function<void(either<string, MovableOnly>&)> test) { |
462 | MovableOnly a(3); |
463 | either<string, MovableOnly> b(MovableOnly(2)); |
464 | b = std::move(a); |
465 | test(b); |
466 | }}, |
467 | EXPECT_IS_RIGHT<string, MovableOnly>(MovableOnly(3))); |
468 | } |
469 | |
470 | TEST(EitherTest, givenRightMoveAssignedFromValue_thenOldIsCorrect) { |
471 | test_with_matrix( |
472 | {[](std::function<void(MovableOnly&)> test) { |
473 | MovableOnly a(3); |
474 | either<string, MovableOnly> b("2" ); |
475 | b = std::move(a); |
476 | test(a); // NOLINT(bugprone-use-after-move) |
477 | }, |
478 | [](std::function<void(MovableOnly&)> test) { |
479 | MovableOnly a(3); |
480 | either<string, MovableOnly> b(MovableOnly(2)); |
481 | b = std::move(a); |
482 | test(a); // NOLINT(bugprone-use-after-move) |
483 | }}, |
484 | EXPECT_IS<MovableOnly>(MovableOnly(0)) // 0 is moved-from value |
485 | ); |
486 | } |
487 | |
488 | TEST(EitherTest, givenLeftCopyConstructed_thenNewIsCorrect) { |
489 | test_with_matrix( |
490 | {[](std::function<void(either<string, int>&)> test) { |
491 | either<string, int> a("4" ); |
492 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
493 | either<string, int> b(a); |
494 | test(b); |
495 | }}, |
496 | EXPECT_IS_LEFT<string, int>("4" )); |
497 | } |
498 | |
499 | TEST(EitherTest, givenLeftCopyConstructed_thenOldIsCorrect) { |
500 | test_with_matrix( |
501 | {[](std::function<void(either<string, int>&)> test) { |
502 | either<string, int> a("4" ); |
503 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
504 | either<string, int> b(a); |
505 | test(a); |
506 | }}, |
507 | EXPECT_IS_LEFT<string, int>("4" )); |
508 | } |
509 | |
510 | TEST(EitherTest, givenLeftCopyConstructed_withSameType_thenNewIsCorrect) { |
511 | test_with_matrix( |
512 | {[](std::function<void(either<string, string>&)> test) { |
513 | either<string, string> a = make_left<string, string>("4" ); |
514 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
515 | either<string, string> b(a); |
516 | test(b); |
517 | }}, |
518 | EXPECT_IS_LEFT<string, string>("4" )); |
519 | } |
520 | |
521 | TEST(EitherTest, givenLeftCopyConstructed_withSameType_thenOldIsCorrect) { |
522 | test_with_matrix( |
523 | {[](std::function<void(either<string, string>&)> test) { |
524 | either<string, string> a = make_left<string, string>("4" ); |
525 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
526 | either<string, string> b(a); |
527 | test(a); |
528 | }}, |
529 | EXPECT_IS_LEFT<string, string>("4" )); |
530 | } |
531 | |
532 | TEST(EitherTest, givenRightCopyConstructed_thenNewIsCorrect) { |
533 | test_with_matrix( |
534 | {[](std::function<void(either<int, string>&)> test) { |
535 | either<int, string> a("4" ); |
536 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
537 | either<int, string> b(a); |
538 | test(b); |
539 | }}, |
540 | EXPECT_IS_RIGHT<int, string>("4" )); |
541 | } |
542 | |
543 | TEST(EitherTest, givenRightCopyConstructed_thenOldIsCorrect) { |
544 | test_with_matrix( |
545 | {[](std::function<void(either<int, string>&)> test) { |
546 | either<int, string> a("4" ); |
547 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
548 | either<int, string> b(a); |
549 | test(a); |
550 | }}, |
551 | EXPECT_IS_RIGHT<int, string>("4" )); |
552 | } |
553 | |
554 | TEST(EitherTest, givenRightCopyConstructed_withSameType_thenNewIsCorrect) { |
555 | test_with_matrix( |
556 | {[](std::function<void(either<string, string>&)> test) { |
557 | either<string, string> a = make_right<string, string>("4" ); |
558 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
559 | either<string, string> b(a); |
560 | test(b); |
561 | }}, |
562 | EXPECT_IS_RIGHT<string, string>("4" )); |
563 | } |
564 | |
565 | TEST(EitherTest, givenRightCopyConstructed_withSameType_thenOldIsCorrect) { |
566 | test_with_matrix( |
567 | {[](std::function<void(either<string, string>&)> test) { |
568 | either<string, string> a = make_right<string, string>("4" ); |
569 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
570 | either<string, string> b(a); |
571 | test(a); |
572 | }}, |
573 | EXPECT_IS_RIGHT<string, string>("4" )); |
574 | } |
575 | |
576 | TEST(EitherTest, givenLeftMoveConstructed_thenNewIsCorrect) { |
577 | test_with_matrix( |
578 | {[](std::function<void(either<MovableOnly, int>&)> test) { |
579 | either<MovableOnly, int> a(MovableOnly(3)); |
580 | either<MovableOnly, int> b(std::move(a)); |
581 | test(b); |
582 | }}, |
583 | EXPECT_IS_LEFT<MovableOnly, int>(MovableOnly(3))); |
584 | } |
585 | |
586 | TEST(EitherTest, givenLeftMoveConstructed_thenOldIsCorrect) { |
587 | test_with_matrix( |
588 | {[](std::function<void(either<MovableOnly, int>&)> test) { |
589 | either<MovableOnly, int> a(MovableOnly(3)); |
590 | either<MovableOnly, int> b(std::move(a)); |
591 | test(a); // NOLINT(bugprone-use-after-move) |
592 | }}, |
593 | EXPECT_IS_LEFT<MovableOnly, int>(MovableOnly(0)) // 0 is moved-from value |
594 | ); |
595 | } |
596 | |
597 | TEST(EitherTest, givenLeftMoveConstructed_withSameType_thenNewIsCorrect) { |
598 | test_with_matrix( |
599 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
600 | either<MovableOnly, MovableOnly> a = |
601 | make_left<MovableOnly, MovableOnly>(MovableOnly(3)); |
602 | either<MovableOnly, MovableOnly> b(std::move(a)); |
603 | test(b); |
604 | }}, |
605 | EXPECT_IS_LEFT<MovableOnly, MovableOnly>(MovableOnly(3))); |
606 | } |
607 | |
608 | TEST(EitherTest, givenLeftMoveConstructed_withSameType_thenOldIsCorrect) { |
609 | test_with_matrix( |
610 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
611 | either<MovableOnly, MovableOnly> a = |
612 | make_left<MovableOnly, MovableOnly>(MovableOnly(3)); |
613 | either<MovableOnly, MovableOnly> b(std::move(a)); |
614 | test(a); // NOLINT(bugprone-use-after-move) |
615 | }}, |
616 | EXPECT_IS_LEFT<MovableOnly, MovableOnly>( |
617 | MovableOnly(0)) // 0 is moved-from value |
618 | ); |
619 | } |
620 | |
621 | TEST(EitherTest, givenRightMoveConstructed_thenNewIsCorrect) { |
622 | test_with_matrix( |
623 | {[](std::function<void(either<int, MovableOnly>&)> test) { |
624 | either<int, MovableOnly> a(MovableOnly(3)); |
625 | either<int, MovableOnly> b(std::move(a)); |
626 | test(b); |
627 | }}, |
628 | EXPECT_IS_RIGHT<int, MovableOnly>(MovableOnly(3))); |
629 | } |
630 | |
631 | TEST(EitherTest, givenRightMoveConstructed_thenOldIsCorrect) { |
632 | test_with_matrix( |
633 | {[](std::function<void(either<int, MovableOnly>&)> test) { |
634 | either<int, MovableOnly> a(MovableOnly(3)); |
635 | either<int, MovableOnly> b(std::move(a)); |
636 | test(a); // NOLINT(bugprone-use-after-move) |
637 | }}, |
638 | EXPECT_IS_RIGHT<int, MovableOnly>(MovableOnly(0)) // 0 is moved-from value |
639 | ); |
640 | } |
641 | |
642 | TEST(EitherTest, givenRightMoveConstructed_withSameType_thenNewIsCorrect) { |
643 | test_with_matrix( |
644 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
645 | either<MovableOnly, MovableOnly> a = |
646 | make_right<MovableOnly, MovableOnly>(MovableOnly(3)); |
647 | either<MovableOnly, MovableOnly> b(std::move(a)); |
648 | test(b); |
649 | }}, |
650 | EXPECT_IS_RIGHT<MovableOnly, MovableOnly>(MovableOnly(3))); |
651 | } |
652 | |
653 | TEST(EitherTest, givenRightMoveConstructed_withSameType_thenOldIsCorrect) { |
654 | test_with_matrix( |
655 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
656 | either<MovableOnly, MovableOnly> a = |
657 | make_right<MovableOnly, MovableOnly>(MovableOnly(3)); |
658 | either<MovableOnly, MovableOnly> b(std::move(a)); |
659 | test(a); // NOLINT(bugprone-use-after-move) |
660 | }}, |
661 | EXPECT_IS_RIGHT<MovableOnly, MovableOnly>( |
662 | MovableOnly(0)) // 0 is moved-from value |
663 | ); |
664 | } |
665 | |
666 | TEST(EitherTest, givenLeftCopyAssigned_thenNewIsCorrect) { |
667 | test_with_matrix( |
668 | {[](std::function<void(either<string, int>&)> test) { |
669 | either<string, int> a("4" ); |
670 | either<string, int> b(2); |
671 | b = a; |
672 | test(b); |
673 | }, |
674 | [](std::function<void(either<string, int>&)> test) { |
675 | either<string, int> a("4" ); |
676 | either<string, int> b("2" ); |
677 | b = a; |
678 | test(b); |
679 | }}, |
680 | EXPECT_IS_LEFT<string, int>("4" )); |
681 | } |
682 | |
683 | TEST(EitherTest, givenLeftCopyAssigned_thenOldIsCorrect) { |
684 | test_with_matrix( |
685 | {[](std::function<void(either<string, int>&)> test) { |
686 | either<string, int> a("4" ); |
687 | either<string, int> b(2); |
688 | b = a; |
689 | test(a); |
690 | }, |
691 | [](std::function<void(either<string, int>&)> test) { |
692 | either<string, int> a("4" ); |
693 | either<string, int> b("2" ); |
694 | b = a; |
695 | test(a); |
696 | }}, |
697 | EXPECT_IS_LEFT<string, int>("4" )); |
698 | } |
699 | |
700 | TEST(EitherTest, givenLeftCopyAssigned_withSameType_thenNewIsCorrect) { |
701 | test_with_matrix( |
702 | {[](std::function<void(either<string, string>&)> test) { |
703 | either<string, string> a = make_left<string, string>("4" ); |
704 | either<string, string> b = make_right<string, string>("2" ); |
705 | b = a; |
706 | test(b); |
707 | }, |
708 | [](std::function<void(either<string, string>&)> test) { |
709 | either<string, string> a = make_left<string, string>("4" ); |
710 | either<string, string> b = make_left<string, string>("2" ); |
711 | b = a; |
712 | test(b); |
713 | }}, |
714 | EXPECT_IS_LEFT<string, string>("4" )); |
715 | } |
716 | |
717 | TEST(EitherTest, givenLeftCopyAssigned_withSameType_thenOldIsCorrect) { |
718 | test_with_matrix( |
719 | {[](std::function<void(either<string, string>&)> test) { |
720 | either<string, string> a = make_left<string, string>("4" ); |
721 | either<string, string> b = make_right<string, string>("2" ); |
722 | b = a; |
723 | test(a); |
724 | }, |
725 | [](std::function<void(either<string, string>&)> test) { |
726 | either<string, string> a = make_left<string, string>("4" ); |
727 | either<string, string> b = make_left<string, string>("2" ); |
728 | b = a; |
729 | test(a); |
730 | }}, |
731 | EXPECT_IS_LEFT<string, string>("4" )); |
732 | } |
733 | |
734 | TEST(EitherTest, givenRightCopyAssigned_thenNewIsCorrect) { |
735 | test_with_matrix( |
736 | {[](std::function<void(either<int, string>&)> test) { |
737 | either<int, string> a("4" ); |
738 | either<int, string> b(2); |
739 | b = a; |
740 | test(b); |
741 | }, |
742 | [](std::function<void(either<int, string>&)> test) { |
743 | either<int, string> a("4" ); |
744 | either<int, string> b("2" ); |
745 | b = a; |
746 | test(b); |
747 | }}, |
748 | EXPECT_IS_RIGHT<int, string>("4" )); |
749 | } |
750 | |
751 | TEST(EitherTest, givenRightCopyAssigned_thenOldIsCorrect) { |
752 | test_with_matrix( |
753 | {[](std::function<void(either<int, string>&)> test) { |
754 | either<int, string> a("4" ); |
755 | either<int, string> b(2); |
756 | b = a; |
757 | test(a); |
758 | }, |
759 | [](std::function<void(either<int, string>&)> test) { |
760 | either<int, string> a("4" ); |
761 | either<int, string> b("2" ); |
762 | b = a; |
763 | test(a); |
764 | }}, |
765 | EXPECT_IS_RIGHT<int, string>("4" )); |
766 | } |
767 | |
768 | TEST(EitherTest, givenRightCopyAssigned_withSameType_thenNewIsCorrect) { |
769 | test_with_matrix( |
770 | {[](std::function<void(either<string, string>&)> test) { |
771 | either<string, string> a = make_right<string, string>("4" ); |
772 | either<string, string> b = make_left<string, string>("2" ); |
773 | b = a; |
774 | test(b); |
775 | }, |
776 | [](std::function<void(either<string, string>&)> test) { |
777 | either<string, string> a = make_right<string, string>("4" ); |
778 | either<string, string> b = make_right<string, string>("2" ); |
779 | b = a; |
780 | test(b); |
781 | }}, |
782 | EXPECT_IS_RIGHT<string, string>("4" )); |
783 | } |
784 | |
785 | TEST(EitherTest, givenRightCopyAssigned_withSameType_thenOldIsCorrect) { |
786 | test_with_matrix( |
787 | {[](std::function<void(either<string, string>&)> test) { |
788 | either<string, string> a = make_right<string, string>("4" ); |
789 | either<string, string> b = make_left<string, string>("2" ); |
790 | b = a; |
791 | test(a); |
792 | }, |
793 | [](std::function<void(either<string, string>&)> test) { |
794 | either<string, string> a = make_right<string, string>("4" ); |
795 | either<string, string> b = make_right<string, string>("2" ); |
796 | b = a; |
797 | test(a); |
798 | }}, |
799 | EXPECT_IS_RIGHT<string, string>("4" )); |
800 | } |
801 | |
802 | TEST(EitherTest, givenLeftMoveAssigned_thenNewIsCorrect) { |
803 | test_with_matrix( |
804 | {[](std::function<void(either<MovableOnly, string>&)> test) { |
805 | either<MovableOnly, string> a(MovableOnly(3)); |
806 | either<MovableOnly, string> b(2); |
807 | b = std::move(a); |
808 | test(b); |
809 | }, |
810 | [](std::function<void(either<MovableOnly, string>&)> test) { |
811 | either<MovableOnly, string> a(MovableOnly(3)); |
812 | either<MovableOnly, string> b(MovableOnly(2)); |
813 | b = std::move(a); |
814 | test(b); |
815 | }}, |
816 | EXPECT_IS_LEFT<MovableOnly, string>(MovableOnly(3))); |
817 | } |
818 | |
819 | TEST(EitherTest, givenLeftMoveAssigned_thenOldIsCorrect) { |
820 | test_with_matrix( |
821 | {[](std::function<void(either<MovableOnly, string>&)> test) { |
822 | either<MovableOnly, string> a(MovableOnly(3)); |
823 | either<MovableOnly, string> b(2); |
824 | b = std::move(a); |
825 | test(a); // NOLINT(bugprone-use-after-move) |
826 | }, |
827 | [](std::function<void(either<MovableOnly, string>&)> test) { |
828 | either<MovableOnly, string> a(MovableOnly(3)); |
829 | either<MovableOnly, string> b(MovableOnly(2)); |
830 | b = std::move(a); |
831 | test(a); // NOLINT(bugprone-use-after-move) |
832 | }}, |
833 | EXPECT_IS_LEFT<MovableOnly, string>( |
834 | MovableOnly(0)) // 0 is moved-from value |
835 | ); |
836 | } |
837 | |
838 | TEST(EitherTest, givenLeftMoveAssigned_withSameType_thenNewIsCorrect) { |
839 | test_with_matrix( |
840 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
841 | either<MovableOnly, MovableOnly> a = |
842 | make_left<MovableOnly, MovableOnly>(3); |
843 | either<MovableOnly, MovableOnly> b = |
844 | make_right<MovableOnly, MovableOnly>(2); |
845 | b = std::move(a); |
846 | test(b); |
847 | }, |
848 | [](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
849 | either<MovableOnly, MovableOnly> a = |
850 | make_left<MovableOnly, MovableOnly>(3); |
851 | either<MovableOnly, MovableOnly> b = |
852 | make_left<MovableOnly, MovableOnly>(2); |
853 | b = std::move(a); |
854 | test(b); |
855 | }}, |
856 | EXPECT_IS_LEFT<MovableOnly, MovableOnly>(MovableOnly(3))); |
857 | } |
858 | |
859 | TEST(EitherTest, givenLeftMoveAssigned_withSameType_thenOldIsCorrect) { |
860 | test_with_matrix( |
861 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
862 | either<MovableOnly, MovableOnly> a = |
863 | make_left<MovableOnly, MovableOnly>(3); |
864 | either<MovableOnly, MovableOnly> b = |
865 | make_right<MovableOnly, MovableOnly>(2); |
866 | b = std::move(a); |
867 | test(a); // NOLINT(bugprone-use-after-move) |
868 | }, |
869 | [](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
870 | either<MovableOnly, MovableOnly> a = |
871 | make_left<MovableOnly, MovableOnly>(3); |
872 | either<MovableOnly, MovableOnly> b = |
873 | make_left<MovableOnly, MovableOnly>(2); |
874 | b = std::move(a); |
875 | test(a); // NOLINT(bugprone-use-after-move) |
876 | }}, |
877 | EXPECT_IS_LEFT<MovableOnly, MovableOnly>( |
878 | MovableOnly(0)) // 0 is moved-from value |
879 | ); |
880 | } |
881 | |
882 | TEST(EitherTest, givenRightMoveAssigned_thenNewIsCorrect) { |
883 | test_with_matrix( |
884 | {[](std::function<void(either<string, MovableOnly>&)> test) { |
885 | either<string, MovableOnly> a(MovableOnly(3)); |
886 | either<string, MovableOnly> b("2" ); |
887 | b = std::move(a); |
888 | test(b); |
889 | }, |
890 | [](std::function<void(either<string, MovableOnly>&)> test) { |
891 | either<string, MovableOnly> a(MovableOnly(3)); |
892 | either<string, MovableOnly> b(MovableOnly(2)); |
893 | b = std::move(a); |
894 | test(b); |
895 | }}, |
896 | EXPECT_IS_RIGHT<string, MovableOnly>(MovableOnly(3))); |
897 | } |
898 | |
899 | TEST(EitherTest, givenRightMoveAssigned_thenOldIsCorrect) { |
900 | test_with_matrix( |
901 | {[](std::function<void(either<string, MovableOnly>&)> test) { |
902 | either<string, MovableOnly> a(MovableOnly(3)); |
903 | either<string, MovableOnly> b("2" ); |
904 | b = std::move(a); |
905 | test(a); // NOLINT(bugprone-use-after-move) |
906 | }, |
907 | [](std::function<void(either<string, MovableOnly>&)> test) { |
908 | either<string, MovableOnly> a(MovableOnly(3)); |
909 | either<string, MovableOnly> b(MovableOnly(2)); |
910 | b = std::move(a); |
911 | test(a); // NOLINT(bugprone-use-after-move) |
912 | }}, |
913 | EXPECT_IS_RIGHT<string, MovableOnly>( |
914 | MovableOnly(0)) // 0 is moved-from value |
915 | ); |
916 | } |
917 | |
918 | TEST(EitherTest, givenRightMoveAssigned_withSameType_thenNewIsCorrect) { |
919 | test_with_matrix( |
920 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
921 | either<MovableOnly, MovableOnly> a = |
922 | make_right<MovableOnly, MovableOnly>(3); |
923 | either<MovableOnly, MovableOnly> b = |
924 | make_left<MovableOnly, MovableOnly>(2); |
925 | b = std::move(a); |
926 | test(b); |
927 | }, |
928 | [](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
929 | either<MovableOnly, MovableOnly> a = |
930 | make_right<MovableOnly, MovableOnly>(3); |
931 | either<MovableOnly, MovableOnly> b = |
932 | make_right<MovableOnly, MovableOnly>(2); |
933 | b = std::move(a); |
934 | test(b); |
935 | }}, |
936 | EXPECT_IS_RIGHT<MovableOnly, MovableOnly>(MovableOnly(3))); |
937 | } |
938 | |
939 | TEST(EitherTest, givenRightMoveAssigned_withSameType_thenOldIsCorrect) { |
940 | test_with_matrix( |
941 | {[](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
942 | either<MovableOnly, MovableOnly> a = |
943 | make_right<MovableOnly, MovableOnly>(3); |
944 | either<MovableOnly, MovableOnly> b = |
945 | make_left<MovableOnly, MovableOnly>(2); |
946 | b = std::move(a); |
947 | test(a); // NOLINT(bugprone-use-after-move) |
948 | }, |
949 | [](std::function<void(either<MovableOnly, MovableOnly>&)> test) { |
950 | either<MovableOnly, MovableOnly> a = |
951 | make_right<MovableOnly, MovableOnly>(3); |
952 | either<MovableOnly, MovableOnly> b = |
953 | make_right<MovableOnly, MovableOnly>(2); |
954 | b = std::move(a); |
955 | test(a); // NOLINT(bugprone-use-after-move) |
956 | }}, |
957 | EXPECT_IS_RIGHT<MovableOnly, MovableOnly>( |
958 | MovableOnly(0)) // 0 is moved-from value |
959 | ); |
960 | } |
961 | |
962 | TEST(EitherTest, givenLeft_whenModified_thenValueIsChanged) { |
963 | test_with_matrix( |
964 | {[](std::function<void(either<int, string>&)> test) { |
965 | either<int, string> a(4); |
966 | a.left() = 5; |
967 | test(a); |
968 | }, |
969 | [](std::function<void(either<int, string>&)> test) { |
970 | either<int, string> a(4); |
971 | a.left() = 5; |
972 | test(a); |
973 | }}, |
974 | EXPECT_IS_LEFT<int, string>(5)); |
975 | } |
976 | |
977 | TEST(EitherTest, givenRight_whenModified_thenValueIsChanged) { |
978 | test_with_matrix( |
979 | {[](std::function<void(either<int, string>&)> test) { |
980 | either<int, string> a("4" ); |
981 | a.right() = "5" ; |
982 | test(a); |
983 | }, |
984 | [](std::function<void(either<int, string>&)> test) { |
985 | either<int, string> a("4" ); |
986 | a.right() = "5" ; |
987 | test(a); |
988 | }}, |
989 | EXPECT_IS_RIGHT<int, string>("5" )); |
990 | } |
991 | |
992 | TEST(EitherTest, canEmplaceConstructLeft) { |
993 | test_with_matrix( |
994 | {[](std::function<void(either<tuple<int, int>, tuple<int, string, int>>&)> |
995 | test) { |
996 | either<tuple<int, int>, tuple<int, string, int>> a(2, 3); |
997 | test(a); |
998 | }}, |
999 | EXPECT_IS_LEFT<tuple<int, int>, tuple<int, string, int>>( |
1000 | tuple<int, int>(2, 3))); |
1001 | } |
1002 | |
1003 | TEST(EitherTest, canEmplaceConstructRight) { |
1004 | test_with_matrix( |
1005 | {[](std::function<void(either<tuple<int, int>, tuple<int, string, int>>&)> |
1006 | test) { |
1007 | either<tuple<int, int>, tuple<int, string, int>> a(2, "3" , 4); |
1008 | test(a); |
1009 | }}, |
1010 | EXPECT_IS_RIGHT<tuple<int, int>, tuple<int, string, int>>( |
1011 | tuple<int, string, int>(2, "3" , 4))); |
1012 | } |
1013 | |
1014 | TEST(EitherTest, givenEqualLefts_thenAreEqual) { |
1015 | either<string, int> a("3" ); |
1016 | either<string, int> b("3" ); |
1017 | EXPECT_TRUE(a == b); |
1018 | } |
1019 | |
1020 | TEST(EitherTest, givenEqualLefts_thenAreNotUnequal) { |
1021 | either<string, int> a("3" ); |
1022 | either<string, int> b("3" ); |
1023 | EXPECT_FALSE(a != b); |
1024 | } |
1025 | |
1026 | TEST(EitherTest, givenEqualRights_thenAreEqual) { |
1027 | either<string, int> a(3); |
1028 | either<string, int> b(3); |
1029 | EXPECT_TRUE(a == b); |
1030 | } |
1031 | |
1032 | TEST(EitherTest, givenEqualRights_thenAreNotUnequal) { |
1033 | either<string, int> a(3); |
1034 | either<string, int> b(3); |
1035 | EXPECT_FALSE(a != b); |
1036 | } |
1037 | |
1038 | TEST(EitherTest, givenLeftAndRight_thenAreNotEqual) { |
1039 | either<string, int> a("3" ); |
1040 | either<string, int> b(3); |
1041 | EXPECT_FALSE(a == b); |
1042 | EXPECT_FALSE(b == a); |
1043 | } |
1044 | |
1045 | TEST(EitherTest, givenLeftAndRight_thenAreUnequal) { |
1046 | either<string, int> a("3" ); |
1047 | either<string, int> b(3); |
1048 | EXPECT_TRUE(a != b); |
1049 | EXPECT_TRUE(b != a); |
1050 | } |
1051 | |
1052 | TEST(EitherTest, OutputLeft) { |
1053 | ostringstream str; |
1054 | str << either<string, int>("mystring" ); |
1055 | EXPECT_EQ("Left(mystring)" , str.str()); |
1056 | } |
1057 | |
1058 | TEST(EitherTest, OutputRight) { |
1059 | ostringstream str; |
1060 | str << either<int, string>("mystring" ); |
1061 | EXPECT_EQ("Right(mystring)" , str.str()); |
1062 | } |
1063 | |
1064 | TEST(EitherTest, givenLeftAndRightWithSameType_thenAreNotEqual) { |
1065 | either<string, string> a = make_left<string, string>("3" ); |
1066 | either<string, string> b = make_right<string, string>("3" ); |
1067 | EXPECT_FALSE(a == b); |
1068 | EXPECT_FALSE(b == a); |
1069 | } |
1070 | |
1071 | TEST(EitherTest, givenLeftAndRightWithSameType_thenAreUnequal) { |
1072 | either<string, string> a = make_left<string, string>("3" ); |
1073 | either<string, string> b = make_right<string, string>("3" ); |
1074 | EXPECT_TRUE(a != b); |
1075 | EXPECT_TRUE(b != a); |
1076 | } |
1077 | |
1078 | namespace { |
1079 | class DestructorCallback { |
1080 | public: |
1081 | MOCK_CONST_METHOD0(call, void()); |
1082 | |
1083 | void EXPECT_CALLED(int times = 1) { |
1084 | EXPECT_CALL(*this, call()).Times(times); |
1085 | } |
1086 | }; |
1087 | class ClassWithDestructorCallback { |
1088 | public: |
1089 | ClassWithDestructorCallback(const DestructorCallback* destructorCallback) |
1090 | : _destructorCallback(destructorCallback) {} |
1091 | |
1092 | ~ClassWithDestructorCallback() { |
1093 | _destructorCallback->call(); |
1094 | } |
1095 | |
1096 | ClassWithDestructorCallback& operator=( |
1097 | const ClassWithDestructorCallback& rhs) = delete; |
1098 | |
1099 | private: |
1100 | const DestructorCallback* _destructorCallback; |
1101 | }; |
1102 | class OnlyMoveableClassWithDestructorCallback { |
1103 | public: |
1104 | OnlyMoveableClassWithDestructorCallback( |
1105 | const DestructorCallback* destructorCallback) |
1106 | : _destructorCallback(destructorCallback) {} |
1107 | OnlyMoveableClassWithDestructorCallback( |
1108 | OnlyMoveableClassWithDestructorCallback&& source) |
1109 | : _destructorCallback(source._destructorCallback) {} |
1110 | |
1111 | ~OnlyMoveableClassWithDestructorCallback() { |
1112 | _destructorCallback->call(); |
1113 | } |
1114 | |
1115 | private: |
1116 | C10_DISABLE_COPY_AND_ASSIGN(OnlyMoveableClassWithDestructorCallback); |
1117 | const DestructorCallback* _destructorCallback; |
1118 | }; |
1119 | |
1120 | } // namespace |
1121 | |
1122 | TEST(EitherTest_Destructor, LeftDestructorIsCalled) { |
1123 | DestructorCallback destructorCallback; |
1124 | destructorCallback.EXPECT_CALLED( |
1125 | 2); // Once for the temp object, once when the either class destructs |
1126 | |
1127 | ClassWithDestructorCallback temp(&destructorCallback); |
1128 | either<ClassWithDestructorCallback, string> var = temp; |
1129 | } |
1130 | |
1131 | TEST(EitherTest_Destructor, RightDestructorIsCalled) { |
1132 | DestructorCallback destructorCallback; |
1133 | destructorCallback.EXPECT_CALLED( |
1134 | 2); // Once for the temp object, once when the either class destructs |
1135 | |
1136 | ClassWithDestructorCallback temp(&destructorCallback); |
1137 | either<string, ClassWithDestructorCallback> var = temp; |
1138 | } |
1139 | |
1140 | TEST(EitherTest_Destructor, LeftDestructorIsCalledAfterCopying) { |
1141 | DestructorCallback destructorCallback; |
1142 | destructorCallback.EXPECT_CALLED( |
1143 | 3); // Once for the temp object, once for var1 and once for var2 |
1144 | |
1145 | ClassWithDestructorCallback temp(&destructorCallback); |
1146 | either<ClassWithDestructorCallback, string> var1 = temp; |
1147 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1148 | either<ClassWithDestructorCallback, string> var2 = var1; |
1149 | } |
1150 | |
1151 | TEST(EitherTest_Destructor, RightDestructorIsCalledAfterCopying) { |
1152 | DestructorCallback destructorCallback; |
1153 | destructorCallback.EXPECT_CALLED( |
1154 | 3); // Once for the temp object, once for var1 and once for var2 |
1155 | |
1156 | ClassWithDestructorCallback temp(&destructorCallback); |
1157 | either<string, ClassWithDestructorCallback> var1 = temp; |
1158 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1159 | either<string, ClassWithDestructorCallback> var2 = var1; |
1160 | } |
1161 | |
1162 | TEST(EitherTest_Destructor, LeftDestructorIsCalledAfterMoving) { |
1163 | DestructorCallback destructorCallback; |
1164 | destructorCallback.EXPECT_CALLED( |
1165 | 3); // Once for the temp object, once for var1 and once for var2 |
1166 | |
1167 | OnlyMoveableClassWithDestructorCallback temp(&destructorCallback); |
1168 | either<OnlyMoveableClassWithDestructorCallback, string> var1 = |
1169 | std::move(temp); |
1170 | either<OnlyMoveableClassWithDestructorCallback, string> var2 = |
1171 | std::move(var1); |
1172 | } |
1173 | |
1174 | TEST(EitherTest_Destructor, RightDestructorIsCalledAfterMoving) { |
1175 | DestructorCallback destructorCallback; |
1176 | destructorCallback.EXPECT_CALLED( |
1177 | 3); // Once for the temp object, once for var1 and once for var2 |
1178 | |
1179 | OnlyMoveableClassWithDestructorCallback temp(&destructorCallback); |
1180 | either<string, OnlyMoveableClassWithDestructorCallback> var1 = |
1181 | std::move(temp); |
1182 | either<string, OnlyMoveableClassWithDestructorCallback> var2 = |
1183 | std::move(var1); |
1184 | } |
1185 | |
1186 | TEST(EitherTest_Destructor, LeftDestructorIsCalledAfterAssignment) { |
1187 | DestructorCallback destructorCallback1; |
1188 | DestructorCallback destructorCallback2; |
1189 | destructorCallback1.EXPECT_CALLED( |
1190 | 2); // Once for the temp1 object, once at the assignment |
1191 | destructorCallback2.EXPECT_CALLED( |
1192 | 3); // Once for the temp2 object, once in destructor of var2, once in |
1193 | // destructor of var1 |
1194 | |
1195 | ClassWithDestructorCallback temp1(&destructorCallback1); |
1196 | either<ClassWithDestructorCallback, string> var1 = temp1; |
1197 | ClassWithDestructorCallback temp2(&destructorCallback2); |
1198 | either<ClassWithDestructorCallback, string> var2 = temp2; |
1199 | var1 = var2; |
1200 | } |
1201 | |
1202 | TEST(EitherTest_Destructor, RightDestructorIsCalledAfterAssignment) { |
1203 | DestructorCallback destructorCallback1; |
1204 | DestructorCallback destructorCallback2; |
1205 | destructorCallback1.EXPECT_CALLED( |
1206 | 2); // Once for the temp1 object, once at the assignment |
1207 | destructorCallback2.EXPECT_CALLED( |
1208 | 3); // Once for the temp2 object, once in destructor of var2, once in |
1209 | // destructor of var1 |
1210 | |
1211 | ClassWithDestructorCallback temp1(&destructorCallback1); |
1212 | either<string, ClassWithDestructorCallback> var1 = temp1; |
1213 | ClassWithDestructorCallback temp2(&destructorCallback2); |
1214 | either<string, ClassWithDestructorCallback> var2 = temp2; |
1215 | var1 = var2; |
1216 | } |
1217 | |
1218 | TEST(EitherTest_Destructor, LeftDestructorIsCalledAfterMoveAssignment) { |
1219 | DestructorCallback destructorCallback1; |
1220 | DestructorCallback destructorCallback2; |
1221 | destructorCallback1.EXPECT_CALLED( |
1222 | 2); // Once for the temp1 object, once at the assignment |
1223 | destructorCallback2.EXPECT_CALLED( |
1224 | 3); // Once for the temp2 object, once in destructor of var2, once in |
1225 | // destructor of var1 |
1226 | |
1227 | OnlyMoveableClassWithDestructorCallback temp1(&destructorCallback1); |
1228 | either<OnlyMoveableClassWithDestructorCallback, string> var1 = |
1229 | std::move(temp1); |
1230 | OnlyMoveableClassWithDestructorCallback temp2(&destructorCallback2); |
1231 | either<OnlyMoveableClassWithDestructorCallback, string> var2 = |
1232 | std::move(temp2); |
1233 | var1 = std::move(var2); |
1234 | } |
1235 | |
1236 | TEST(EitherTest_Destructor, RightDestructorIsCalledAfterMoveAssignment) { |
1237 | DestructorCallback destructorCallback1; |
1238 | DestructorCallback destructorCallback2; |
1239 | destructorCallback1.EXPECT_CALLED( |
1240 | 2); // Once for the temp1 object, once at the assignment |
1241 | destructorCallback2.EXPECT_CALLED( |
1242 | 3); // Once for the temp2 object, once in destructor of var2, once in |
1243 | // destructor of var1 |
1244 | |
1245 | OnlyMoveableClassWithDestructorCallback temp1(&destructorCallback1); |
1246 | either<string, OnlyMoveableClassWithDestructorCallback> var1 = |
1247 | std::move(temp1); |
1248 | OnlyMoveableClassWithDestructorCallback temp2(&destructorCallback2); |
1249 | either<string, OnlyMoveableClassWithDestructorCallback> var2 = |
1250 | std::move(temp2); |
1251 | var1 = std::move(var2); |
1252 | } |
1253 | |