blob: d1496203606a1c3c86c72e44e8ad15b5ac33d8b7 [file] [log] [blame]
Karl Wiberg6e587202015-10-21 12:43:56 +02001/*
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
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
Karl Wiberg6e587202015-10-21 12:43:56 +020012#include <sstream>
13#include <string>
14#include <utility>
15#include <vector>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/optional.h"
18#include "rtc_base/gunit.h"
Karl Wiberg6e587202015-10-21 12:43:56 +020019
20namespace rtc {
21
22namespace {
23
ossue5c27a52017-02-20 04:41:42 -080024struct MyUnprintableType {
25 int value;
26};
27
28struct MyPrintableType {
29 int value;
30};
31
32struct MyOstreamPrintableType {
33 int value;
34};
35
36void PrintTo(const MyPrintableType& mpt, std::ostream* os) {
37 *os << "The value is " << mpt.value;
38}
39
kwiberg84f6a3f2017-09-05 08:43:13 -070040std::ostream& operator<<(std::ostream& os, const MyPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080041 os << mpt.value;
42 return os;
43}
44
kwiberg84f6a3f2017-09-05 08:43:13 -070045std::ostream& operator<<(std::ostream& os, const MyOstreamPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080046 os << mpt.value;
47 return os;
48}
49
Karl Wiberg6e587202015-10-21 12:43:56 +020050// Class whose instances logs various method calls (constructor, destructor,
51// etc.). Each instance has a unique ID (a simple global sequence number) and
52// an origin ID. When a copy is made, the new object gets a fresh ID but copies
53// the origin ID from the original. When a new Logger is created from scratch,
54// it gets a fresh ID, and the origin ID is the same as the ID (default
55// constructor) or given as an argument (explicit constructor).
56class Logger {
57 public:
kwibergb2137952016-03-17 08:38:12 -070058 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
59 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020060 Log("explicit constructor");
61 }
danilchap9e83c972016-10-18 04:07:18 -070062 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value)
63 : id_(g_next_id++), origin_(origin) {
64 Log("multi parameter constructor");
65 }
kwibergb2137952016-03-17 08:38:12 -070066 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020067 LogFrom("copy constructor", other);
68 }
kwibergb2137952016-03-17 08:38:12 -070069 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020070 LogFrom("move constructor", other);
71 }
72 ~Logger() { Log("destructor"); }
73 Logger& operator=(const Logger& other) {
74 origin_ = other.origin_;
75 LogFrom("operator= copy", other);
76 return *this;
77 }
78 Logger& operator=(Logger&& other) {
79 origin_ = other.origin_;
80 LogFrom("operator= move", other);
81 return *this;
82 }
83 friend void swap(Logger& a, Logger& b) {
84 using std::swap;
85 swap(a.origin_, b.origin_);
86 Log2("swap", a, b);
87 }
88 friend bool operator==(const Logger& a, const Logger& b) {
89 Log2("operator==", a, b);
90 return a.origin_ == b.origin_;
91 }
92 friend bool operator!=(const Logger& a, const Logger& b) {
93 Log2("operator!=", a, b);
94 return a.origin_ != b.origin_;
95 }
96 void Foo() { Log("Foo()"); }
97 void Foo() const { Log("Foo() const"); }
jbauch555604a2016-04-26 03:13:22 -070098 static std::unique_ptr<std::vector<std::string>> Setup() {
99 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -0700100 g_log = s.get();
101 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200102 return s;
103 }
104
105 private:
106 int id_;
107 int origin_;
kwibergb2137952016-03-17 08:38:12 -0700108 static std::vector<std::string>* g_log;
109 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +0200110 void Log(const char* msg) const {
111 std::ostringstream oss;
112 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -0700113 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200114 }
115 void LogFrom(const char* msg, const Logger& other) const {
116 std::ostringstream oss;
117 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
118 << other.origin_ << ")";
kwibergb2137952016-03-17 08:38:12 -0700119 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200120 }
121 static void Log2(const char* msg, const Logger& a, const Logger& b) {
122 std::ostringstream oss;
123 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
124 << b.origin_;
kwibergb2137952016-03-17 08:38:12 -0700125 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200126 }
127};
128
kwibergb2137952016-03-17 08:38:12 -0700129std::vector<std::string>* Logger::g_log = nullptr;
130int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200131
132// Append all the other args to the vector pointed to by the first arg.
133template <typename T>
134void VectorAppend(std::vector<T>* v) {}
135template <typename T, typename... Ts>
136void VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
137 v->push_back(e);
138 VectorAppend(v, es...);
139}
140
141// Create a vector of strings. Because we're not allowed to use
142// std::initializer_list.
143template <typename... Ts>
144std::vector<std::string> V(Ts... es) {
145 std::vector<std::string> strings;
146 VectorAppend(&strings, static_cast<std::string>(es)...);
147 return strings;
148}
149
150} // namespace
151
Karl Wibergbe579832015-11-10 22:34:18 +0100152TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200153 auto log = Logger::Setup();
154 {
Karl Wibergbe579832015-11-10 22:34:18 +0100155 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200156 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700157 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200158 }
kwibergd0404802016-05-09 06:06:05 -0700159 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200160}
161
Karl Wibergbe579832015-11-10 22:34:18 +0100162TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200163 auto log = Logger::Setup();
164 {
Karl Wibergbe579832015-11-10 22:34:18 +0100165 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200166 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700167 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200168 auto y = x;
169 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700170 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200171 }
kwibergd0404802016-05-09 06:06:05 -0700172 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200173}
174
Karl Wibergbe579832015-11-10 22:34:18 +0100175TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200176 auto log = Logger::Setup();
177 {
178 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100179 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200180 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700181 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200182 log->push_back("---");
183 auto y = x;
184 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700185 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200186 log->push_back("---");
187 }
188 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
189 "---", "2:0. copy constructor (from 1:0)", "---",
190 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
191 *log);
192}
193
Karl Wibergbe579832015-11-10 22:34:18 +0100194TEST(OptionalTest, TestConstructMoveEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200195 auto log = Logger::Setup();
196 {
Karl Wibergbe579832015-11-10 22:34:18 +0100197 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200198 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700199 EXPECT_FALSE(x.has_value());
kwibergcea7c2f2016-01-07 05:52:04 -0800200 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200201 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700202 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200203 }
kwibergd0404802016-05-09 06:06:05 -0700204 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200205}
206
Karl Wibergbe579832015-11-10 22:34:18 +0100207TEST(OptionalTest, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200208 auto log = Logger::Setup();
209 {
Karl Wibergbe579832015-11-10 22:34:18 +0100210 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200211 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700212 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200213 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800214 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200215 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700216 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200217 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700218 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200219 log->push_back("---");
220 }
221 EXPECT_EQ(
222 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
223 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
224 "2:17. destructor", "1:17. destructor"),
225 *log);
226}
227
Karl Wibergbe579832015-11-10 22:34:18 +0100228TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200229 auto log = Logger::Setup();
230 {
Karl Wibergbe579832015-11-10 22:34:18 +0100231 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200232 x = y;
233 }
kwibergd0404802016-05-09 06:06:05 -0700234 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200235}
236
Karl Wibergbe579832015-11-10 22:34:18 +0100237TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200238 auto log = Logger::Setup();
239 {
Karl Wibergbe579832015-11-10 22:34:18 +0100240 Optional<Logger> x(Logger(17));
241 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200242 log->push_back("---");
243 x = y;
244 log->push_back("---");
245 }
246 EXPECT_EQ(
247 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700248 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200249 *log);
250}
251
Karl Wibergbe579832015-11-10 22:34:18 +0100252TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200253 auto log = Logger::Setup();
254 {
Karl Wibergbe579832015-11-10 22:34:18 +0100255 Optional<Logger> x;
256 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200257 log->push_back("---");
258 x = y;
259 log->push_back("---");
260 }
kwibergd0404802016-05-09 06:06:05 -0700261 EXPECT_EQ(
262 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
263 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
264 "1:17. destructor", "2:17. destructor"),
265 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200266}
267
Karl Wibergbe579832015-11-10 22:34:18 +0100268TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200269 auto log = Logger::Setup();
270 {
Karl Wibergbe579832015-11-10 22:34:18 +0100271 Optional<Logger> x(Logger(17));
272 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200273 log->push_back("---");
274 x = y;
275 log->push_back("---");
276 }
277 EXPECT_EQ(
278 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
279 "0:17. destructor", "2:42. explicit constructor",
280 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
281 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
282 "1:42. destructor"),
283 *log);
284}
285
Karl Wibergbe579832015-11-10 22:34:18 +0100286TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200287 auto log = Logger::Setup();
288 {
Karl Wibergbe579832015-11-10 22:34:18 +0100289 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200290 Logger y(17);
291 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100292 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200293 log->push_back("---");
294 }
kwibergd0404802016-05-09 06:06:05 -0700295 EXPECT_EQ(V("0:17. explicit constructor", "---",
296 "1:17. copy constructor (from 0:17)",
297 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
298 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200299 *log);
300}
301
Karl Wibergbe579832015-11-10 22:34:18 +0100302TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200303 auto log = Logger::Setup();
304 {
Karl Wibergbe579832015-11-10 22:34:18 +0100305 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200306 Logger y(42);
307 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100308 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200309 log->push_back("---");
310 }
311 EXPECT_EQ(
312 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
313 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700314 "3:42. copy constructor (from 2:42)",
315 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
316 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200317 *log);
318}
319
Karl Wibergbe579832015-11-10 22:34:18 +0100320TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200321 auto log = Logger::Setup();
322 {
Karl Wibergbe579832015-11-10 22:34:18 +0100323 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800324 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200325 }
kwibergd0404802016-05-09 06:06:05 -0700326 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200327}
328
Karl Wibergbe579832015-11-10 22:34:18 +0100329TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200330 auto log = Logger::Setup();
331 {
Karl Wibergbe579832015-11-10 22:34:18 +0100332 Optional<Logger> x(Logger(17));
333 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200334 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800335 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200336 log->push_back("---");
337 }
338 EXPECT_EQ(
339 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700340 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200341 *log);
342}
343
Karl Wibergbe579832015-11-10 22:34:18 +0100344TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200345 auto log = Logger::Setup();
346 {
Karl Wibergbe579832015-11-10 22:34:18 +0100347 Optional<Logger> x;
348 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200349 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800350 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200351 log->push_back("---");
352 }
kwibergd0404802016-05-09 06:06:05 -0700353 EXPECT_EQ(
354 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
355 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
356 "1:17. destructor", "2:17. destructor"),
357 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200358}
359
Karl Wibergbe579832015-11-10 22:34:18 +0100360TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200361 auto log = Logger::Setup();
362 {
Karl Wibergbe579832015-11-10 22:34:18 +0100363 Optional<Logger> x(Logger(17));
364 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200365 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800366 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200367 log->push_back("---");
368 }
369 EXPECT_EQ(
370 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
371 "0:17. destructor", "2:42. explicit constructor",
372 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
373 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
374 "1:42. destructor"),
375 *log);
376}
377
Karl Wibergbe579832015-11-10 22:34:18 +0100378TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200379 auto log = Logger::Setup();
380 {
Karl Wibergbe579832015-11-10 22:34:18 +0100381 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200382 Logger y(17);
383 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800384 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200385 log->push_back("---");
386 }
kwibergd0404802016-05-09 06:06:05 -0700387 EXPECT_EQ(V("0:17. explicit constructor", "---",
388 "1:17. move constructor (from 0:17)",
389 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
390 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200391 *log);
392}
393
Karl Wibergbe579832015-11-10 22:34:18 +0100394TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200395 auto log = Logger::Setup();
396 {
Karl Wibergbe579832015-11-10 22:34:18 +0100397 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200398 Logger y(42);
399 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800400 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200401 log->push_back("---");
402 }
403 EXPECT_EQ(
404 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
405 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700406 "3:42. move constructor (from 2:42)",
407 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
408 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200409 *log);
410}
411
danilchapc4fd23c2016-10-17 07:16:54 -0700412TEST(OptionalTest, TestResetEmpty) {
413 auto log = Logger::Setup();
414 {
415 Optional<Logger> x;
416 x.reset();
417 }
418 EXPECT_EQ(V(), *log);
419}
420
421TEST(OptionalTest, TestResetFull) {
422 auto log = Logger::Setup();
423 {
424 Optional<Logger> x(Logger(17));
425 log->push_back("---");
426 x.reset();
427 log->push_back("---");
428 }
429 EXPECT_EQ(
430 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
431 "0:17. destructor", "---", "1:17. destructor", "---"),
432 *log);
433}
434
danilchap9e83c972016-10-18 04:07:18 -0700435TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
436 auto log = Logger::Setup();
437 {
438 Optional<Logger> x;
439 log->push_back("---");
440 x.emplace(42);
441 log->push_back("---");
442 }
443 // clang-format off
444 EXPECT_EQ(V("---",
445 "0:42. explicit constructor",
446 "---",
447 "0:42. destructor"),
448 *log);
449 // clang-format on
450}
451
452TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
453 auto log = Logger::Setup();
454 {
455 Optional<Logger> x;
456 Logger ref(21);
457 Logger value(35);
458 log->push_back("---");
459 x.emplace(42, ref, std::move(value));
460 log->push_back("---");
461 }
462 // clang-format off
463 EXPECT_EQ(V("0:21. explicit constructor",
464 "1:35. explicit constructor",
465 "---",
466 "2:35. move constructor (from 1:35)",
467 "3:42. multi parameter constructor",
468 "2:35. destructor",
469 "---",
470 "1:35. destructor",
471 "0:21. destructor",
472 "3:42. destructor"),
473 *log);
474 // clang-format on
475}
476
477TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
478 auto log = Logger::Setup();
479 {
480 Optional<Logger> x;
481 Logger y(42);
482 log->push_back("---");
483 x.emplace(y);
484 log->push_back("---");
485 }
486 // clang-format off
487 EXPECT_EQ(V("0:42. explicit constructor",
488 "---",
489 "1:42. copy constructor (from 0:42)",
490 "---",
491 "0:42. destructor",
492 "1:42. destructor"),
493 *log);
494 // clang-format on
495}
496
497TEST(OptionalTest, TestEmplaceEmptyWithMove) {
498 auto log = Logger::Setup();
499 {
500 Optional<Logger> x;
501 Logger y(42);
502 log->push_back("---");
503 x.emplace(std::move(y));
504 log->push_back("---");
505 }
506 // clang-format off
507 EXPECT_EQ(V("0:42. explicit constructor",
508 "---",
509 "1:42. move constructor (from 0:42)",
510 "---",
511 "0:42. destructor",
512 "1:42. destructor"),
513 *log);
514 // clang-format on
515}
516
517TEST(OptionalTest, TestEmplaceFullWithExplicit) {
518 auto log = Logger::Setup();
519 {
520 Optional<Logger> x(Logger(17));
521 log->push_back("---");
522 x.emplace(42);
523 log->push_back("---");
524 }
525 // clang-format off
526 EXPECT_EQ(
527 V("0:17. explicit constructor",
528 "1:17. move constructor (from 0:17)",
529 "0:17. destructor",
530 "---",
531 "1:17. destructor",
532 "2:42. explicit constructor",
533 "---",
534 "2:42. destructor"),
535 *log);
536 // clang-format on
537}
538
539TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
540 auto log = Logger::Setup();
541 {
542 Optional<Logger> x(Logger(17));
543 Logger ref(21);
544 Logger value(35);
545 log->push_back("---");
546 x.emplace(42, ref, std::move(value));
547 log->push_back("---");
548 }
549 // clang-format off
550 EXPECT_EQ(V("0:17. explicit constructor",
551 "1:17. move constructor (from 0:17)",
552 "0:17. destructor",
553 "2:21. explicit constructor",
554 "3:35. explicit constructor",
555 "---",
556 "1:17. destructor",
557 "4:35. move constructor (from 3:35)",
558 "5:42. multi parameter constructor",
559 "4:35. destructor",
560 "---",
561 "3:35. destructor",
562 "2:21. destructor",
563 "5:42. destructor"),
564 *log);
565 // clang-format on
566}
567
568TEST(OptionalTest, TestEmplaceFullWithCopy) {
569 auto log = Logger::Setup();
570 {
571 Optional<Logger> x(Logger(17));
572 Logger y(42);
573 log->push_back("---");
574 x.emplace(y);
575 log->push_back("---");
576 }
577 // clang-format off
578 EXPECT_EQ(V("0:17. explicit constructor",
579 "1:17. move constructor (from 0:17)",
580 "0:17. destructor",
581 "2:42. explicit constructor",
582 "---",
583 "1:17. destructor",
584 "3:42. copy constructor (from 2:42)",
585 "---",
586 "2:42. destructor",
587 "3:42. destructor"),
588 *log);
589 // clang-format on
590}
591
592TEST(OptionalTest, TestEmplaceFullWithMove) {
593 auto log = Logger::Setup();
594 {
595 Optional<Logger> x(Logger(17));
596 Logger y(42);
597 log->push_back("---");
598 x.emplace(std::move(y));
599 log->push_back("---");
600 }
601 // clang-format off
602 EXPECT_EQ(V("0:17. explicit constructor",
603 "1:17. move constructor (from 0:17)",
604 "0:17. destructor",
605 "2:42. explicit constructor",
606 "---",
607 "1:17. destructor",
608 "3:42. move constructor (from 2:42)",
609 "---",
610 "2:42. destructor",
611 "3:42. destructor"),
612 *log);
613 // clang-format on
614}
615
Karl Wibergbe579832015-11-10 22:34:18 +0100616TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200617 auto log = Logger::Setup();
618 {
Karl Wibergbe579832015-11-10 22:34:18 +0100619 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200620 const auto& y = x;
621 log->push_back("---");
622 x->Foo();
623 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800624 std::move(x)->Foo();
625 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200626 log->push_back("---");
627 (*x).Foo();
628 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800629 (*std::move(x)).Foo();
630 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200631 log->push_back("---");
tereliusf79dbad2017-06-16 06:48:13 -0700632 x.value().Foo();
633 y.value().Foo();
634 std::move(x).value().Foo();
635 std::move(y).value().Foo();
636 log->push_back("---");
Karl Wiberg6e587202015-10-21 12:43:56 +0200637 }
tereliusf79dbad2017-06-16 06:48:13 -0700638 // clang-format off
Karl Wiberg6e587202015-10-21 12:43:56 +0200639 EXPECT_EQ(V("0:42. explicit constructor",
tereliusf79dbad2017-06-16 06:48:13 -0700640 "1:42. move constructor (from 0:42)",
641 "0:42. destructor",
642 "---",
643 "1:42. Foo()",
644 "1:42. Foo() const",
645 "1:42. Foo()",
646 "1:42. Foo() const",
647 "---",
648 "1:42. Foo()",
649 "1:42. Foo() const",
650 "1:42. Foo()",
651 "1:42. Foo() const",
652 "---",
653 "1:42. Foo()",
654 "1:42. Foo() const",
655 "1:42. Foo()",
656 "1:42. Foo() const",
657 "---",
658 "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200659 *log);
tereliusf79dbad2017-06-16 06:48:13 -0700660 // clang-format on
Karl Wiberg6e587202015-10-21 12:43:56 +0200661}
662
Karl Wibergbe579832015-11-10 22:34:18 +0100663TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200664 auto log = Logger::Setup();
665 {
666 const Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100667 Optional<Logger> x(a);
668 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200669 log->push_back("-1-");
670 EXPECT_EQ(a, x.value_or(Logger(42)));
671 log->push_back("-2-");
672 EXPECT_EQ(b, y.value_or(Logger(42)));
673 log->push_back("-3-");
Karl Wibergbe579832015-11-10 22:34:18 +0100674 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200675 log->push_back("-4-");
Karl Wibergbe579832015-11-10 22:34:18 +0100676 EXPECT_EQ(b, Optional<Logger>().value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200677 log->push_back("-5-");
678 }
679 EXPECT_EQ(
680 V("0:17. explicit constructor", "1:42. explicit constructor",
kwibergd0404802016-05-09 06:06:05 -0700681 "2:17. copy constructor (from 0:17)", "-1-",
682 "3:42. explicit constructor", "operator== 0:17, 2:17",
683 "3:42. destructor", "-2-", "4:42. explicit constructor",
684 "operator== 1:42, 4:42", "4:42. destructor", "-3-",
685 "5:17. explicit constructor", "6:17. move constructor (from 5:17)",
686 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-",
687 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200688 "0:17. destructor"),
689 *log);
690}
691
Karl Wibergbe579832015-11-10 22:34:18 +0100692TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200693 auto log = Logger::Setup();
694 {
695 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100696 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200697 log->push_back("---");
698 EXPECT_EQ(ma1, ma1);
699 EXPECT_EQ(ma1, ma2);
700 EXPECT_NE(ma1, mb);
701 EXPECT_NE(ma1, me1);
702 EXPECT_EQ(me1, me1);
703 EXPECT_EQ(me1, me2);
704 log->push_back("---");
705 }
kwibergd0404802016-05-09 06:06:05 -0700706 EXPECT_EQ(
707 V("0:17. explicit constructor", "1:42. explicit constructor",
708 "2:17. copy constructor (from 0:17)",
709 "3:17. copy constructor (from 0:17)",
710 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
711 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
712 "4:42. destructor", "3:17. destructor", "2:17. destructor",
713 "1:42. destructor", "0:17. destructor"),
714 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200715}
716
danilchape0370602016-10-20 00:58:15 -0700717TEST(OptionalTest, TestEqualityWithObject) {
718 auto log = Logger::Setup();
719 {
720 Logger a(17), b(42);
721 Optional<Logger> ma(a), me;
722 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE
723 // macros because those operators are under test.
724 log->push_back("---");
725
726 EXPECT_TRUE(ma == a);
727 EXPECT_TRUE(a == ma);
728 EXPECT_FALSE(ma == b);
729 EXPECT_FALSE(b == ma);
730 EXPECT_FALSE(me == a);
731 EXPECT_FALSE(a == me);
732
733 EXPECT_FALSE(ma != a);
734 EXPECT_FALSE(a != ma);
735 EXPECT_TRUE(ma != b);
736 EXPECT_TRUE(b != ma);
737 EXPECT_TRUE(me != a);
738 EXPECT_TRUE(a != me);
739
740 log->push_back("---");
741 }
742 // clang-format off
743 EXPECT_EQ(V("0:17. explicit constructor",
744 "1:42. explicit constructor",
745 "2:17. copy constructor (from 0:17)",
746 "---",
747 "operator== 2:17, 0:17",
748 "operator== 0:17, 2:17",
749 "operator== 2:17, 1:42",
750 "operator== 1:42, 2:17",
751 // No operator should be called when comparing to empty.
752 "operator!= 2:17, 0:17",
753 "operator!= 0:17, 2:17",
754 "operator!= 2:17, 1:42",
755 "operator!= 1:42, 2:17",
756 // No operator should be called when comparing to empty.
757 "---",
758 "2:17. destructor",
759 "1:42. destructor",
760 "0:17. destructor"),
761 *log);
762 // clang-format on
763}
764
Karl Wibergbe579832015-11-10 22:34:18 +0100765TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200766 auto log = Logger::Setup();
767 {
768 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100769 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200770 log->push_back("---");
771 swap(x1, x2); // Swap full <-> full.
772 swap(y1, y2); // Swap full <-> empty.
773 swap(z1, z2); // Swap empty <-> empty.
774 log->push_back("---");
775 }
776 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
777 "2:17. copy constructor (from 0:17)",
778 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700779 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
780 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
781 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200782 "1:42. destructor", "0:17. destructor"),
783 *log);
784}
785
deadbeef81baed32017-02-10 18:11:11 -0800786TEST(OptionalTest, TestMoveValue) {
787 auto log = Logger::Setup();
788 {
789 Optional<Logger> x(Logger(42));
790 log->push_back("---");
791 Logger moved = x.MoveValue();
792 log->push_back("---");
793 }
794 EXPECT_EQ(
795 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)",
796 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---",
797 "2:42. destructor", "1:42. destructor"),
798 *log);
799}
800
ossue5c27a52017-02-20 04:41:42 -0800801TEST(OptionalTest, TestPrintTo) {
802 constexpr char kEmptyOptionalMessage[] = "<empty optional>";
803 const Optional<MyUnprintableType> empty_unprintable;
804 const Optional<MyPrintableType> empty_printable;
805 const Optional<MyOstreamPrintableType> empty_ostream_printable;
806 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable));
807 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable));
808 EXPECT_EQ(kEmptyOptionalMessage,
809 ::testing::PrintToString(empty_ostream_printable));
810 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1})));
811 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1})));
812 EXPECT_EQ("The value is 1",
813 ::testing::PrintToString(Optional<MyPrintableType>({1})));
814 EXPECT_EQ("1",
815 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1})));
816}
817
818void UnusedFunctionWorkaround() {
819 // These are here to ensure we don't get warnings about ostream and PrintTo
820 // for MyPrintableType never getting called.
821 const MyPrintableType dont_warn{17};
822 const MyOstreamPrintableType dont_warn2{18};
823 std::stringstream sstr;
824 sstr << dont_warn;
825 PrintTo(dont_warn, &sstr);
826 sstr << dont_warn2;
827}
828
Karl Wiberg6e587202015-10-21 12:43:56 +0200829} // namespace rtc