1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/Optional.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/Support/raw_ostream.h"
13 #include "gtest/gtest-spi.h"
14 #include "gtest/gtest.h"
15
16 #include <array>
17
18
19 using namespace llvm;
20
21 static_assert(std::is_trivially_copyable<Optional<int>>::value,
22 "trivially copyable");
23
24 static_assert(std::is_trivially_copyable<Optional<std::array<int, 3>>>::value,
25 "trivially copyable");
26
OptionalWorksInConstexpr()27 void OptionalWorksInConstexpr() {
28 constexpr auto x1 = Optional<int>();
29 constexpr Optional<int> x2{};
30 static_assert(!x1.has_value() && !x2.has_value(),
31 "Default construction and hasValue() are contexpr");
32 static_assert(!x1.has_value() && !x2.has_value(),
33 "Default construction and hasValue() are contexpr");
34 constexpr auto y1 = Optional<int>(3);
35 constexpr Optional<int> y2{3};
36 static_assert(y1.value() == y2.value() && y1.value() == 3,
37 "Construction with value and getValue() are constexpr");
38 static_assert(y1.value() == y2.value() && y1.value() == 3,
39 "Construction with value and getValue() are constexpr");
40 static_assert(Optional<int>{3} >= 2 && Optional<int>{1} < Optional<int>{2},
41 "Comparisons work in constexpr");
42 }
43
44 namespace {
45
46 struct NonDefaultConstructible {
47 static unsigned CopyConstructions;
48 static unsigned Destructions;
49 static unsigned CopyAssignments;
NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible50 explicit NonDefaultConstructible(int) {
51 }
NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible52 NonDefaultConstructible(const NonDefaultConstructible&) {
53 ++CopyConstructions;
54 }
operator =__anon243dbdea0111::NonDefaultConstructible55 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
56 ++CopyAssignments;
57 return *this;
58 }
~NonDefaultConstructible__anon243dbdea0111::NonDefaultConstructible59 ~NonDefaultConstructible() {
60 ++Destructions;
61 }
ResetCounts__anon243dbdea0111::NonDefaultConstructible62 static void ResetCounts() {
63 CopyConstructions = 0;
64 Destructions = 0;
65 CopyAssignments = 0;
66 }
67 };
68
69 unsigned NonDefaultConstructible::CopyConstructions = 0;
70 unsigned NonDefaultConstructible::Destructions = 0;
71 unsigned NonDefaultConstructible::CopyAssignments = 0;
72
73 static_assert(
74 !std::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
75 "not trivially copyable");
76
TEST(OptionalTest,NonDefaultConstructibleTest)77 TEST(OptionalTest, NonDefaultConstructibleTest) {
78 Optional<NonDefaultConstructible> O;
79 EXPECT_FALSE(O);
80 }
81
TEST(OptionalTest,ResetTest)82 TEST(OptionalTest, ResetTest) {
83 NonDefaultConstructible::ResetCounts();
84 Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
85 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
86 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
87 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
88 NonDefaultConstructible::ResetCounts();
89 O.reset();
90 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
91 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
92 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
93 }
94
TEST(OptionalTest,InitializationLeakTest)95 TEST(OptionalTest, InitializationLeakTest) {
96 NonDefaultConstructible::ResetCounts();
97 Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
98 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
99 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
100 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
101 }
102
TEST(OptionalTest,CopyConstructionTest)103 TEST(OptionalTest, CopyConstructionTest) {
104 NonDefaultConstructible::ResetCounts();
105 {
106 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
107 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
108 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
109 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
110 NonDefaultConstructible::ResetCounts();
111 Optional<NonDefaultConstructible> B(A);
112 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
113 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
114 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
115 NonDefaultConstructible::ResetCounts();
116 }
117 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
118 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
119 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
120 }
121
TEST(OptionalTest,ConstructingCopyAssignmentTest)122 TEST(OptionalTest, ConstructingCopyAssignmentTest) {
123 NonDefaultConstructible::ResetCounts();
124 {
125 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
126 Optional<NonDefaultConstructible> B;
127 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
128 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
129 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
130 NonDefaultConstructible::ResetCounts();
131 B = A;
132 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
133 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
134 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
135 NonDefaultConstructible::ResetCounts();
136 }
137 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
138 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
139 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
140 }
141
TEST(OptionalTest,CopyingCopyAssignmentTest)142 TEST(OptionalTest, CopyingCopyAssignmentTest) {
143 NonDefaultConstructible::ResetCounts();
144 {
145 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
146 Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
147 EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
148 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
149 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
150 NonDefaultConstructible::ResetCounts();
151 B = A;
152 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
153 EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
154 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
155 NonDefaultConstructible::ResetCounts();
156 }
157 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
158 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
159 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
160 }
161
TEST(OptionalTest,DeletingCopyAssignmentTest)162 TEST(OptionalTest, DeletingCopyAssignmentTest) {
163 NonDefaultConstructible::ResetCounts();
164 {
165 Optional<NonDefaultConstructible> A;
166 Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
167 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
168 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
169 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
170 NonDefaultConstructible::ResetCounts();
171 B = A;
172 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
173 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
174 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
175 NonDefaultConstructible::ResetCounts();
176 }
177 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
178 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
179 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
180 }
181
TEST(OptionalTest,NullCopyConstructionTest)182 TEST(OptionalTest, NullCopyConstructionTest) {
183 NonDefaultConstructible::ResetCounts();
184 {
185 Optional<NonDefaultConstructible> A;
186 Optional<NonDefaultConstructible> B;
187 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
188 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
189 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
190 NonDefaultConstructible::ResetCounts();
191 B = A;
192 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
193 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
194 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
195 NonDefaultConstructible::ResetCounts();
196 }
197 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
198 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
199 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
200 }
201
TEST(OptionalTest,InPlaceConstructionNonDefaultConstructibleTest)202 TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) {
203 NonDefaultConstructible::ResetCounts();
204 { Optional<NonDefaultConstructible> A{in_place, 1}; }
205 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
206 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
207 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
208 }
209
TEST(OptionalTest,GetValueOr)210 TEST(OptionalTest, GetValueOr) {
211 Optional<int> A;
212 EXPECT_EQ(42, A.value_or(42));
213
214 A = 5;
215 EXPECT_EQ(5, A.value_or(42));
216 }
217
218 struct MultiArgConstructor {
219 int x, y;
MultiArgConstructor__anon243dbdea0111::MultiArgConstructor220 MultiArgConstructor(int x, int y) : x(x), y(y) {}
MultiArgConstructor__anon243dbdea0111::MultiArgConstructor221 explicit MultiArgConstructor(int x, bool positive)
222 : x(x), y(positive ? x : -x) {}
223
224 MultiArgConstructor(const MultiArgConstructor &) = delete;
225 MultiArgConstructor(MultiArgConstructor &&) = delete;
226 MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
227 MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
228
operator ==(const MultiArgConstructor & LHS,const MultiArgConstructor & RHS)229 friend bool operator==(const MultiArgConstructor &LHS,
230 const MultiArgConstructor &RHS) {
231 return LHS.x == RHS.x && LHS.y == RHS.y;
232 }
233
234 static unsigned Destructions;
~MultiArgConstructor__anon243dbdea0111::MultiArgConstructor235 ~MultiArgConstructor() {
236 ++Destructions;
237 }
ResetCounts__anon243dbdea0111::MultiArgConstructor238 static void ResetCounts() {
239 Destructions = 0;
240 }
241 };
242 unsigned MultiArgConstructor::Destructions = 0;
243
244 static_assert(!std::is_trivially_copyable<Optional<MultiArgConstructor>>::value,
245 "not trivially copyable");
246
TEST(OptionalTest,Emplace)247 TEST(OptionalTest, Emplace) {
248 MultiArgConstructor::ResetCounts();
249 Optional<MultiArgConstructor> A;
250
251 A.emplace(1, 2);
252 EXPECT_TRUE(A.has_value());
253 EXPECT_TRUE(A.has_value());
254 EXPECT_EQ(1, A->x);
255 EXPECT_EQ(2, A->y);
256 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
257
258 A.emplace(5, false);
259 EXPECT_TRUE(A.has_value());
260 EXPECT_TRUE(A.has_value());
261 EXPECT_EQ(5, A->x);
262 EXPECT_EQ(-5, A->y);
263 EXPECT_EQ(1u, MultiArgConstructor::Destructions);
264 }
265
TEST(OptionalTest,InPlaceConstructionMultiArgConstructorTest)266 TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) {
267 MultiArgConstructor::ResetCounts();
268 {
269 Optional<MultiArgConstructor> A{in_place, 1, 2};
270 EXPECT_TRUE(A.has_value());
271 EXPECT_TRUE(A.has_value());
272 EXPECT_EQ(1, A->x);
273 EXPECT_EQ(2, A->y);
274 Optional<MultiArgConstructor> B{in_place, 5, false};
275 EXPECT_TRUE(B.has_value());
276 EXPECT_TRUE(B.has_value());
277 EXPECT_EQ(5, B->x);
278 EXPECT_EQ(-5, B->y);
279 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
280 }
281 EXPECT_EQ(2u, MultiArgConstructor::Destructions);
282 }
283
TEST(OptionalTest,InPlaceConstructionAndEmplaceEquivalentTest)284 TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) {
285 MultiArgConstructor::ResetCounts();
286 {
287 Optional<MultiArgConstructor> A{in_place, 1, 2};
288 Optional<MultiArgConstructor> B;
289 B.emplace(1, 2);
290 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
291 ASSERT_EQ(A, B);
292 }
293 EXPECT_EQ(2u, MultiArgConstructor::Destructions);
294 }
295
296 struct MoveOnly {
297 static unsigned MoveConstructions;
298 static unsigned Destructions;
299 static unsigned MoveAssignments;
300 int val;
MoveOnly__anon243dbdea0111::MoveOnly301 explicit MoveOnly(int val) : val(val) {
302 }
MoveOnly__anon243dbdea0111::MoveOnly303 MoveOnly(MoveOnly&& other) {
304 val = other.val;
305 ++MoveConstructions;
306 }
operator =__anon243dbdea0111::MoveOnly307 MoveOnly &operator=(MoveOnly&& other) {
308 val = other.val;
309 ++MoveAssignments;
310 return *this;
311 }
~MoveOnly__anon243dbdea0111::MoveOnly312 ~MoveOnly() {
313 ++Destructions;
314 }
ResetCounts__anon243dbdea0111::MoveOnly315 static void ResetCounts() {
316 MoveConstructions = 0;
317 Destructions = 0;
318 MoveAssignments = 0;
319 }
320 };
321
322 unsigned MoveOnly::MoveConstructions = 0;
323 unsigned MoveOnly::Destructions = 0;
324 unsigned MoveOnly::MoveAssignments = 0;
325
326 static_assert(!std::is_trivially_copyable<Optional<MoveOnly>>::value,
327 "not trivially copyable");
328
TEST(OptionalTest,MoveOnlyNull)329 TEST(OptionalTest, MoveOnlyNull) {
330 MoveOnly::ResetCounts();
331 Optional<MoveOnly> O;
332 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
333 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
334 EXPECT_EQ(0u, MoveOnly::Destructions);
335 }
336
TEST(OptionalTest,MoveOnlyConstruction)337 TEST(OptionalTest, MoveOnlyConstruction) {
338 MoveOnly::ResetCounts();
339 Optional<MoveOnly> O(MoveOnly(3));
340 EXPECT_TRUE((bool)O);
341 EXPECT_EQ(3, O->val);
342 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
343 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
344 EXPECT_EQ(1u, MoveOnly::Destructions);
345 }
346
TEST(OptionalTest,MoveOnlyMoveConstruction)347 TEST(OptionalTest, MoveOnlyMoveConstruction) {
348 Optional<MoveOnly> A(MoveOnly(3));
349 MoveOnly::ResetCounts();
350 Optional<MoveOnly> B(std::move(A));
351 EXPECT_TRUE((bool)A);
352 EXPECT_TRUE((bool)B);
353 EXPECT_EQ(3, B->val);
354 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
355 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
356 EXPECT_EQ(0u, MoveOnly::Destructions);
357 }
358
TEST(OptionalTest,MoveOnlyAssignment)359 TEST(OptionalTest, MoveOnlyAssignment) {
360 MoveOnly::ResetCounts();
361 Optional<MoveOnly> O;
362 O = MoveOnly(3);
363 EXPECT_TRUE((bool)O);
364 EXPECT_EQ(3, O->val);
365 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
366 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
367 EXPECT_EQ(1u, MoveOnly::Destructions);
368 }
369
TEST(OptionalTest,MoveOnlyInitializingAssignment)370 TEST(OptionalTest, MoveOnlyInitializingAssignment) {
371 Optional<MoveOnly> A(MoveOnly(3));
372 Optional<MoveOnly> B;
373 MoveOnly::ResetCounts();
374 B = std::move(A);
375 EXPECT_TRUE((bool)A);
376 EXPECT_TRUE((bool)B);
377 EXPECT_EQ(3, B->val);
378 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
379 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
380 EXPECT_EQ(0u, MoveOnly::Destructions);
381 }
382
TEST(OptionalTest,MoveOnlyNullingAssignment)383 TEST(OptionalTest, MoveOnlyNullingAssignment) {
384 Optional<MoveOnly> A;
385 Optional<MoveOnly> B(MoveOnly(3));
386 MoveOnly::ResetCounts();
387 B = std::move(A);
388 EXPECT_FALSE((bool)A);
389 EXPECT_FALSE((bool)B);
390 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
391 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
392 EXPECT_EQ(1u, MoveOnly::Destructions);
393 }
394
TEST(OptionalTest,MoveOnlyAssigningAssignment)395 TEST(OptionalTest, MoveOnlyAssigningAssignment) {
396 Optional<MoveOnly> A(MoveOnly(3));
397 Optional<MoveOnly> B(MoveOnly(4));
398 MoveOnly::ResetCounts();
399 B = std::move(A);
400 EXPECT_TRUE((bool)A);
401 EXPECT_TRUE((bool)B);
402 EXPECT_EQ(3, B->val);
403 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
404 EXPECT_EQ(1u, MoveOnly::MoveAssignments);
405 EXPECT_EQ(0u, MoveOnly::Destructions);
406 }
407
408 struct Immovable {
409 static unsigned Constructions;
410 static unsigned Destructions;
411 int val;
Immovable__anon243dbdea0111::Immovable412 explicit Immovable(int val) : val(val) {
413 ++Constructions;
414 }
~Immovable__anon243dbdea0111::Immovable415 ~Immovable() {
416 ++Destructions;
417 }
ResetCounts__anon243dbdea0111::Immovable418 static void ResetCounts() {
419 Constructions = 0;
420 Destructions = 0;
421 }
422 private:
423 // This should disable all move/copy operations.
424 Immovable(Immovable&& other) = delete;
425 };
426
427 unsigned Immovable::Constructions = 0;
428 unsigned Immovable::Destructions = 0;
429
430 static_assert(!std::is_trivially_copyable<Optional<Immovable>>::value,
431 "not trivially copyable");
432
TEST(OptionalTest,ImmovableEmplace)433 TEST(OptionalTest, ImmovableEmplace) {
434 Optional<Immovable> A;
435 Immovable::ResetCounts();
436 A.emplace(4);
437 EXPECT_TRUE((bool)A);
438 EXPECT_EQ(4, A->val);
439 EXPECT_EQ(1u, Immovable::Constructions);
440 EXPECT_EQ(0u, Immovable::Destructions);
441 }
442
TEST(OptionalTest,ImmovableInPlaceConstruction)443 TEST(OptionalTest, ImmovableInPlaceConstruction) {
444 Immovable::ResetCounts();
445 Optional<Immovable> A{in_place, 4};
446 EXPECT_TRUE((bool)A);
447 EXPECT_EQ(4, A->val);
448 EXPECT_EQ(1u, Immovable::Constructions);
449 EXPECT_EQ(0u, Immovable::Destructions);
450 }
451
452 // Craft a class which is_trivially_copyable, but not
453 // is_trivially_copy_constructible.
454 struct NonTCopy {
455 NonTCopy() = default;
456
457 // Delete the volatile copy constructor to engage the "rule of 3" and delete
458 // any unspecified copy assignment or constructor.
459 NonTCopy(volatile NonTCopy const &) = delete;
460
461 // Leave the non-volatile default copy constructor unspecified (deleted by
462 // rule of 3)
463
464 // This template can serve as the copy constructor, but isn't chosen
465 // by =default in a class with a 'NonTCopy' member.
466 template <typename Self = NonTCopy>
NonTCopy__anon243dbdea0111::NonTCopy467 NonTCopy(Self const &Other) : Val(Other.Val) {}
468
469 NonTCopy &operator=(NonTCopy const &) = default;
470
471 int Val{0};
472 };
473
474 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
475 // Currently only true on recent MSVC releases.
476 static_assert(std::is_trivially_copyable<NonTCopy>::value,
477 "Expect NonTCopy to be trivially copyable");
478
479 static_assert(!std::is_trivially_copy_constructible<NonTCopy>::value,
480 "Expect NonTCopy not to be trivially copy constructible.");
481 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
482
TEST(OptionalTest,DeletedCopyConstructor)483 TEST(OptionalTest, DeletedCopyConstructor) {
484
485 // Expect compile to fail if 'trivial' version of
486 // optional_detail::OptionalStorage is chosen.
487 using NonTCopyOptT = Optional<NonTCopy>;
488 NonTCopyOptT NonTCopy1;
489
490 // Check that the Optional can be copy constructed.
491 NonTCopyOptT NonTCopy2{NonTCopy1};
492
493 // Check that the Optional can be copy assigned.
494 NonTCopy1 = NonTCopy2;
495 }
496
497 // Craft a class which is_trivially_copyable, but not
498 // is_trivially_copy_assignable.
499 class NonTAssign {
500 public:
501 NonTAssign() = default;
502 NonTAssign(NonTAssign const &) = default;
503
504 // Delete the volatile copy assignment to engage the "rule of 3" and delete
505 // any unspecified copy assignment or constructor.
506 NonTAssign &operator=(volatile NonTAssign const &) = delete;
507
508 // Leave the non-volatile default copy assignment unspecified (deleted by rule
509 // of 3).
510
511 // This template can serve as the copy assignment, but isn't chosen
512 // by =default in a class with a 'NonTAssign' member.
513 template <typename Self = NonTAssign>
operator =(Self const & Other)514 NonTAssign &operator=(Self const &Other) {
515 A = Other.A;
516 return *this;
517 }
518
519 int A{0};
520 };
521
522 #if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
523 // Currently only true on recent MSVC releases.
524 static_assert(std::is_trivially_copyable<NonTAssign>::value,
525 "Expect NonTAssign to be trivially copyable");
526
527 static_assert(!std::is_trivially_copy_assignable<NonTAssign>::value,
528 "Expect NonTAssign not to be trivially assignable.");
529 #endif // defined(_MSC_VER) && _MSC_VER >= 1927
530
TEST(OptionalTest,DeletedCopyAssignment)531 TEST(OptionalTest, DeletedCopyAssignment) {
532
533 // Expect compile to fail if 'trivial' version of
534 // optional_detail::OptionalStorage is chosen.
535 using NonTAssignOptT = Optional<NonTAssign>;
536 NonTAssignOptT NonTAssign1;
537
538 // Check that the Optional can be copy constructed.
539 NonTAssignOptT NonTAssign2{NonTAssign1};
540
541 // Check that the Optional can be copy assigned.
542 NonTAssign1 = NonTAssign2;
543 }
544
545 struct NoTMove {
546 NoTMove() = default;
547 NoTMove(NoTMove const &) = default;
548 NoTMove &operator=(NoTMove const &) = default;
549
550 // Delete move constructor / assignment. Compiler should fall-back to the
551 // trivial copy constructor / assignment in the trivial OptionalStorage
552 // specialization.
553 NoTMove(NoTMove &&) = delete;
554 NoTMove &operator=(NoTMove &&) = delete;
555
556 int Val{0};
557 };
558
TEST(OptionalTest,DeletedMoveConstructor)559 TEST(OptionalTest, DeletedMoveConstructor) {
560 using NoTMoveOptT = Optional<NoTMove>;
561
562 NoTMoveOptT NonTMove1;
563 NoTMoveOptT NonTMove2{std::move(NonTMove1)};
564
565 NonTMove1 = std::move(NonTMove2);
566
567 static_assert(
568 std::is_trivially_copyable<NoTMoveOptT>::value,
569 "Expect Optional<NoTMove> to still use the trivial specialization "
570 "of OptionalStorage despite the deleted move constructor / assignment.");
571 }
572
573 class NoCopyStringMap {
574 public:
575 NoCopyStringMap() = default;
576
577 private:
578 llvm::StringMap<std::unique_ptr<int>> Map;
579 };
580
TEST(OptionalTest,DeletedCopyStringMap)581 TEST(OptionalTest, DeletedCopyStringMap) {
582 // Old versions of gcc (7.3 and prior) instantiate the copy constructor when
583 // std::is_trivially_copyable is instantiated. This test will fail
584 // compilation if std::is_trivially_copyable is used in the OptionalStorage
585 // specialization condition by gcc <= 7.3.
586 Optional<NoCopyStringMap> TestInstantiation;
587 }
588
TEST(OptionalTest,MoveValueOr)589 TEST(OptionalTest, MoveValueOr) {
590 Optional<MoveOnly> A;
591
592 MoveOnly::ResetCounts();
593 EXPECT_EQ(42, std::move(A).value_or(MoveOnly(42)).val);
594 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
595 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
596 EXPECT_EQ(2u, MoveOnly::Destructions);
597
598 A = MoveOnly(5);
599 MoveOnly::ResetCounts();
600 EXPECT_EQ(5, std::move(A).value_or(MoveOnly(42)).val);
601 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
602 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
603 EXPECT_EQ(2u, MoveOnly::Destructions);
604 }
605
606 struct EqualTo {
apply__anon243dbdea0111::EqualTo607 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
608 return X == Y;
609 }
610 };
611
612 struct NotEqualTo {
apply__anon243dbdea0111::NotEqualTo613 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
614 return X != Y;
615 }
616 };
617
618 struct Less {
apply__anon243dbdea0111::Less619 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
620 return X < Y;
621 }
622 };
623
624 struct Greater {
apply__anon243dbdea0111::Greater625 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
626 return X > Y;
627 }
628 };
629
630 struct LessEqual {
apply__anon243dbdea0111::LessEqual631 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
632 return X <= Y;
633 }
634 };
635
636 struct GreaterEqual {
apply__anon243dbdea0111::GreaterEqual637 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
638 return X >= Y;
639 }
640 };
641
642 template <typename OperatorT, typename T>
CheckRelation(const Optional<T> & Lhs,const Optional<T> & Rhs,bool Expected)643 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
644 bool Expected) {
645 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
646
647 if (Lhs)
648 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
649 else
650 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
651
652 if (Rhs)
653 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
654 else
655 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
656 }
657
658 struct EqualityMock {};
659 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
660 EqualityRhs((EqualityMock()));
661 bool IsEqual;
662
operator ==(const EqualityMock & Lhs,const EqualityMock & Rhs)663 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
664 EXPECT_EQ(&*EqualityLhs, &Lhs);
665 EXPECT_EQ(&*EqualityRhs, &Rhs);
666 return IsEqual;
667 }
668
TEST(OptionalTest,OperatorEqual)669 TEST(OptionalTest, OperatorEqual) {
670 CheckRelation<EqualTo>(NoneEq, NoneEq, true);
671 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
672 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
673
674 IsEqual = false;
675 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
676 IsEqual = true;
677 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
678 }
679
TEST(OptionalTest,OperatorNotEqual)680 TEST(OptionalTest, OperatorNotEqual) {
681 CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
682 CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
683 CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
684
685 IsEqual = false;
686 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
687 IsEqual = true;
688 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
689 }
690
691 struct InequalityMock {};
692 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
693 InequalityRhs((InequalityMock()));
694 bool IsLess;
695
operator <(const InequalityMock & Lhs,const InequalityMock & Rhs)696 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
697 EXPECT_EQ(&*InequalityLhs, &Lhs);
698 EXPECT_EQ(&*InequalityRhs, &Rhs);
699 return IsLess;
700 }
701
TEST(OptionalTest,OperatorLess)702 TEST(OptionalTest, OperatorLess) {
703 CheckRelation<Less>(NoneIneq, NoneIneq, false);
704 CheckRelation<Less>(NoneIneq, InequalityRhs, true);
705 CheckRelation<Less>(InequalityLhs, NoneIneq, false);
706
707 IsLess = false;
708 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
709 IsLess = true;
710 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
711 }
712
TEST(OptionalTest,OperatorGreater)713 TEST(OptionalTest, OperatorGreater) {
714 CheckRelation<Greater>(NoneIneq, NoneIneq, false);
715 CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
716 CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
717
718 IsLess = false;
719 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
720 IsLess = true;
721 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
722 }
723
TEST(OptionalTest,OperatorLessEqual)724 TEST(OptionalTest, OperatorLessEqual) {
725 CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
726 CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
727 CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
728
729 IsLess = false;
730 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
731 IsLess = true;
732 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
733 }
734
TEST(OptionalTest,OperatorGreaterEqual)735 TEST(OptionalTest, OperatorGreaterEqual) {
736 CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
737 CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
738 CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
739
740 IsLess = false;
741 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
742 IsLess = true;
743 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
744 }
745
746 struct ComparableAndStreamable {
operator ==(ComparableAndStreamable,ComparableAndStreamable)747 friend bool operator==(ComparableAndStreamable,
748 ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
749 return true;
750 }
751
operator <<(raw_ostream & OS,ComparableAndStreamable)752 friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
753 return OS << "ComparableAndStreamable";
754 }
755
get__anon243dbdea0111::ComparableAndStreamable756 static Optional<ComparableAndStreamable> get() {
757 return ComparableAndStreamable();
758 }
759 };
760
TEST(OptionalTest,StreamOperator)761 TEST(OptionalTest, StreamOperator) {
762 auto to_string = [](Optional<ComparableAndStreamable> O) {
763 SmallString<16> S;
764 raw_svector_ostream OS(S);
765 OS << O;
766 return S;
767 };
768 EXPECT_EQ("ComparableAndStreamable",
769 to_string(ComparableAndStreamable::get()));
770 EXPECT_EQ("None", to_string(None));
771 }
772
773 struct Comparable {
operator ==(Comparable,Comparable)774 friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
775 return true;
776 }
get__anon243dbdea0111::Comparable777 static Optional<Comparable> get() { return Comparable(); }
778 };
779
TEST(OptionalTest,UseInUnitTests)780 TEST(OptionalTest, UseInUnitTests) {
781 // Test that we invoke the streaming operators when pretty-printing values in
782 // EXPECT macros.
783 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
784 "Expected equality of these values:\n"
785 " llvm::None\n"
786 " Which is: None\n"
787 " ComparableAndStreamable::get()\n"
788 " Which is: ComparableAndStreamable");
789
790 // Test that it is still possible to compare objects which do not have a
791 // custom streaming operator.
792 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
793 }
794
TEST(OptionalTest,HashValue)795 TEST(OptionalTest, HashValue) {
796 // Check that None, false, and true all hash differently.
797 Optional<bool> B, B0 = false, B1 = true;
798 EXPECT_NE(hash_value(B0), hash_value(B));
799 EXPECT_NE(hash_value(B1), hash_value(B));
800 EXPECT_NE(hash_value(B1), hash_value(B0));
801
802 // Check that None, 0, and 1 all hash differently.
803 Optional<int> I, I0 = 0, I1 = 1;
804 EXPECT_NE(hash_value(I0), hash_value(I));
805 EXPECT_NE(hash_value(I1), hash_value(I));
806 EXPECT_NE(hash_value(I1), hash_value(I0));
807
808 // Check None hash the same way regardless of type.
809 EXPECT_EQ(hash_value(B), hash_value(I));
810 }
811
812 struct NotTriviallyCopyable {
813 NotTriviallyCopyable(); // Constructor out-of-line.
814 virtual ~NotTriviallyCopyable() = default;
815 Optional<MoveOnly> MO;
816 };
817
TEST(OptionalTest,GCCIsTriviallyMoveConstructibleCompat)818 TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) {
819 Optional<NotTriviallyCopyable> V;
820 EXPECT_FALSE(V);
821 }
822
823 } // end anonymous namespace
824