1/*
2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include "RefLogger.h"
29
30#include <memory>
31#include <string>
32
33#include <wtf/Expected.h>
34#include <wtf/Unexpected.h>
35#include <wtf/StdLibExtras.h>
36#include <wtf/Ref.h>
37
38namespace std {
39
40template<typename T0, typename T1> std::ostream& operator<<(std::ostream& os, const std::pair<T0, T1>& p)
41{
42 return os << '(' << p.first << ", " << p.second << ')';
43}
44
45namespace experimental {
46inline namespace fundamentals_v3 {
47
48template<class E> std::ostream& operator<<(std::ostream& os, const Unexpected<E>& u)
49{
50 return os << u.value();
51}
52
53template<class T, class E> std::ostream& operator<<(std::ostream& os, const Expected<T, E>& e)
54{
55 if (e.has_value())
56 return os << e.value();
57 return os << e.error();
58}
59
60template<class E> std::ostream& operator<<(std::ostream& os, const Expected<void, E>& e)
61{
62 if (e.has_value())
63 return os << "";
64 return os << e.error();
65}
66
67}}} // namespace std::experimental::fundamentals_v3
68
69
70namespace TestWebKitAPI {
71
72constexpr const char* oops = "oops";
73constexpr const char* foof = "foof";
74
75TEST(WTF_Expected, Unexpected)
76{
77 {
78 auto u = Unexpected<int>(42);
79 EXPECT_EQ(u.value(), 42);
80 constexpr auto c = makeUnexpected(42);
81 EXPECT_EQ(c.value(), 42);
82 EXPECT_EQ(u, c);
83 EXPECT_FALSE(u != c);
84 }
85 {
86 auto c = makeUnexpected(oops);
87 EXPECT_EQ(c.value(), oops);
88 }
89 {
90 auto s = makeUnexpected(std::string(oops));
91 EXPECT_EQ(s.value(), oops);
92 }
93 {
94 constexpr auto s0 = makeUnexpected(oops);
95 constexpr auto s1(s0);
96 EXPECT_EQ(s0, s1);
97 }
98}
99
100struct foo {
101 int v;
102 foo(int v)
103 : v(v)
104 { }
105 ~foo() { }
106 bool operator==(const foo& y) const { return v == y.v; }
107 friend std::ostream& operator<<(std::ostream&, const foo&);
108};
109std::ostream& operator<<(std::ostream& os, const foo& f) { return os << f.v; }
110
111TEST(WTF_Expected, expected)
112{
113 typedef Expected<int, const char*> E;
114 typedef Expected<int, const void*> EV;
115 typedef Expected<foo, const char*> FooChar;
116 typedef Expected<foo, std::string> FooString;
117 {
118 auto e = E();
119 EXPECT_TRUE(e.has_value());
120 EXPECT_EQ(e.value(), 0);
121 EXPECT_EQ(e.value_or(3.14), 0);
122 }
123 {
124 constexpr E e;
125 EXPECT_TRUE(e.has_value());
126 EXPECT_EQ(e.value(), 0);
127 EXPECT_EQ(e.value_or(3.14), 0);
128 }
129 {
130 auto e = E(42);
131 EXPECT_TRUE(e.has_value());
132 EXPECT_EQ(e.value(), 42);
133 EXPECT_EQ(e.value_or(3.14), 42);
134 const auto e2(e);
135 EXPECT_TRUE(e2.has_value());
136 EXPECT_EQ(e2.value(), 42);
137 EXPECT_EQ(e2.value_or(3.14), 42);
138 E e3;
139 e3 = e2;
140 EXPECT_TRUE(e3.has_value());
141 EXPECT_EQ(e3.value(), 42);
142 EXPECT_EQ(e3.value_or(3.14), 42);
143 const E e4 = e2;
144 EXPECT_TRUE(e4.has_value());
145 EXPECT_EQ(e4.value(), 42);
146 EXPECT_EQ(e4.value_or(3.14), 42);
147 }
148 {
149 constexpr E c(42);
150 EXPECT_TRUE(c.has_value());
151 EXPECT_EQ(c.value(), 42);
152 EXPECT_EQ(c.value_or(3.14), 42);
153 constexpr const auto c2(c);
154 EXPECT_TRUE(c2.has_value());
155 EXPECT_EQ(c2.value(), 42);
156 EXPECT_EQ(c2.value_or(3.14), 42);
157 }
158 {
159 auto u = E(makeUnexpected(oops));
160 EXPECT_FALSE(u.has_value());
161 EXPECT_EQ(u.error(), oops);
162 EXPECT_EQ(u.value_or(3.14), 3);
163 }
164 {
165 auto uv = EV(makeUnexpected(oops));
166 EXPECT_FALSE(uv.has_value());
167 EXPECT_EQ(uv.error(), oops);
168 EXPECT_EQ(uv.value_or(3.14), 3);
169 }
170 {
171 E e = makeUnexpected(oops);
172 EXPECT_FALSE(e.has_value());
173 EXPECT_EQ(e.error(), oops);
174 EXPECT_EQ(e.value_or(3.14), 3);
175 }
176 {
177 auto e = FooChar(42);
178 EXPECT_EQ(e->v, 42);
179 EXPECT_EQ((*e).v, 42);
180 }
181 {
182 auto e0 = E(42);
183 auto e1 = E(1024);
184 swap(e0, e1);
185 EXPECT_EQ(e0.value(), 1024);
186 EXPECT_EQ(e1.value(), 42);
187 }
188 {
189 auto e0 = E(makeUnexpected(oops));
190 auto e1 = E(makeUnexpected(foof));
191 swap(e0, e1);
192 EXPECT_EQ(e0.error(), foof);
193 EXPECT_EQ(e1.error(), oops);
194 }
195 {
196 FooChar c(foo(42));
197 EXPECT_EQ(c->v, 42);
198 EXPECT_EQ((*c).v, 42);
199 }
200 {
201 FooString s(foo(42));
202 EXPECT_EQ(s->v, 42);
203 EXPECT_EQ((*s).v, 42);
204 const char* message = "very long failure string, for very bad failure cases";
205 FooString e0(makeUnexpected<std::string>(message));
206 FooString e1(makeUnexpected<std::string>(message));
207 FooString e2(makeUnexpected<std::string>(std::string()));
208 EXPECT_EQ(e0.error(), std::string(message));
209 EXPECT_EQ(e0, e1);
210 EXPECT_NE(e0, e2);
211 FooString* e4 = new FooString(makeUnexpected<std::string>(message));
212 FooString* e5 = new FooString(*e4);
213 EXPECT_EQ(e0, *e4);
214 delete e4;
215 EXPECT_EQ(e0, *e5);
216 delete e5;
217 }
218}
219
220TEST(WTF_Expected, void)
221{
222 typedef Expected<void, const char*> E;
223 typedef Expected<void, const void*> EV;
224 typedef Expected<void, std::string> String;
225 {
226 auto e = E();
227 EXPECT_TRUE(e.has_value());
228 const auto e2(e);
229 EXPECT_TRUE(e2.has_value());
230 EXPECT_EQ(e, e2);
231 E e3;
232 e3 = e2;
233 EXPECT_TRUE(e3.has_value());
234 EXPECT_EQ(e, e3);
235 }
236 {
237 constexpr E c;
238 EXPECT_TRUE(c.has_value());
239 constexpr const auto c2(c);
240 EXPECT_TRUE(c2.has_value());
241 EXPECT_EQ(c, c2);
242 }
243 {
244 auto u = E(makeUnexpected(oops));
245 EXPECT_FALSE(u.has_value());
246 EXPECT_EQ(u.error(), oops);
247 }
248 {
249 auto uv = EV(makeUnexpected(oops));
250 EXPECT_FALSE(uv.has_value());
251 EXPECT_EQ(uv.error(), oops);
252 }
253 {
254 E e = makeUnexpected(oops);
255 EXPECT_FALSE(e.has_value());
256 EXPECT_EQ(e.error(), oops);
257 }
258 {
259 auto e0 = E();
260 auto e1 = E();
261 swap(e0, e1);
262 EXPECT_EQ(e0, e1);
263 }
264 {
265 auto e0 = E(makeUnexpected(oops));
266 auto e1 = E(makeUnexpected(foof));
267 swap(e0, e1);
268 EXPECT_EQ(e0.error(), foof);
269 EXPECT_EQ(e1.error(), oops);
270 }
271 {
272 const char* message = "very long failure string, for very bad failure cases";
273 String e0(makeUnexpected<std::string>(message));
274 String e1(makeUnexpected<std::string>(message));
275 String e2(makeUnexpected<std::string>(std::string()));
276 EXPECT_EQ(e0.error(), std::string(message));
277 EXPECT_EQ(e0, e1);
278 EXPECT_NE(e0, e2);
279 String* e4 = new String(makeUnexpected<std::string>(message));
280 String* e5 = new String(*e4);
281 EXPECT_EQ(e0, *e4);
282 delete e4;
283 EXPECT_EQ(e0, *e5);
284 delete e5;
285 }
286 {
287 typedef Expected<std::pair<int, int>, std::string> Et;
288 EXPECT_EQ(Et(std::in_place, 1, 2), Et(std::in_place, 1, 2));
289 }
290}
291
292template<typename T>
293struct NonCopyable {
294 NonCopyable(NonCopyable&&) = default;
295 NonCopyable(const NonCopyable&) = delete;
296 NonCopyable& operator=(const NonCopyable&) = delete;
297 NonCopyable& operator=(NonCopyable&&) = default;
298 bool operator==(const NonCopyable<T>& other) const { return value == other.value; }
299 bool operator!=(const NonCopyable<T>& other) const { return value != other.value; }
300 T value;
301};
302
303TEST(WTF_Expected, comparison)
304{
305 typedef Expected<int, const char*> Ex;
306 typedef Expected<int, int> Er;
307
308 // Two Expected, no errors.
309 EXPECT_EQ(Ex(42), Ex(42));
310 EXPECT_NE(Ex(42), Ex(1024));
311
312 EXPECT_FALSE(Ex(42) == Ex(1024));
313 EXPECT_FALSE(Ex(42) != Ex(42));
314
315 // Two Expected, half errors.
316 EXPECT_FALSE(Ex(42) == Ex(makeUnexpected(oops)));
317 EXPECT_NE(Ex(42), Ex(makeUnexpected(oops)));
318
319 EXPECT_FALSE(Ex(makeUnexpected(oops)) == Ex(42));
320 EXPECT_NE(Ex(makeUnexpected(oops)), Ex(42));
321
322 // Two Expected, all errors.
323 EXPECT_EQ(Er(42), Er(42));
324 EXPECT_NE(Er(42), Er(1024));
325
326 EXPECT_FALSE(Er(42) == Er(1024));
327 EXPECT_FALSE(Er(42) != Er(42));
328
329 // One Expected, one value.
330 EXPECT_EQ(Ex(42), 42);
331 EXPECT_NE(Ex(42), 0);
332
333 EXPECT_FALSE(Ex(42) == 0);
334 EXPECT_FALSE(Ex(42) != 42);
335
336 EXPECT_EQ(42, Ex(42));
337 EXPECT_NE(42, Ex(1024));
338
339 EXPECT_FALSE(42 == Ex(1024));
340 EXPECT_FALSE(42 != Ex(42));
341
342 // One Expected, one unexpected.
343 EXPECT_FALSE(Ex(42) == makeUnexpected(oops));
344 EXPECT_NE(Ex(42), makeUnexpected(oops));
345
346 EXPECT_FALSE(makeUnexpected(oops) == Ex(42));
347 EXPECT_NE(makeUnexpected(oops), Ex(42));
348
349 NonCopyable<int> a { 5 };
350 NonCopyable<int> b { 6 };
351 Unexpected<NonCopyable<double>> c { makeUnexpected(NonCopyable<double> { 5.0 }) };
352 Expected<NonCopyable<int>, NonCopyable<double>> d { NonCopyable<int> { 5 } };
353 Expected<NonCopyable<int>, NonCopyable<double>> e { makeUnexpected(NonCopyable<double> { 5.0 }) };
354
355 EXPECT_TRUE(a != e);
356 EXPECT_TRUE(e != a);
357 EXPECT_FALSE(a == e);
358 EXPECT_FALSE(e == a);
359
360 EXPECT_TRUE(b != e);
361 EXPECT_TRUE(e != b);
362 EXPECT_FALSE(b == e);
363 EXPECT_FALSE(e == b);
364
365 EXPECT_TRUE(c != d);
366 EXPECT_TRUE(d != c);
367 EXPECT_FALSE(c == d);
368 EXPECT_FALSE(d == c);
369
370 EXPECT_TRUE(c == e);
371 EXPECT_TRUE(e == c);
372 EXPECT_FALSE(c != e);
373 EXPECT_FALSE(e != c);
374}
375
376struct NonTrivialDtor {
377 ~NonTrivialDtor() { ++count; }
378 static int count;
379};
380int NonTrivialDtor::count = 0;
381
382TEST(WTF_Expected, destructors)
383{
384 typedef Expected<NonTrivialDtor, const char*> NT;
385 typedef Expected<const char*, NonTrivialDtor> TN;
386 typedef Expected<NonTrivialDtor, NonTrivialDtor> NN;
387 typedef Expected<void, NonTrivialDtor> VN;
388 EXPECT_EQ(NonTrivialDtor::count, 0);
389 { NT nt; }
390 EXPECT_EQ(NonTrivialDtor::count, 1);
391 { NT nt = makeUnexpected(oops); }
392 EXPECT_EQ(NonTrivialDtor::count, 1);
393 { TN tn; }
394 EXPECT_EQ(NonTrivialDtor::count, 1);
395 { TN tn = makeUnexpected(NonTrivialDtor()); }
396 EXPECT_EQ(NonTrivialDtor::count, 4);
397 { NN nn; }
398 EXPECT_EQ(NonTrivialDtor::count, 5);
399 { NN nn = makeUnexpected(NonTrivialDtor()); }
400 EXPECT_EQ(NonTrivialDtor::count, 8);
401 { VN vn; }
402 EXPECT_EQ(NonTrivialDtor::count, 8);
403 { VN vn = makeUnexpected(NonTrivialDtor()); }
404 EXPECT_EQ(NonTrivialDtor::count, 11);
405}
406
407static int snowflakes = 0;
408static int melted = 0;
409struct snowflake {
410 static void reset() { snowflakes = melted = 0; }
411 snowflake() { ++snowflakes; }
412 ~snowflake() { ++melted; }
413};
414
415TEST(WTF_Expected, unique_ptr)
416{
417 // Unique snowflakes cannot be copied.
418 {
419 auto s = makeUnexpected(std::make_unique<snowflake>());
420 EXPECT_EQ(snowflakes, 1);
421 EXPECT_EQ(melted, 0);
422 }
423 EXPECT_EQ(snowflakes, 1);
424 EXPECT_EQ(melted, 1);
425 snowflake::reset();
426
427 {
428 auto s = makeUnexpected(std::make_unique<snowflake>());
429 Unexpected<std::unique_ptr<snowflake>> c(WTFMove(s));
430 EXPECT_EQ(snowflakes, 1);
431 EXPECT_EQ(melted, 0);
432 }
433 EXPECT_EQ(snowflakes, 1);
434 EXPECT_EQ(melted, 1);
435 snowflake::reset();
436
437 auto plow = [] (std::unique_ptr<snowflake>&& s)
438 {
439 {
440 std::unique_ptr<snowflake> moved = WTFMove(s);
441 EXPECT_EQ(snowflakes, 1);
442 EXPECT_EQ(melted, 0);
443 }
444 EXPECT_EQ(snowflakes, 1);
445 EXPECT_EQ(melted, 1);
446 };
447
448 {
449 Expected<std::unique_ptr<snowflake>, int> s(std::make_unique<snowflake>());
450 plow(WTFMove(s).value());
451 }
452 EXPECT_EQ(snowflakes, 1);
453 EXPECT_EQ(melted, 1);
454 snowflake::reset();
455
456 {
457 Expected<int, std::unique_ptr<snowflake>> s(makeUnexpected(std::make_unique<snowflake>()));
458 plow(WTFMove(s).error());
459 }
460 EXPECT_EQ(snowflakes, 1);
461 EXPECT_EQ(melted, 1);
462 snowflake::reset();
463
464 {
465 Expected<void, std::unique_ptr<snowflake>> s(makeUnexpected(std::make_unique<snowflake>()));
466 plow(WTFMove(s).error());
467 }
468 EXPECT_EQ(snowflakes, 1);
469 EXPECT_EQ(melted, 1);
470 snowflake::reset();
471}
472
473TEST(WTF_Expected, Ref)
474{
475 {
476 RefLogger a("a");
477 Expected<Ref<RefLogger>, int> expected = Ref<RefLogger>(a);
478 EXPECT_TRUE(expected.has_value());
479 EXPECT_EQ(&a, expected.value().ptr());
480 }
481
482 ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
483
484 {
485 RefLogger a("a");
486 Expected<Ref<RefLogger>, int> expected = Expected<Ref<RefLogger>, int>(Ref<RefLogger>(a));
487 EXPECT_TRUE(expected.has_value());
488 EXPECT_EQ(&a, expected.value().ptr());
489 }
490
491 ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
492
493 {
494 RefLogger a("a");
495 Expected<int, Ref<RefLogger>> expected = makeUnexpected(Ref<RefLogger>(a));
496 EXPECT_FALSE(expected.has_value());
497 EXPECT_EQ(&a, expected.error().ptr());
498 }
499
500 ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
501
502 {
503 RefLogger a("a");
504 Expected<void, Ref<RefLogger>> expected = makeUnexpected(Ref<RefLogger>(a));
505 EXPECT_FALSE(expected.has_value());
506 EXPECT_EQ(&a, expected.error().ptr());
507 }
508
509 ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
510}
511
512class NeedsStdAddress {
513public:
514 NeedsStdAddress(NeedsStdAddress&& other)
515 : m_ptr(WTFMove(other.m_ptr)) { }
516 NeedsStdAddress(int& other)
517 : m_ptr(&other) { }
518 int* operator&() { ASSERT_NOT_REACHED(); return nullptr; }
519private:
520 std::unique_ptr<int> m_ptr;
521};
522
523TEST(WTF_Expected, Address)
524{
525 NeedsStdAddress a(*new int(3));
526 Expected<NeedsStdAddress, float> b(WTFMove(a));
527 Expected<NeedsStdAddress, float> c(WTFMove(b));
528 (void)c;
529}
530
531} // namespace TestWebkitAPI
532