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