Home | History | Annotate | Download | only in ADT
      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;
     20   explicit NonDefaultConstructible(int) {
     21   }
     22   NonDefaultConstructible(const NonDefaultConstructible&) {
     23     ++CopyConstructions;
     24   }
     25   NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
     26     ++CopyAssignments;
     27     return *this;
     28   }
     29   ~NonDefaultConstructible() {
     30     ++Destructions;
     31   }
     32   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 
     47 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
     48   Optional<NonDefaultConstructible> O;
     49   EXPECT_FALSE(O);
     50 }
     51 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    172 #if LLVM_HAS_RVALUE_REFERENCES
    173 struct MoveOnly {
    174   static unsigned MoveConstructions;
    175   static unsigned Destructions;
    176   static unsigned MoveAssignments;
    177   int val;
    178   explicit MoveOnly(int val) : val(val) {
    179   }
    180   MoveOnly(MoveOnly&& other) {
    181     val = other.val;
    182     ++MoveConstructions;
    183   }
    184   MoveOnly &operator=(MoveOnly&& other) {
    185     val = other.val;
    186     ++MoveAssignments;
    187     return *this;
    188   }
    189   ~MoveOnly() {
    190     ++Destructions;
    191   }
    192   static void ResetCounts() {
    193     MoveConstructions = 0;
    194     Destructions = 0;
    195     MoveAssignments = 0;
    196   }
    197 };
    198 
    199 unsigned MoveOnly::MoveConstructions = 0;
    200 unsigned MoveOnly::Destructions = 0;
    201 unsigned MoveOnly::MoveAssignments = 0;
    202 
    203 TEST_F(OptionalTest, MoveOnlyNull) {
    204   MoveOnly::ResetCounts();
    205   Optional<MoveOnly> O;
    206   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
    207   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    208   EXPECT_EQ(0u, MoveOnly::Destructions);
    209 }
    210 
    211 TEST_F(OptionalTest, MoveOnlyConstruction) {
    212   MoveOnly::ResetCounts();
    213   Optional<MoveOnly> O(MoveOnly(3));
    214   EXPECT_TRUE((bool)O);
    215   EXPECT_EQ(3, O->val);
    216   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
    217   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    218   EXPECT_EQ(1u, MoveOnly::Destructions);
    219 }
    220 
    221 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
    222   Optional<MoveOnly> A(MoveOnly(3));
    223   MoveOnly::ResetCounts();
    224   Optional<MoveOnly> B(std::move(A));
    225   EXPECT_FALSE((bool)A);
    226   EXPECT_TRUE((bool)B);
    227   EXPECT_EQ(3, B->val);
    228   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
    229   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    230   EXPECT_EQ(1u, MoveOnly::Destructions);
    231 }
    232 
    233 TEST_F(OptionalTest, MoveOnlyAssignment) {
    234   MoveOnly::ResetCounts();
    235   Optional<MoveOnly> O;
    236   O = MoveOnly(3);
    237   EXPECT_TRUE((bool)O);
    238   EXPECT_EQ(3, O->val);
    239   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
    240   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    241   EXPECT_EQ(1u, MoveOnly::Destructions);
    242 }
    243 
    244 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
    245   Optional<MoveOnly> A(MoveOnly(3));
    246   Optional<MoveOnly> B;
    247   MoveOnly::ResetCounts();
    248   B = std::move(A);
    249   EXPECT_FALSE((bool)A);
    250   EXPECT_TRUE((bool)B);
    251   EXPECT_EQ(3, B->val);
    252   EXPECT_EQ(1u, MoveOnly::MoveConstructions);
    253   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    254   EXPECT_EQ(1u, MoveOnly::Destructions);
    255 }
    256 
    257 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
    258   Optional<MoveOnly> A;
    259   Optional<MoveOnly> B(MoveOnly(3));
    260   MoveOnly::ResetCounts();
    261   B = std::move(A);
    262   EXPECT_FALSE((bool)A);
    263   EXPECT_FALSE((bool)B);
    264   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
    265   EXPECT_EQ(0u, MoveOnly::MoveAssignments);
    266   EXPECT_EQ(1u, MoveOnly::Destructions);
    267 }
    268 
    269 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
    270   Optional<MoveOnly> A(MoveOnly(3));
    271   Optional<MoveOnly> B(MoveOnly(4));
    272   MoveOnly::ResetCounts();
    273   B = std::move(A);
    274   EXPECT_FALSE((bool)A);
    275   EXPECT_TRUE((bool)B);
    276   EXPECT_EQ(3, B->val);
    277   EXPECT_EQ(0u, MoveOnly::MoveConstructions);
    278   EXPECT_EQ(1u, MoveOnly::MoveAssignments);
    279   EXPECT_EQ(1u, MoveOnly::Destructions);
    280 }
    281 #endif
    282 
    283 } // end anonymous namespace
    284 
    285