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 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;
    182   MultiArgConstructor(int x, int y) : x(x), y(y) {}
    183   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;
    192   ~MultiArgConstructor() {
    193     ++Destructions;
    194   }
    195   static void ResetCounts() {
    196     Destructions = 0;
    197   }
    198 };
    199 unsigned MultiArgConstructor::Destructions = 0;
    200 
    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;
    223   explicit MoveOnly(int val) : val(val) {
    224   }
    225   MoveOnly(MoveOnly&& other) {
    226     val = other.val;
    227     ++MoveConstructions;
    228   }
    229   MoveOnly &operator=(MoveOnly&& other) {
    230     val = other.val;
    231     ++MoveAssignments;
    232     return *this;
    233   }
    234   ~MoveOnly() {
    235     ++Destructions;
    236   }
    237   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 
    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 
    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 
    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 
    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 
    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 
    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 
    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;
    331   explicit Immovable(int val) : val(val) {
    332     ++Constructions;
    333   }
    334   ~Immovable() {
    335     ++Destructions;
    336   }
    337   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 
    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 
    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 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