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