| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license | |
| 5 * that can be found in the LICENSE file in the root of the source | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 #include <memory> | |
| 12 #include <sstream> | |
| 13 #include <string> | |
| 14 #include <utility> | |
| 15 #include <vector> | |
| 16 | |
| 17 #include "webrtc/base/gunit.h" | |
| 18 #include "webrtc/base/optional.h" | |
| 19 | |
| 20 namespace rtc { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 struct MyUnprintableType { | |
| 25 int value; | |
| 26 }; | |
| 27 | |
| 28 struct MyPrintableType { | |
| 29 int value; | |
| 30 }; | |
| 31 | |
| 32 struct MyOstreamPrintableType { | |
| 33 int value; | |
| 34 }; | |
| 35 | |
| 36 void PrintTo(const MyPrintableType& mpt, std::ostream* os) { | |
| 37 *os << "The value is " << mpt.value; | |
| 38 } | |
| 39 | |
| 40 std::ostream& operator<<(std::ostream& os, | |
| 41 const MyPrintableType& mpt) { | |
| 42 os << mpt.value; | |
| 43 return os; | |
| 44 } | |
| 45 | |
| 46 std::ostream& operator<<(std::ostream& os, | |
| 47 const MyOstreamPrintableType& mpt) { | |
| 48 os << mpt.value; | |
| 49 return os; | |
| 50 } | |
| 51 | |
| 52 // Class whose instances logs various method calls (constructor, destructor, | |
| 53 // etc.). Each instance has a unique ID (a simple global sequence number) and | |
| 54 // an origin ID. When a copy is made, the new object gets a fresh ID but copies | |
| 55 // the origin ID from the original. When a new Logger is created from scratch, | |
| 56 // it gets a fresh ID, and the origin ID is the same as the ID (default | |
| 57 // constructor) or given as an argument (explicit constructor). | |
| 58 class Logger { | |
| 59 public: | |
| 60 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); } | |
| 61 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) { | |
| 62 Log("explicit constructor"); | |
| 63 } | |
| 64 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value) | |
| 65 : id_(g_next_id++), origin_(origin) { | |
| 66 Log("multi parameter constructor"); | |
| 67 } | |
| 68 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) { | |
| 69 LogFrom("copy constructor", other); | |
| 70 } | |
| 71 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) { | |
| 72 LogFrom("move constructor", other); | |
| 73 } | |
| 74 ~Logger() { Log("destructor"); } | |
| 75 Logger& operator=(const Logger& other) { | |
| 76 origin_ = other.origin_; | |
| 77 LogFrom("operator= copy", other); | |
| 78 return *this; | |
| 79 } | |
| 80 Logger& operator=(Logger&& other) { | |
| 81 origin_ = other.origin_; | |
| 82 LogFrom("operator= move", other); | |
| 83 return *this; | |
| 84 } | |
| 85 friend void swap(Logger& a, Logger& b) { | |
| 86 using std::swap; | |
| 87 swap(a.origin_, b.origin_); | |
| 88 Log2("swap", a, b); | |
| 89 } | |
| 90 friend bool operator==(const Logger& a, const Logger& b) { | |
| 91 Log2("operator==", a, b); | |
| 92 return a.origin_ == b.origin_; | |
| 93 } | |
| 94 friend bool operator!=(const Logger& a, const Logger& b) { | |
| 95 Log2("operator!=", a, b); | |
| 96 return a.origin_ != b.origin_; | |
| 97 } | |
| 98 void Foo() { Log("Foo()"); } | |
| 99 void Foo() const { Log("Foo() const"); } | |
| 100 static std::unique_ptr<std::vector<std::string>> Setup() { | |
| 101 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>); | |
| 102 g_log = s.get(); | |
| 103 g_next_id = 0; | |
| 104 return s; | |
| 105 } | |
| 106 | |
| 107 private: | |
| 108 int id_; | |
| 109 int origin_; | |
| 110 static std::vector<std::string>* g_log; | |
| 111 static int g_next_id; | |
| 112 void Log(const char* msg) const { | |
| 113 std::ostringstream oss; | |
| 114 oss << id_ << ':' << origin_ << ". " << msg; | |
| 115 g_log->push_back(oss.str()); | |
| 116 } | |
| 117 void LogFrom(const char* msg, const Logger& other) const { | |
| 118 std::ostringstream oss; | |
| 119 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':' | |
| 120 << other.origin_ << ")"; | |
| 121 g_log->push_back(oss.str()); | |
| 122 } | |
| 123 static void Log2(const char* msg, const Logger& a, const Logger& b) { | |
| 124 std::ostringstream oss; | |
| 125 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':' | |
| 126 << b.origin_; | |
| 127 g_log->push_back(oss.str()); | |
| 128 } | |
| 129 }; | |
| 130 | |
| 131 std::vector<std::string>* Logger::g_log = nullptr; | |
| 132 int Logger::g_next_id = 0; | |
| 133 | |
| 134 // Append all the other args to the vector pointed to by the first arg. | |
| 135 template <typename T> | |
| 136 void VectorAppend(std::vector<T>* v) {} | |
| 137 template <typename T, typename... Ts> | |
| 138 void VectorAppend(std::vector<T>* v, const T& e, Ts... es) { | |
| 139 v->push_back(e); | |
| 140 VectorAppend(v, es...); | |
| 141 } | |
| 142 | |
| 143 // Create a vector of strings. Because we're not allowed to use | |
| 144 // std::initializer_list. | |
| 145 template <typename... Ts> | |
| 146 std::vector<std::string> V(Ts... es) { | |
| 147 std::vector<std::string> strings; | |
| 148 VectorAppend(&strings, static_cast<std::string>(es)...); | |
| 149 return strings; | |
| 150 } | |
| 151 | |
| 152 } // namespace | |
| 153 | |
| 154 TEST(OptionalTest, TestConstructDefault) { | |
| 155 auto log = Logger::Setup(); | |
| 156 { | |
| 157 Optional<Logger> x; | |
| 158 EXPECT_FALSE(x); | |
| 159 EXPECT_FALSE(x.has_value()); | |
| 160 } | |
| 161 EXPECT_EQ(V(), *log); | |
| 162 } | |
| 163 | |
| 164 TEST(OptionalTest, TestConstructCopyEmpty) { | |
| 165 auto log = Logger::Setup(); | |
| 166 { | |
| 167 Optional<Logger> x; | |
| 168 EXPECT_FALSE(x); | |
| 169 EXPECT_FALSE(x.has_value()); | |
| 170 auto y = x; | |
| 171 EXPECT_FALSE(y); | |
| 172 EXPECT_FALSE(y.has_value()); | |
| 173 } | |
| 174 EXPECT_EQ(V(), *log); | |
| 175 } | |
| 176 | |
| 177 TEST(OptionalTest, TestConstructCopyFull) { | |
| 178 auto log = Logger::Setup(); | |
| 179 { | |
| 180 Logger a; | |
| 181 Optional<Logger> x(a); | |
| 182 EXPECT_TRUE(x); | |
| 183 EXPECT_TRUE(x.has_value()); | |
| 184 log->push_back("---"); | |
| 185 auto y = x; | |
| 186 EXPECT_TRUE(y); | |
| 187 EXPECT_TRUE(y.has_value()); | |
| 188 log->push_back("---"); | |
| 189 } | |
| 190 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)", | |
| 191 "---", "2:0. copy constructor (from 1:0)", "---", | |
| 192 "2:0. destructor", "1:0. destructor", "0:0. destructor"), | |
| 193 *log); | |
| 194 } | |
| 195 | |
| 196 TEST(OptionalTest, TestConstructMoveEmpty) { | |
| 197 auto log = Logger::Setup(); | |
| 198 { | |
| 199 Optional<Logger> x; | |
| 200 EXPECT_FALSE(x); | |
| 201 EXPECT_FALSE(x.has_value()); | |
| 202 auto y = std::move(x); | |
| 203 EXPECT_FALSE(y); | |
| 204 EXPECT_FALSE(y.has_value()); | |
| 205 } | |
| 206 EXPECT_EQ(V(), *log); | |
| 207 } | |
| 208 | |
| 209 TEST(OptionalTest, TestConstructMoveFull) { | |
| 210 auto log = Logger::Setup(); | |
| 211 { | |
| 212 Optional<Logger> x(Logger(17)); | |
| 213 EXPECT_TRUE(x); | |
| 214 EXPECT_TRUE(x.has_value()); | |
| 215 log->push_back("---"); | |
| 216 auto y = std::move(x); | |
| 217 EXPECT_TRUE(x); | |
| 218 EXPECT_TRUE(x.has_value()); | |
| 219 EXPECT_TRUE(y); | |
| 220 EXPECT_TRUE(y.has_value()); | |
| 221 log->push_back("---"); | |
| 222 } | |
| 223 EXPECT_EQ( | |
| 224 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 225 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---", | |
| 226 "2:17. destructor", "1:17. destructor"), | |
| 227 *log); | |
| 228 } | |
| 229 | |
| 230 TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) { | |
| 231 auto log = Logger::Setup(); | |
| 232 { | |
| 233 Optional<Logger> x, y; | |
| 234 x = y; | |
| 235 } | |
| 236 EXPECT_EQ(V(), *log); | |
| 237 } | |
| 238 | |
| 239 TEST(OptionalTest, TestCopyAssignToFullFromEmpty) { | |
| 240 auto log = Logger::Setup(); | |
| 241 { | |
| 242 Optional<Logger> x(Logger(17)); | |
| 243 Optional<Logger> y; | |
| 244 log->push_back("---"); | |
| 245 x = y; | |
| 246 log->push_back("---"); | |
| 247 } | |
| 248 EXPECT_EQ( | |
| 249 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 250 "0:17. destructor", "---", "1:17. destructor", "---"), | |
| 251 *log); | |
| 252 } | |
| 253 | |
| 254 TEST(OptionalTest, TestCopyAssignToEmptyFromFull) { | |
| 255 auto log = Logger::Setup(); | |
| 256 { | |
| 257 Optional<Logger> x; | |
| 258 Optional<Logger> y(Logger(17)); | |
| 259 log->push_back("---"); | |
| 260 x = y; | |
| 261 log->push_back("---"); | |
| 262 } | |
| 263 EXPECT_EQ( | |
| 264 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 265 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---", | |
| 266 "1:17. destructor", "2:17. destructor"), | |
| 267 *log); | |
| 268 } | |
| 269 | |
| 270 TEST(OptionalTest, TestCopyAssignToFullFromFull) { | |
| 271 auto log = Logger::Setup(); | |
| 272 { | |
| 273 Optional<Logger> x(Logger(17)); | |
| 274 Optional<Logger> y(Logger(42)); | |
| 275 log->push_back("---"); | |
| 276 x = y; | |
| 277 log->push_back("---"); | |
| 278 } | |
| 279 EXPECT_EQ( | |
| 280 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 281 "0:17. destructor", "2:42. explicit constructor", | |
| 282 "3:42. move constructor (from 2:42)", "2:42. destructor", "---", | |
| 283 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor", | |
| 284 "1:42. destructor"), | |
| 285 *log); | |
| 286 } | |
| 287 | |
| 288 TEST(OptionalTest, TestCopyAssignToEmptyFromT) { | |
| 289 auto log = Logger::Setup(); | |
| 290 { | |
| 291 Optional<Logger> x; | |
| 292 Logger y(17); | |
| 293 log->push_back("---"); | |
| 294 x = Optional<Logger>(y); | |
| 295 log->push_back("---"); | |
| 296 } | |
| 297 EXPECT_EQ(V("0:17. explicit constructor", "---", | |
| 298 "1:17. copy constructor (from 0:17)", | |
| 299 "2:17. move constructor (from 1:17)", "1:17. destructor", "---", | |
| 300 "0:17. destructor", "2:17. destructor"), | |
| 301 *log); | |
| 302 } | |
| 303 | |
| 304 TEST(OptionalTest, TestCopyAssignToFullFromT) { | |
| 305 auto log = Logger::Setup(); | |
| 306 { | |
| 307 Optional<Logger> x(Logger(17)); | |
| 308 Logger y(42); | |
| 309 log->push_back("---"); | |
| 310 x = Optional<Logger>(y); | |
| 311 log->push_back("---"); | |
| 312 } | |
| 313 EXPECT_EQ( | |
| 314 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 315 "0:17. destructor", "2:42. explicit constructor", "---", | |
| 316 "3:42. copy constructor (from 2:42)", | |
| 317 "1:42. operator= move (from 3:42)", "3:42. destructor", "---", | |
| 318 "2:42. destructor", "1:42. destructor"), | |
| 319 *log); | |
| 320 } | |
| 321 | |
| 322 TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) { | |
| 323 auto log = Logger::Setup(); | |
| 324 { | |
| 325 Optional<Logger> x, y; | |
| 326 x = std::move(y); | |
| 327 } | |
| 328 EXPECT_EQ(V(), *log); | |
| 329 } | |
| 330 | |
| 331 TEST(OptionalTest, TestMoveAssignToFullFromEmpty) { | |
| 332 auto log = Logger::Setup(); | |
| 333 { | |
| 334 Optional<Logger> x(Logger(17)); | |
| 335 Optional<Logger> y; | |
| 336 log->push_back("---"); | |
| 337 x = std::move(y); | |
| 338 log->push_back("---"); | |
| 339 } | |
| 340 EXPECT_EQ( | |
| 341 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 342 "0:17. destructor", "---", "1:17. destructor", "---"), | |
| 343 *log); | |
| 344 } | |
| 345 | |
| 346 TEST(OptionalTest, TestMoveAssignToEmptyFromFull) { | |
| 347 auto log = Logger::Setup(); | |
| 348 { | |
| 349 Optional<Logger> x; | |
| 350 Optional<Logger> y(Logger(17)); | |
| 351 log->push_back("---"); | |
| 352 x = std::move(y); | |
| 353 log->push_back("---"); | |
| 354 } | |
| 355 EXPECT_EQ( | |
| 356 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 357 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---", | |
| 358 "1:17. destructor", "2:17. destructor"), | |
| 359 *log); | |
| 360 } | |
| 361 | |
| 362 TEST(OptionalTest, TestMoveAssignToFullFromFull) { | |
| 363 auto log = Logger::Setup(); | |
| 364 { | |
| 365 Optional<Logger> x(Logger(17)); | |
| 366 Optional<Logger> y(Logger(42)); | |
| 367 log->push_back("---"); | |
| 368 x = std::move(y); | |
| 369 log->push_back("---"); | |
| 370 } | |
| 371 EXPECT_EQ( | |
| 372 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 373 "0:17. destructor", "2:42. explicit constructor", | |
| 374 "3:42. move constructor (from 2:42)", "2:42. destructor", "---", | |
| 375 "1:42. operator= move (from 3:42)", "---", "3:42. destructor", | |
| 376 "1:42. destructor"), | |
| 377 *log); | |
| 378 } | |
| 379 | |
| 380 TEST(OptionalTest, TestMoveAssignToEmptyFromT) { | |
| 381 auto log = Logger::Setup(); | |
| 382 { | |
| 383 Optional<Logger> x; | |
| 384 Logger y(17); | |
| 385 log->push_back("---"); | |
| 386 x = Optional<Logger>(std::move(y)); | |
| 387 log->push_back("---"); | |
| 388 } | |
| 389 EXPECT_EQ(V("0:17. explicit constructor", "---", | |
| 390 "1:17. move constructor (from 0:17)", | |
| 391 "2:17. move constructor (from 1:17)", "1:17. destructor", "---", | |
| 392 "0:17. destructor", "2:17. destructor"), | |
| 393 *log); | |
| 394 } | |
| 395 | |
| 396 TEST(OptionalTest, TestMoveAssignToFullFromT) { | |
| 397 auto log = Logger::Setup(); | |
| 398 { | |
| 399 Optional<Logger> x(Logger(17)); | |
| 400 Logger y(42); | |
| 401 log->push_back("---"); | |
| 402 x = Optional<Logger>(std::move(y)); | |
| 403 log->push_back("---"); | |
| 404 } | |
| 405 EXPECT_EQ( | |
| 406 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 407 "0:17. destructor", "2:42. explicit constructor", "---", | |
| 408 "3:42. move constructor (from 2:42)", | |
| 409 "1:42. operator= move (from 3:42)", "3:42. destructor", "---", | |
| 410 "2:42. destructor", "1:42. destructor"), | |
| 411 *log); | |
| 412 } | |
| 413 | |
| 414 TEST(OptionalTest, TestResetEmpty) { | |
| 415 auto log = Logger::Setup(); | |
| 416 { | |
| 417 Optional<Logger> x; | |
| 418 x.reset(); | |
| 419 } | |
| 420 EXPECT_EQ(V(), *log); | |
| 421 } | |
| 422 | |
| 423 TEST(OptionalTest, TestResetFull) { | |
| 424 auto log = Logger::Setup(); | |
| 425 { | |
| 426 Optional<Logger> x(Logger(17)); | |
| 427 log->push_back("---"); | |
| 428 x.reset(); | |
| 429 log->push_back("---"); | |
| 430 } | |
| 431 EXPECT_EQ( | |
| 432 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
| 433 "0:17. destructor", "---", "1:17. destructor", "---"), | |
| 434 *log); | |
| 435 } | |
| 436 | |
| 437 TEST(OptionalTest, TestEmplaceEmptyWithExplicit) { | |
| 438 auto log = Logger::Setup(); | |
| 439 { | |
| 440 Optional<Logger> x; | |
| 441 log->push_back("---"); | |
| 442 x.emplace(42); | |
| 443 log->push_back("---"); | |
| 444 } | |
| 445 // clang-format off | |
| 446 EXPECT_EQ(V("---", | |
| 447 "0:42. explicit constructor", | |
| 448 "---", | |
| 449 "0:42. destructor"), | |
| 450 *log); | |
| 451 // clang-format on | |
| 452 } | |
| 453 | |
| 454 TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) { | |
| 455 auto log = Logger::Setup(); | |
| 456 { | |
| 457 Optional<Logger> x; | |
| 458 Logger ref(21); | |
| 459 Logger value(35); | |
| 460 log->push_back("---"); | |
| 461 x.emplace(42, ref, std::move(value)); | |
| 462 log->push_back("---"); | |
| 463 } | |
| 464 // clang-format off | |
| 465 EXPECT_EQ(V("0:21. explicit constructor", | |
| 466 "1:35. explicit constructor", | |
| 467 "---", | |
| 468 "2:35. move constructor (from 1:35)", | |
| 469 "3:42. multi parameter constructor", | |
| 470 "2:35. destructor", | |
| 471 "---", | |
| 472 "1:35. destructor", | |
| 473 "0:21. destructor", | |
| 474 "3:42. destructor"), | |
| 475 *log); | |
| 476 // clang-format on | |
| 477 } | |
| 478 | |
| 479 TEST(OptionalTest, TestEmplaceEmptyWithCopy) { | |
| 480 auto log = Logger::Setup(); | |
| 481 { | |
| 482 Optional<Logger> x; | |
| 483 Logger y(42); | |
| 484 log->push_back("---"); | |
| 485 x.emplace(y); | |
| 486 log->push_back("---"); | |
| 487 } | |
| 488 // clang-format off | |
| 489 EXPECT_EQ(V("0:42. explicit constructor", | |
| 490 "---", | |
| 491 "1:42. copy constructor (from 0:42)", | |
| 492 "---", | |
| 493 "0:42. destructor", | |
| 494 "1:42. destructor"), | |
| 495 *log); | |
| 496 // clang-format on | |
| 497 } | |
| 498 | |
| 499 TEST(OptionalTest, TestEmplaceEmptyWithMove) { | |
| 500 auto log = Logger::Setup(); | |
| 501 { | |
| 502 Optional<Logger> x; | |
| 503 Logger y(42); | |
| 504 log->push_back("---"); | |
| 505 x.emplace(std::move(y)); | |
| 506 log->push_back("---"); | |
| 507 } | |
| 508 // clang-format off | |
| 509 EXPECT_EQ(V("0:42. explicit constructor", | |
| 510 "---", | |
| 511 "1:42. move constructor (from 0:42)", | |
| 512 "---", | |
| 513 "0:42. destructor", | |
| 514 "1:42. destructor"), | |
| 515 *log); | |
| 516 // clang-format on | |
| 517 } | |
| 518 | |
| 519 TEST(OptionalTest, TestEmplaceFullWithExplicit) { | |
| 520 auto log = Logger::Setup(); | |
| 521 { | |
| 522 Optional<Logger> x(Logger(17)); | |
| 523 log->push_back("---"); | |
| 524 x.emplace(42); | |
| 525 log->push_back("---"); | |
| 526 } | |
| 527 // clang-format off | |
| 528 EXPECT_EQ( | |
| 529 V("0:17. explicit constructor", | |
| 530 "1:17. move constructor (from 0:17)", | |
| 531 "0:17. destructor", | |
| 532 "---", | |
| 533 "1:17. destructor", | |
| 534 "2:42. explicit constructor", | |
| 535 "---", | |
| 536 "2:42. destructor"), | |
| 537 *log); | |
| 538 // clang-format on | |
| 539 } | |
| 540 | |
| 541 TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) { | |
| 542 auto log = Logger::Setup(); | |
| 543 { | |
| 544 Optional<Logger> x(Logger(17)); | |
| 545 Logger ref(21); | |
| 546 Logger value(35); | |
| 547 log->push_back("---"); | |
| 548 x.emplace(42, ref, std::move(value)); | |
| 549 log->push_back("---"); | |
| 550 } | |
| 551 // clang-format off | |
| 552 EXPECT_EQ(V("0:17. explicit constructor", | |
| 553 "1:17. move constructor (from 0:17)", | |
| 554 "0:17. destructor", | |
| 555 "2:21. explicit constructor", | |
| 556 "3:35. explicit constructor", | |
| 557 "---", | |
| 558 "1:17. destructor", | |
| 559 "4:35. move constructor (from 3:35)", | |
| 560 "5:42. multi parameter constructor", | |
| 561 "4:35. destructor", | |
| 562 "---", | |
| 563 "3:35. destructor", | |
| 564 "2:21. destructor", | |
| 565 "5:42. destructor"), | |
| 566 *log); | |
| 567 // clang-format on | |
| 568 } | |
| 569 | |
| 570 TEST(OptionalTest, TestEmplaceFullWithCopy) { | |
| 571 auto log = Logger::Setup(); | |
| 572 { | |
| 573 Optional<Logger> x(Logger(17)); | |
| 574 Logger y(42); | |
| 575 log->push_back("---"); | |
| 576 x.emplace(y); | |
| 577 log->push_back("---"); | |
| 578 } | |
| 579 // clang-format off | |
| 580 EXPECT_EQ(V("0:17. explicit constructor", | |
| 581 "1:17. move constructor (from 0:17)", | |
| 582 "0:17. destructor", | |
| 583 "2:42. explicit constructor", | |
| 584 "---", | |
| 585 "1:17. destructor", | |
| 586 "3:42. copy constructor (from 2:42)", | |
| 587 "---", | |
| 588 "2:42. destructor", | |
| 589 "3:42. destructor"), | |
| 590 *log); | |
| 591 // clang-format on | |
| 592 } | |
| 593 | |
| 594 TEST(OptionalTest, TestEmplaceFullWithMove) { | |
| 595 auto log = Logger::Setup(); | |
| 596 { | |
| 597 Optional<Logger> x(Logger(17)); | |
| 598 Logger y(42); | |
| 599 log->push_back("---"); | |
| 600 x.emplace(std::move(y)); | |
| 601 log->push_back("---"); | |
| 602 } | |
| 603 // clang-format off | |
| 604 EXPECT_EQ(V("0:17. explicit constructor", | |
| 605 "1:17. move constructor (from 0:17)", | |
| 606 "0:17. destructor", | |
| 607 "2:42. explicit constructor", | |
| 608 "---", | |
| 609 "1:17. destructor", | |
| 610 "3:42. move constructor (from 2:42)", | |
| 611 "---", | |
| 612 "2:42. destructor", | |
| 613 "3:42. destructor"), | |
| 614 *log); | |
| 615 // clang-format on | |
| 616 } | |
| 617 | |
| 618 TEST(OptionalTest, TestDereference) { | |
| 619 auto log = Logger::Setup(); | |
| 620 { | |
| 621 Optional<Logger> x(Logger(42)); | |
| 622 const auto& y = x; | |
| 623 log->push_back("---"); | |
| 624 x->Foo(); | |
| 625 y->Foo(); | |
| 626 std::move(x)->Foo(); | |
| 627 std::move(y)->Foo(); | |
| 628 log->push_back("---"); | |
| 629 (*x).Foo(); | |
| 630 (*y).Foo(); | |
| 631 (*std::move(x)).Foo(); | |
| 632 (*std::move(y)).Foo(); | |
| 633 log->push_back("---"); | |
| 634 x.value().Foo(); | |
| 635 y.value().Foo(); | |
| 636 std::move(x).value().Foo(); | |
| 637 std::move(y).value().Foo(); | |
| 638 log->push_back("---"); | |
| 639 } | |
| 640 // clang-format off | |
| 641 EXPECT_EQ(V("0:42. explicit constructor", | |
| 642 "1:42. move constructor (from 0:42)", | |
| 643 "0:42. destructor", | |
| 644 "---", | |
| 645 "1:42. Foo()", | |
| 646 "1:42. Foo() const", | |
| 647 "1:42. Foo()", | |
| 648 "1:42. Foo() const", | |
| 649 "---", | |
| 650 "1:42. Foo()", | |
| 651 "1:42. Foo() const", | |
| 652 "1:42. Foo()", | |
| 653 "1:42. Foo() const", | |
| 654 "---", | |
| 655 "1:42. Foo()", | |
| 656 "1:42. Foo() const", | |
| 657 "1:42. Foo()", | |
| 658 "1:42. Foo() const", | |
| 659 "---", | |
| 660 "1:42. destructor"), | |
| 661 *log); | |
| 662 // clang-format on | |
| 663 } | |
| 664 | |
| 665 TEST(OptionalTest, TestDereferenceWithDefault) { | |
| 666 auto log = Logger::Setup(); | |
| 667 { | |
| 668 const Logger a(17), b(42); | |
| 669 Optional<Logger> x(a); | |
| 670 Optional<Logger> y; | |
| 671 log->push_back("-1-"); | |
| 672 EXPECT_EQ(a, x.value_or(Logger(42))); | |
| 673 log->push_back("-2-"); | |
| 674 EXPECT_EQ(b, y.value_or(Logger(42))); | |
| 675 log->push_back("-3-"); | |
| 676 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b)); | |
| 677 log->push_back("-4-"); | |
| 678 EXPECT_EQ(b, Optional<Logger>().value_or(b)); | |
| 679 log->push_back("-5-"); | |
| 680 } | |
| 681 EXPECT_EQ( | |
| 682 V("0:17. explicit constructor", "1:42. explicit constructor", | |
| 683 "2:17. copy constructor (from 0:17)", "-1-", | |
| 684 "3:42. explicit constructor", "operator== 0:17, 2:17", | |
| 685 "3:42. destructor", "-2-", "4:42. explicit constructor", | |
| 686 "operator== 1:42, 4:42", "4:42. destructor", "-3-", | |
| 687 "5:17. explicit constructor", "6:17. move constructor (from 5:17)", | |
| 688 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-", | |
| 689 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor", | |
| 690 "0:17. destructor"), | |
| 691 *log); | |
| 692 } | |
| 693 | |
| 694 TEST(OptionalTest, TestEquality) { | |
| 695 auto log = Logger::Setup(); | |
| 696 { | |
| 697 Logger a(17), b(42); | |
| 698 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2; | |
| 699 log->push_back("---"); | |
| 700 EXPECT_EQ(ma1, ma1); | |
| 701 EXPECT_EQ(ma1, ma2); | |
| 702 EXPECT_NE(ma1, mb); | |
| 703 EXPECT_NE(ma1, me1); | |
| 704 EXPECT_EQ(me1, me1); | |
| 705 EXPECT_EQ(me1, me2); | |
| 706 log->push_back("---"); | |
| 707 } | |
| 708 EXPECT_EQ( | |
| 709 V("0:17. explicit constructor", "1:42. explicit constructor", | |
| 710 "2:17. copy constructor (from 0:17)", | |
| 711 "3:17. copy constructor (from 0:17)", | |
| 712 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17", | |
| 713 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---", | |
| 714 "4:42. destructor", "3:17. destructor", "2:17. destructor", | |
| 715 "1:42. destructor", "0:17. destructor"), | |
| 716 *log); | |
| 717 } | |
| 718 | |
| 719 TEST(OptionalTest, TestEqualityWithObject) { | |
| 720 auto log = Logger::Setup(); | |
| 721 { | |
| 722 Logger a(17), b(42); | |
| 723 Optional<Logger> ma(a), me; | |
| 724 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE | |
| 725 // macros because those operators are under test. | |
| 726 log->push_back("---"); | |
| 727 | |
| 728 EXPECT_TRUE(ma == a); | |
| 729 EXPECT_TRUE(a == ma); | |
| 730 EXPECT_FALSE(ma == b); | |
| 731 EXPECT_FALSE(b == ma); | |
| 732 EXPECT_FALSE(me == a); | |
| 733 EXPECT_FALSE(a == me); | |
| 734 | |
| 735 EXPECT_FALSE(ma != a); | |
| 736 EXPECT_FALSE(a != ma); | |
| 737 EXPECT_TRUE(ma != b); | |
| 738 EXPECT_TRUE(b != ma); | |
| 739 EXPECT_TRUE(me != a); | |
| 740 EXPECT_TRUE(a != me); | |
| 741 | |
| 742 log->push_back("---"); | |
| 743 } | |
| 744 // clang-format off | |
| 745 EXPECT_EQ(V("0:17. explicit constructor", | |
| 746 "1:42. explicit constructor", | |
| 747 "2:17. copy constructor (from 0:17)", | |
| 748 "---", | |
| 749 "operator== 2:17, 0:17", | |
| 750 "operator== 0:17, 2:17", | |
| 751 "operator== 2:17, 1:42", | |
| 752 "operator== 1:42, 2:17", | |
| 753 // No operator should be called when comparing to empty. | |
| 754 "operator!= 2:17, 0:17", | |
| 755 "operator!= 0:17, 2:17", | |
| 756 "operator!= 2:17, 1:42", | |
| 757 "operator!= 1:42, 2:17", | |
| 758 // No operator should be called when comparing to empty. | |
| 759 "---", | |
| 760 "2:17. destructor", | |
| 761 "1:42. destructor", | |
| 762 "0:17. destructor"), | |
| 763 *log); | |
| 764 // clang-format on | |
| 765 } | |
| 766 | |
| 767 TEST(OptionalTest, TestSwap) { | |
| 768 auto log = Logger::Setup(); | |
| 769 { | |
| 770 Logger a(17), b(42); | |
| 771 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2; | |
| 772 log->push_back("---"); | |
| 773 swap(x1, x2); // Swap full <-> full. | |
| 774 swap(y1, y2); // Swap full <-> empty. | |
| 775 swap(z1, z2); // Swap empty <-> empty. | |
| 776 log->push_back("---"); | |
| 777 } | |
| 778 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor", | |
| 779 "2:17. copy constructor (from 0:17)", | |
| 780 "3:42. copy constructor (from 1:42)", | |
| 781 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17", | |
| 782 "5:17. move constructor (from 4:17)", "4:17. destructor", "---", | |
| 783 "5:17. destructor", "3:17. destructor", "2:42. destructor", | |
| 784 "1:42. destructor", "0:17. destructor"), | |
| 785 *log); | |
| 786 } | |
| 787 | |
| 788 TEST(OptionalTest, TestMoveValue) { | |
| 789 auto log = Logger::Setup(); | |
| 790 { | |
| 791 Optional<Logger> x(Logger(42)); | |
| 792 log->push_back("---"); | |
| 793 Logger moved = x.MoveValue(); | |
| 794 log->push_back("---"); | |
| 795 } | |
| 796 EXPECT_EQ( | |
| 797 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)", | |
| 798 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---", | |
| 799 "2:42. destructor", "1:42. destructor"), | |
| 800 *log); | |
| 801 } | |
| 802 | |
| 803 TEST(OptionalTest, TestPrintTo) { | |
| 804 constexpr char kEmptyOptionalMessage[] = "<empty optional>"; | |
| 805 const Optional<MyUnprintableType> empty_unprintable; | |
| 806 const Optional<MyPrintableType> empty_printable; | |
| 807 const Optional<MyOstreamPrintableType> empty_ostream_printable; | |
| 808 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable)); | |
| 809 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable)); | |
| 810 EXPECT_EQ(kEmptyOptionalMessage, | |
| 811 ::testing::PrintToString(empty_ostream_printable)); | |
| 812 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1}))); | |
| 813 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1}))); | |
| 814 EXPECT_EQ("The value is 1", | |
| 815 ::testing::PrintToString(Optional<MyPrintableType>({1}))); | |
| 816 EXPECT_EQ("1", | |
| 817 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1}))); | |
| 818 } | |
| 819 | |
| 820 void UnusedFunctionWorkaround() { | |
| 821 // These are here to ensure we don't get warnings about ostream and PrintTo | |
| 822 // for MyPrintableType never getting called. | |
| 823 const MyPrintableType dont_warn{17}; | |
| 824 const MyOstreamPrintableType dont_warn2{18}; | |
| 825 std::stringstream sstr; | |
| 826 sstr << dont_warn; | |
| 827 PrintTo(dont_warn, &sstr); | |
| 828 sstr << dont_warn2; | |
| 829 } | |
| 830 | |
| 831 } // namespace rtc | |
| OLD | NEW |