• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
TEST_F(OptionalTest,NoneComparison)380  TEST_F(OptionalTest, NoneComparison) {
381    Optional<int> o;
382    EXPECT_EQ(o, None);
383    EXPECT_EQ(None, o);
384    EXPECT_FALSE(o != None);
385    EXPECT_FALSE(None != o);
386    o = 3;
387    EXPECT_FALSE(o == None);
388    EXPECT_FALSE(None == o);
389    EXPECT_TRUE(o != None);
390    EXPECT_TRUE(None != o);
391  }
392  
393  } // end anonymous namespace
394  
395