16e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg/*
26e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
36e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *
46e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  Use of this source code is governed by a BSD-style license
56e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  that can be found in the LICENSE file in the root of the source
66e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  tree. An additional intellectual property rights grant can be found
76e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  in the file PATENTS.  All contributing project authors may
86e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg *  be found in the AUTHORS file in the root of the source tree.
96e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg */
106e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
116e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg#include <sstream>
126e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg#include <string>
136e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg#include <utility>
146e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg#include <vector>
156e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
166e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg#include "webrtc/base/gunit.h"
17be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg#include "webrtc/base/optional.h"
186e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
196e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergnamespace rtc {
206e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
216e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergnamespace {
226e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
236e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// Class whose instances logs various method calls (constructor, destructor,
246e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// etc.). Each instance has a unique ID (a simple global sequence number) and
256e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// an origin ID. When a copy is made, the new object gets a fresh ID but copies
266e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// the origin ID from the original. When a new Logger is created from scratch,
276e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// it gets a fresh ID, and the origin ID is the same as the ID (default
286e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// constructor) or given as an argument (explicit constructor).
296e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergclass Logger {
306e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg public:
316e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  Logger() : id_(next_id_++), origin_(id_) { Log("default constructor"); }
326e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  explicit Logger(int origin) : id_(next_id_++), origin_(origin) {
336e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Log("explicit constructor");
346e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
356e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  Logger(const Logger& other) : id_(next_id_++), origin_(other.origin_) {
366e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    LogFrom("copy constructor", other);
376e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
386e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  Logger(Logger&& other) : id_(next_id_++), origin_(other.origin_) {
396e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    LogFrom("move constructor", other);
406e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
416e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  ~Logger() { Log("destructor"); }
426e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  Logger& operator=(const Logger& other) {
436e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    origin_ = other.origin_;
446e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    LogFrom("operator= copy", other);
456e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    return *this;
466e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
476e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  Logger& operator=(Logger&& other) {
486e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    origin_ = other.origin_;
496e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    LogFrom("operator= move", other);
506e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    return *this;
516e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
526e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  friend void swap(Logger& a, Logger& b) {
536e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    using std::swap;
546e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    swap(a.origin_, b.origin_);
556e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Log2("swap", a, b);
566e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
576e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  friend bool operator==(const Logger& a, const Logger& b) {
586e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Log2("operator==", a, b);
596e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    return a.origin_ == b.origin_;
606e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
616e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  friend bool operator!=(const Logger& a, const Logger& b) {
626e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Log2("operator!=", a, b);
636e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    return a.origin_ != b.origin_;
646e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
656e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  void Foo() { Log("Foo()"); }
666e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  void Foo() const { Log("Foo() const"); }
676e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  static rtc::scoped_ptr<std::vector<std::string>> Setup() {
686e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    auto s = rtc_make_scoped_ptr(new std::vector<std::string>);
696e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger::log_ = s.get();
706e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger::next_id_ = 0;
716e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    return s;
726e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
736e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
746e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg private:
756e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  int id_;
766e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  int origin_;
776e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  static std::vector<std::string>* log_;
786e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  static int next_id_;
796e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  void Log(const char* msg) const {
806e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    std::ostringstream oss;
816e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    oss << id_ << ':' << origin_ << ". " << msg;
826e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log_->push_back(oss.str());
836e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
846e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  void LogFrom(const char* msg, const Logger& other) const {
856e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    std::ostringstream oss;
866e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
876e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        << other.origin_ << ")";
886e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log_->push_back(oss.str());
896e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
906e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  static void Log2(const char* msg, const Logger& a, const Logger& b) {
916e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    std::ostringstream oss;
926e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
936e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        << b.origin_;
946e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log_->push_back(oss.str());
956e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
966e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg};
976e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
986e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergstd::vector<std::string>* Logger::log_ = nullptr;
996e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergint Logger::next_id_ = 0;
1006e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
1016e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// Append all the other args to the vector pointed to by the first arg.
1026e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergtemplate <typename T>
1036e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergvoid VectorAppend(std::vector<T>* v) {}
1046e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergtemplate <typename T, typename... Ts>
1056e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergvoid VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
1066e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  v->push_back(e);
1076e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  VectorAppend(v, es...);
1086e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1096e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
1106e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// Create a vector of strings. Because we're not allowed to use
1116e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg// std::initializer_list.
1126e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergtemplate <typename... Ts>
1136e587200db7ddae0d33e5187b73acdd41175584cKarl Wibergstd::vector<std::string> V(Ts... es) {
1146e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  std::vector<std::string> strings;
1156e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  VectorAppend(&strings, static_cast<std::string>(es)...);
1166e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  return strings;
1176e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1186e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
1196e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}  // namespace
1206e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
121be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestConstructDefault) {
1226e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1236e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
124be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
1256e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_FALSE(x);
1266e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1276e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "0:0. destructor"), *log);
1286e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1296e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
130be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestConstructCopyEmpty) {
1316e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1326e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
133be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
1346e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_FALSE(x);
1356e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    auto y = x;
1366e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_FALSE(y);
1376e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1386e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
1396e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:0. destructor", "0:0. destructor"),
1406e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
1416e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1426e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
143be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestConstructCopyFull) {
1446e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1456e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
1466e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger a;
147be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(a);
1486e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_TRUE(x);
1496e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
1506e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    auto y = x;
1516e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_TRUE(y);
1526e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
1536e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1546e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
1556e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "---", "2:0. copy constructor (from 1:0)", "---",
1566e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "2:0. destructor", "1:0. destructor", "0:0. destructor"),
1576e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
1586e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1596e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
160be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestConstructMoveEmpty) {
1616e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1626e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
163be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
1646e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_FALSE(x);
165cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    auto y = std::move(x);
1666e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_FALSE(y);
1676e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1686e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:0. move constructor (from 0:0)",
1696e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:0. destructor", "0:0. destructor"),
1706e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
1716e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1726e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
173be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestConstructMoveFull) {
1746e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1756e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
176be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
1776e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_TRUE(x);
1786e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
179cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    auto y = std::move(x);
1806e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_TRUE(x);
1816e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_TRUE(y);
1826e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
1836e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1846e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
1856e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
1866e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
1876e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "2:17. destructor", "1:17. destructor"),
1886e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
1896e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
1906e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
191be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
1926e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
1936e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
194be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x, y;
1956e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    x = y;
1966e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
1976e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
1986e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:0. default constructor", "1:1. default constructor",
1996e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:1. operator= copy (from 1:1)", "1:1. destructor", "0:1. destructor"),
2006e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
2016e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2026e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
203be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
2046e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2056e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
206be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
207be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y;
2086e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2096e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    x = y;
2106e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2116e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2126e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
2136e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
2146e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:2. default constructor", "---",
2156e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:2. operator= copy (from 2:2)", "---", "2:2. destructor",
2166e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:2. destructor"),
2176e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
2186e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2196e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
220be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
2216e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2226e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
223be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
224be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y(Logger(17));
2256e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2266e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    x = y;
2276e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2286e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2296e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:17. explicit constructor",
2306e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
2316e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "0:17. operator= copy (from 2:17)", "---", "2:17. destructor",
2326e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "0:17. destructor"),
2336e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
2346e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2356e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
236be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToFullFromFull) {
2376e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2386e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
239be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
240be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y(Logger(42));
2416e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2426e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    x = y;
2436e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2446e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2456e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
2466e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
2476e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:42. explicit constructor",
2486e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
2496e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
2506e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:42. destructor"),
2516e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
2526e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2536e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
254be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToEmptyFromT) {
2556e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2566e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
257be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
2586e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger y(17);
2596e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
260be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    x = Optional<Logger>(y);
2616e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2626e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2636e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:17. explicit constructor", "---",
264102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "2:17. copy constructor (from 1:17)",
265102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "0:17. operator= move (from 2:17)", "2:17. destructor", "---",
266102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "1:17. destructor", "0:17. destructor"),
2676e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
2686e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2696e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
270be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestCopyAssignToFullFromT) {
2716e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2726e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
273be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
2746e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger y(42);
2756e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
276be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    x = Optional<Logger>(y);
2776e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
2786e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2796e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
2806e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
2816e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:42. explicit constructor", "---",
282102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "3:42. copy constructor (from 2:42)",
283102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
284102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "2:42. destructor", "1:42. destructor"),
2856e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
2866e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2876e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
288be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
2896e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
2906e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
291be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x, y;
292cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = std::move(y);
2936e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
2946e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
2956e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:0. default constructor", "1:1. default constructor",
2966e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:1. operator= move (from 1:1)", "1:1. destructor", "0:1. destructor"),
2976e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
2986e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
2996e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
300be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
3016e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3026e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
303be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
304be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y;
3056e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
306cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = std::move(y);
3076e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3086e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
3096e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
3106e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
3116e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:2. default constructor", "---",
3126e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:2. operator= move (from 2:2)", "---", "2:2. destructor",
3136e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:2. destructor"),
3146e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
3156e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
3166e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
317be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
3186e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3196e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
320be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
321be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y(Logger(17));
3226e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
323cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = std::move(y);
3246e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3256e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
3266e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:17. explicit constructor",
3276e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
3286e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "0:17. operator= move (from 2:17)", "---", "2:17. destructor",
3296e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "0:17. destructor"),
3306e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
3316e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
3326e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
333be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToFullFromFull) {
3346e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3356e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
336be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
337be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y(Logger(42));
3386e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
339cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = std::move(y);
3406e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3416e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
3426e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
3436e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
3446e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:42. explicit constructor",
3456e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
3466e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
3476e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "1:42. destructor"),
3486e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
3496e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
3506e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
351be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToEmptyFromT) {
3526e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3536e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
354be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x;
3556e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger y(17);
3566e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
357cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = Optional<Logger>(std::move(y));
3586e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3596e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
3606e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:0. default constructor", "1:17. explicit constructor", "---",
361102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "2:17. move constructor (from 1:17)",
362102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "0:17. operator= move (from 2:17)", "2:17. destructor", "---",
363102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg              "1:17. destructor", "0:17. destructor"),
3646e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
3656e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
3666e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
367be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestMoveAssignToFullFromT) {
3686e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3696e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
370be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(17));
3716e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger y(42);
3726e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
373cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    x = Optional<Logger>(std::move(y));
3746e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3756e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
3766e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
3776e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
3786e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor", "2:42. explicit constructor", "---",
379102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "3:42. move constructor (from 2:42)",
380102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
381102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg        "2:42. destructor", "1:42. destructor"),
3826e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
3836e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
3846e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
385be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestDereference) {
3866e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
3876e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
388be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(Logger(42));
3896e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    const auto& y = x;
3906e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3916e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    x->Foo();
3926e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    y->Foo();
393cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    std::move(x)->Foo();
394cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    std::move(y)->Foo();
3956e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
3966e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    (*x).Foo();
3976e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    (*y).Foo();
398cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    (*std::move(x)).Foo();
399cea7c2f7839eef81ecbd6dd10d103190ef68875ckwiberg    (*std::move(y)).Foo();
4006e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
4016e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
4026e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:42. explicit constructor",
4036e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:42. move constructor (from 0:42)", "0:42. destructor", "---",
4046e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:42. Foo()", "1:42. Foo() const", "1:42. Foo()",
4056e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:42. Foo() const", "---", "1:42. Foo()", "1:42. Foo() const",
4066e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:42. Foo()", "1:42. Foo() const", "---", "1:42. destructor"),
4076e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
4086e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
4096e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
410be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestDereferenceWithDefault) {
4116e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
4126e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
4136e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    const Logger a(17), b(42);
414be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x(a);
415be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> y;
4166e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("-1-");
4176e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(a, x.value_or(Logger(42)));
4186e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("-2-");
4196e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(b, y.value_or(Logger(42)));
4206e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("-3-");
421be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
4226e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("-4-");
423be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    EXPECT_EQ(b, Optional<Logger>().value_or(b));
4246e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("-5-");
4256e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
4266e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(
4276e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      V("0:17. explicit constructor", "1:42. explicit constructor",
4286e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "2:17. copy constructor (from 0:17)", "3:3. default constructor", "-1-",
4296e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "4:42. explicit constructor", "operator== 0:17, 2:17",
4306e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "4:42. destructor", "-2-", "5:42. explicit constructor",
4316e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "operator== 1:42, 5:42", "5:42. destructor", "-3-",
4326e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "6:17. explicit constructor", "7:17. move constructor (from 6:17)",
4336e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "operator== 0:17, 7:17", "7:17. destructor", "6:17. destructor", "-4-",
4346e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "8:8. default constructor", "operator== 1:42, 1:42", "8:8. destructor",
4356e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "-5-", "3:3. destructor", "2:17. destructor", "1:42. destructor",
4366e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg        "0:17. destructor"),
4376e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg      *log);
4386e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
4396e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
440be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestEquality) {
4416e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
4426e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
4436e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger a(17), b(42);
444be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
4456e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
4466e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(ma1, ma1);
4476e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(ma1, ma2);
4486e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_NE(ma1, mb);
4496e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_NE(ma1, me1);
4506e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(me1, me1);
4516e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    EXPECT_EQ(me1, me2);
4526e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
4536e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
4546e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
4556e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "2:17. copy constructor (from 0:17)",
4566e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "3:17. copy constructor (from 0:17)",
4576e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "4:42. copy constructor (from 1:42)", "5:5. default constructor",
4586e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "6:6. default constructor", "---", "operator== 2:17, 2:17",
4596e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
4606e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "6:6. destructor", "5:5. destructor", "4:42. destructor",
4616e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "3:17. destructor", "2:17. destructor", "1:42. destructor",
4626e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "0:17. destructor"),
4636e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
4646e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
4656e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
466be57983f4bd875c39a229bab5112b32dad004057Karl WibergTEST(OptionalTest, TestSwap) {
4676e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  auto log = Logger::Setup();
4686e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  {
4696e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    Logger a(17), b(42);
470be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg    Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
4716e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
4726e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    swap(x1, x2);  // Swap full <-> full.
4736e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    swap(y1, y2);  // Swap full <-> empty.
4746e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    swap(z1, z2);  // Swap empty <-> empty.
4756e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg    log->push_back("---");
4766e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  }
4776e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg  EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
4786e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "2:17. copy constructor (from 0:17)",
4796e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "3:42. copy constructor (from 1:42)",
4806e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "4:17. copy constructor (from 0:17)", "5:5. default constructor",
4816e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "6:6. default constructor", "7:7. default constructor", "---",
4826e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "swap 2:42, 3:17", "swap 4:5, 5:17", "swap 6:7, 7:6", "---",
4836e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "7:6. destructor", "6:7. destructor", "5:17. destructor",
4846e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "4:5. destructor", "3:17. destructor", "2:42. destructor",
4856e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg              "1:42. destructor", "0:17. destructor"),
4866e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg            *log);
4876e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}
4886e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg
4896e587200db7ddae0d33e5187b73acdd41175584cKarl Wiberg}  // namespace rtc
490