1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "gtest/gtest.h"
11 #include "llvm/ADT/Optional.h"
12 using namespace llvm;
13 
14 namespace {
15 
16 struct NonDefaultConstructible {
17   static unsigned CopyConstructions;
18   static unsigned Destructions;
19   static unsigned CopyAssignments;
NonDefaultConstructible__anon9733531c0111::NonDefaultConstructible20   explicit NonDefaultConstructible(int) {
21   }
NonDefaultConstructible__anon9733531c0111::NonDefaultConstructible22   NonDefaultConstructible(const NonDefaultConstructible&) {
23     ++CopyConstructions;
24   }
operator =__anon9733531c0111::NonDefaultConstructible25   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
26     ++CopyAssignments;
27     return *this;
28   }
~NonDefaultConstructible__anon9733531c0111::NonDefaultConstructible29   ~NonDefaultConstructible() {
30     ++Destructions;
31   }
ResetCounts__anon9733531c0111::NonDefaultConstructible32   static void ResetCounts() {
33     CopyConstructions = 0;
34     Destructions = 0;
35     CopyAssignments = 0;
36   }
37 };
38 
39 unsigned NonDefaultConstructible::CopyConstructions = 0;
40 unsigned NonDefaultConstructible::Destructions = 0;
41 unsigned NonDefaultConstructible::CopyAssignments = 0;
42 
43 // Test fixture
44 class OptionalTest : public testing::Test {
45 };
46 
TEST_F(OptionalTest,NonDefaultConstructibleTest)47 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
48   Optional<NonDefaultConstructible> O;
49   EXPECT_FALSE(O);
50 }
51 
TEST_F(OptionalTest,ResetTest)52 TEST_F(OptionalTest, ResetTest) {
53   NonDefaultConstructible::ResetCounts();
54   Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
55   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
56   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
57   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
58   NonDefaultConstructible::ResetCounts();
59   O.reset();
60   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
61   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
62   EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
63 }
64 
TEST_F(OptionalTest,InitializationLeakTest)65 TEST_F(OptionalTest, InitializationLeakTest) {
66   NonDefaultConstructible::ResetCounts();
67   Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
68   EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
69   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
70   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
71 }
72 
TEST_F(OptionalTest,CopyConstructionTest)73 TEST_F(OptionalTest, CopyConstructionTest) {
74   NonDefaultConstructible::ResetCounts();
75   {
76     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
77     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
78     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
79     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
80     NonDefaultConstructible::ResetCounts();
81     Optional<NonDefaultConstructible> B(A);
82     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
83     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
84     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
85     NonDefaultConstructible::ResetCounts();
86   }
87   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
88   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
89   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
90 }
91 
TEST_F(OptionalTest,ConstructingCopyAssignmentTest)92 TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
93   NonDefaultConstructible::ResetCounts();
94   {
95     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
96     Optional<NonDefaultConstructible> B;
97     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
98     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
99     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
100     NonDefaultConstructible::ResetCounts();
101     B = A;
102     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
103     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
104     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
105     NonDefaultConstructible::ResetCounts();
106   }
107   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
108   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
109   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
110 }
111 
TEST_F(OptionalTest,CopyingCopyAssignmentTest)112 TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
113   NonDefaultConstructible::ResetCounts();
114   {
115     Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
116     Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
117     EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
118     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
119     EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
120     NonDefaultConstructible::ResetCounts();
121     B = A;
122     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
123     EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
124     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
125     NonDefaultConstructible::ResetCounts();
126   }
127   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
128   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
129   EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
130 }
131 
TEST_F(OptionalTest,DeletingCopyAssignmentTest)132 TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
133   NonDefaultConstructible::ResetCounts();
134   {
135     Optional<NonDefaultConstructible> A;
136     Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
137     EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
138     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
139     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
140     NonDefaultConstructible::ResetCounts();
141     B = A;
142     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
143     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
144     EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
145     NonDefaultConstructible::ResetCounts();
146   }
147   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
148   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
149   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
150 }
151 
TEST_F(OptionalTest,NullCopyConstructionTest)152 TEST_F(OptionalTest, NullCopyConstructionTest) {
153   NonDefaultConstructible::ResetCounts();
154   {
155     Optional<NonDefaultConstructible> A;
156     Optional<NonDefaultConstructible> B;
157     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
158     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
159     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
160     NonDefaultConstructible::ResetCounts();
161     B = A;
162     EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
163     EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
164     EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
165     NonDefaultConstructible::ResetCounts();
166   }
167   EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
168   EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
169   EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
170 }
171 
TEST_F(OptionalTest,GetValueOr)172 TEST_F(OptionalTest, GetValueOr) {
173   Optional<int> A;
174   EXPECT_EQ(42, A.getValueOr(42));
175 
176   A = 5;
177   EXPECT_EQ(5, A.getValueOr(42));
178 }
179 
180 struct MultiArgConstructor {
181   int x, y;
MultiArgConstructor__anon9733531c0111::MultiArgConstructor182   MultiArgConstructor(int x, int y) : x(x), y(y) {}
MultiArgConstructor__anon9733531c0111::MultiArgConstructor183   explicit MultiArgConstructor(int x, bool positive)
184     : x(x), y(positive ? x : -x) {}
185 
186   MultiArgConstructor(const MultiArgConstructor &) = delete;
187   MultiArgConstructor(MultiArgConstructor &&) = delete;
188   MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
189   MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
190 
191   static unsigned Destructions;
~MultiArgConstructor__anon9733531c0111::MultiArgConstructor192   ~MultiArgConstructor() {
193     ++Destructions;
194   }
ResetCounts__anon9733531c0111::MultiArgConstructor195   static void ResetCounts() {
196     Destructions = 0;
197   }
198 };
199 unsigned MultiArgConstructor::Destructions = 0;
200 
TEST_F(OptionalTest,Emplace)201 TEST_F(OptionalTest, Emplace) {
202   MultiArgConstructor::ResetCounts();
203   Optional<MultiArgConstructor> A;
204 
205   A.emplace(1, 2);
206   EXPECT_TRUE(A.hasValue());
207   EXPECT_EQ(1, A->x);
208   EXPECT_EQ(2, A->y);
209   EXPECT_EQ(0u, MultiArgConstructor::Destructions);
210 
211   A.emplace(5, false);
212   EXPECT_TRUE(A.hasValue());
213   EXPECT_EQ(5, A->x);
214   EXPECT_EQ(-5, A->y);
215   EXPECT_EQ(1u, MultiArgConstructor::Destructions);
216 }
217 
218 struct MoveOnly {
219   static unsigned MoveConstructions;
220   static unsigned Destructions;
221   static unsigned MoveAssignments;
222   int val;
MoveOnly__anon9733531c0111::MoveOnly223   explicit MoveOnly(int val) : val(val) {
224   }
MoveOnly__anon9733531c0111::MoveOnly225   MoveOnly(MoveOnly&& other) {
226     val = other.val;
227     ++MoveConstructions;
228   }
operator =__anon9733531c0111::MoveOnly229   MoveOnly &operator=(MoveOnly&& other) {
230     val = other.val;
231     ++MoveAssignments;
232     return *this;
233   }
~MoveOnly__anon9733531c0111::MoveOnly234   ~MoveOnly() {
235     ++Destructions;
236   }
ResetCounts__anon9733531c0111::MoveOnly237   static void ResetCounts() {
238     MoveConstructions = 0;
239     Destructions = 0;
240     MoveAssignments = 0;
241   }
242 };
243 
244 unsigned MoveOnly::MoveConstructions = 0;
245 unsigned MoveOnly::Destructions = 0;
246 unsigned MoveOnly::MoveAssignments = 0;
247 
TEST_F(OptionalTest,MoveOnlyNull)248 TEST_F(OptionalTest, MoveOnlyNull) {
249   MoveOnly::ResetCounts();
250   Optional<MoveOnly> O;
251   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
252   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
253   EXPECT_EQ(0u, MoveOnly::Destructions);
254 }
255 
TEST_F(OptionalTest,MoveOnlyConstruction)256 TEST_F(OptionalTest, MoveOnlyConstruction) {
257   MoveOnly::ResetCounts();
258   Optional<MoveOnly> O(MoveOnly(3));
259   EXPECT_TRUE((bool)O);
260   EXPECT_EQ(3, O->val);
261   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
262   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
263   EXPECT_EQ(1u, MoveOnly::Destructions);
264 }
265 
TEST_F(OptionalTest,MoveOnlyMoveConstruction)266 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
267   Optional<MoveOnly> A(MoveOnly(3));
268   MoveOnly::ResetCounts();
269   Optional<MoveOnly> B(std::move(A));
270   EXPECT_FALSE((bool)A);
271   EXPECT_TRUE((bool)B);
272   EXPECT_EQ(3, B->val);
273   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
274   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
275   EXPECT_EQ(1u, MoveOnly::Destructions);
276 }
277 
TEST_F(OptionalTest,MoveOnlyAssignment)278 TEST_F(OptionalTest, MoveOnlyAssignment) {
279   MoveOnly::ResetCounts();
280   Optional<MoveOnly> O;
281   O = MoveOnly(3);
282   EXPECT_TRUE((bool)O);
283   EXPECT_EQ(3, O->val);
284   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
285   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
286   EXPECT_EQ(1u, MoveOnly::Destructions);
287 }
288 
TEST_F(OptionalTest,MoveOnlyInitializingAssignment)289 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
290   Optional<MoveOnly> A(MoveOnly(3));
291   Optional<MoveOnly> B;
292   MoveOnly::ResetCounts();
293   B = std::move(A);
294   EXPECT_FALSE((bool)A);
295   EXPECT_TRUE((bool)B);
296   EXPECT_EQ(3, B->val);
297   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
298   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
299   EXPECT_EQ(1u, MoveOnly::Destructions);
300 }
301 
TEST_F(OptionalTest,MoveOnlyNullingAssignment)302 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
303   Optional<MoveOnly> A;
304   Optional<MoveOnly> B(MoveOnly(3));
305   MoveOnly::ResetCounts();
306   B = std::move(A);
307   EXPECT_FALSE((bool)A);
308   EXPECT_FALSE((bool)B);
309   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
310   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
311   EXPECT_EQ(1u, MoveOnly::Destructions);
312 }
313 
TEST_F(OptionalTest,MoveOnlyAssigningAssignment)314 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
315   Optional<MoveOnly> A(MoveOnly(3));
316   Optional<MoveOnly> B(MoveOnly(4));
317   MoveOnly::ResetCounts();
318   B = std::move(A);
319   EXPECT_FALSE((bool)A);
320   EXPECT_TRUE((bool)B);
321   EXPECT_EQ(3, B->val);
322   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
323   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
324   EXPECT_EQ(1u, MoveOnly::Destructions);
325 }
326 
327 struct Immovable {
328   static unsigned Constructions;
329   static unsigned Destructions;
330   int val;
Immovable__anon9733531c0111::Immovable331   explicit Immovable(int val) : val(val) {
332     ++Constructions;
333   }
~Immovable__anon9733531c0111::Immovable334   ~Immovable() {
335     ++Destructions;
336   }
ResetCounts__anon9733531c0111::Immovable337   static void ResetCounts() {
338     Constructions = 0;
339     Destructions = 0;
340   }
341 private:
342   // This should disable all move/copy operations.
343   Immovable(Immovable&& other) = delete;
344 };
345 
346 unsigned Immovable::Constructions = 0;
347 unsigned Immovable::Destructions = 0;
348 
TEST_F(OptionalTest,ImmovableEmplace)349 TEST_F(OptionalTest, ImmovableEmplace) {
350   Optional<Immovable> A;
351   Immovable::ResetCounts();
352   A.emplace(4);
353   EXPECT_TRUE((bool)A);
354   EXPECT_EQ(4, A->val);
355   EXPECT_EQ(1u, Immovable::Constructions);
356   EXPECT_EQ(0u, Immovable::Destructions);
357 }
358 
359 #if LLVM_HAS_RVALUE_REFERENCE_THIS
360 
TEST_F(OptionalTest,MoveGetValueOr)361 TEST_F(OptionalTest, MoveGetValueOr) {
362   Optional<MoveOnly> A;
363 
364   MoveOnly::ResetCounts();
365   EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
366   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
367   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
368   EXPECT_EQ(2u, MoveOnly::Destructions);
369 
370   A = MoveOnly(5);
371   MoveOnly::ResetCounts();
372   EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
373   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
374   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
375   EXPECT_EQ(2u, MoveOnly::Destructions);
376 }
377 
378 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
379 
380 } // end anonymous namespace
381 
382