Consistently have the namespace closing comment
[folly.git] / folly / gen / test / BaseTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <glog/logging.h>
18
19 #include <iosfwd>
20 #include <memory>
21 #include <random>
22 #include <set>
23 #include <vector>
24
25 #include <folly/FBVector.h>
26 #include <folly/MapUtil.h>
27 #include <folly/Memory.h>
28 #include <folly/String.h>
29 #include <folly/dynamic.h>
30 #include <folly/experimental/TestUtil.h>
31 #include <folly/gen/Base.h>
32 #include <folly/portability/GTest.h>
33
34 using namespace folly::gen;
35 using namespace folly;
36 using std::make_tuple;
37 using std::ostream;
38 using std::pair;
39 using std::set;
40 using std::string;
41 using std::tuple;
42 using std::unique_ptr;
43 using std::vector;
44
45 #define EXPECT_SAME(A, B) \
46   static_assert(std::is_same<A, B>::value, "Mismatched: " #A ", " #B)
47 EXPECT_SAME(int&&, typename ArgumentReference<int>::type);
48 EXPECT_SAME(int&, typename ArgumentReference<int&>::type);
49 EXPECT_SAME(const int&, typename ArgumentReference<const int&>::type);
50 EXPECT_SAME(const int&, typename ArgumentReference<const int>::type);
51
52 template <typename T>
53 ostream& operator<<(ostream& os, const set<T>& values) {
54   return os << from(values);
55 }
56
57 template <typename T>
58 ostream& operator<<(ostream& os, const vector<T>& values) {
59   os << "[";
60   for (auto& value : values) {
61     if (&value != &values.front()) {
62       os << " ";
63     }
64     os << value;
65   }
66   return os << "]";
67 }
68
69 auto square = [](int x) { return x * x; };
70 auto add = [](int a, int b) { return a + b; };
71 auto multiply = [](int a, int b) { return a * b; };
72
73 auto product = foldl(1, multiply);
74
75 template <typename A, typename B>
76 ostream& operator<<(ostream& os, const pair<A, B>& pair) {
77   return os << "(" << pair.first << ", " << pair.second << ")";
78 }
79
80 TEST(Gen, Count) {
81   auto gen = seq(1, 10);
82   EXPECT_EQ(10, gen | count);
83   EXPECT_EQ(5, gen | take(5) | count);
84 }
85
86 TEST(Gen, Sum) {
87   auto gen = seq(1, 10);
88   EXPECT_EQ((1 + 10) * 10 / 2, gen | sum);
89   EXPECT_EQ((1 + 5) * 5 / 2, gen | take(5) | sum);
90 }
91
92 TEST(Gen, Foreach) {
93   auto gen = seq(1, 4);
94   int accum = 0;
95   gen | [&](int x) { accum += x; };
96   EXPECT_EQ(10, accum);
97   int accum2 = 0;
98   gen | take(3) | [&](int x) { accum2 += x; };
99   EXPECT_EQ(6, accum2);
100 }
101
102 TEST(Gen, Map) {
103   auto expected = vector<int>{4, 9, 16};
104   auto gen = from({2, 3, 4}) | map(square);
105   EXPECT_EQ((vector<int>{4, 9, 16}), gen | as<vector>());
106   EXPECT_EQ((vector<int>{4, 9}), gen | take(2) | as<vector>());
107 }
108
109 TEST(Gen, Member) {
110   struct Counter {
111     Counter(int start = 0)
112       : c(start)
113     {}
114
115     int count() const { return c; }
116     int incr() { return ++c; }
117
118     int& ref() { return c; }
119     const int& ref() const { return c; }
120    private:
121     int c;
122   };
123   auto counters = seq(1, 10) | eachAs<Counter>() | as<vector>();
124   EXPECT_EQ(10 * (1 + 10) / 2,
125             from(counters)
126           | member(&Counter::count)
127           | sum);
128   EXPECT_EQ(10 * (1 + 10) / 2,
129             from(counters)
130           | indirect
131           | member(&Counter::count)
132           | sum);
133   EXPECT_EQ(10 * (2 + 11) / 2,
134             from(counters)
135           | member(&Counter::incr)
136           | sum);
137   EXPECT_EQ(10 * (3 + 12) / 2,
138             from(counters)
139           | indirect
140           | member(&Counter::incr)
141           | sum);
142   EXPECT_EQ(10 * (3 + 12) / 2,
143             from(counters)
144           | member(&Counter::count)
145           | sum);
146
147   // type-verifications
148   auto m = empty<Counter&>();
149   auto c = empty<const Counter&>();
150   m | member(&Counter::incr) | assert_type<int&&>();
151   m | member(&Counter::count) | assert_type<int&&>();
152   m | member(&Counter::count) | assert_type<int&&>();
153   m | member<Const>(&Counter::ref) | assert_type<const int&>();
154   m | member<Mutable>(&Counter::ref) | assert_type<int&>();
155   c | member<Const>(&Counter::ref) | assert_type<const int&>();
156 }
157
158 TEST(Gen, Field) {
159   struct X {
160     X() : a(2), b(3), c(4), d(b) {}
161
162     const int a;
163     int b;
164     mutable int c;
165     int& d; // can't access this with a field pointer.
166   };
167
168   std::vector<X> xs(1);
169   EXPECT_EQ(2, from(xs)
170              | field(&X::a)
171              | sum);
172   EXPECT_EQ(3, from(xs)
173              | field(&X::b)
174              | sum);
175   EXPECT_EQ(4, from(xs)
176              | field(&X::c)
177              | sum);
178   EXPECT_EQ(2, seq(&xs[0], &xs[0])
179              | field(&X::a)
180              | sum);
181   // type-verification
182   empty<X&>() | field(&X::a) | assert_type<const int&>();
183   empty<X*>() | field(&X::a) | assert_type<const int&>();
184   empty<X&>() | field(&X::b) | assert_type<int&>();
185   empty<X*>() | field(&X::b) | assert_type<int&>();
186   empty<X&>() | field(&X::c) | assert_type<int&>();
187   empty<X*>() | field(&X::c) | assert_type<int&>();
188
189   empty<X&&>() | field(&X::a) | assert_type<const int&&>();
190   empty<X&&>() | field(&X::b) | assert_type<int&&>();
191   empty<X&&>() | field(&X::c) | assert_type<int&&>();
192   // references don't imply ownership so they're not moved
193
194   empty<const X&>() | field(&X::a) | assert_type<const int&>();
195   empty<const X*>() | field(&X::a) | assert_type<const int&>();
196   empty<const X&>() | field(&X::b) | assert_type<const int&>();
197   empty<const X*>() | field(&X::b) | assert_type<const int&>();
198   // 'mutable' has no effect on field pointers, by C++ spec
199   empty<const X&>() | field(&X::c) | assert_type<const int&>();
200   empty<const X*>() | field(&X::c) | assert_type<const int&>();
201
202   // can't form pointer-to-reference field: empty<X&>() | field(&X::d)
203 }
204
205 TEST(Gen, Seq) {
206   // cover the fenceposts of the loop unrolling
207   for (int n = 1; n < 100; ++n) {
208     EXPECT_EQ(n, seq(1, n) | count);
209     EXPECT_EQ(n + 1, seq(1) | take(n + 1) | count);
210   }
211 }
212
213 TEST(Gen, SeqWithStep) {
214   EXPECT_EQ(75, seq(5, 25, 5) | sum);
215 }
216
217 TEST(Gen, SeqWithStepArray) {
218   const std::array<int, 6> arr{{1, 2, 3, 4, 5, 6}};
219   EXPECT_EQ(9, seq(&arr[0], &arr[5], 2)
220              | map([](const int *i) { return *i; })
221              | sum);
222 }
223
224 TEST(Gen, Range) {
225   // cover the fenceposts of the loop unrolling
226   for (int n = 1; n < 100; ++n) {
227     EXPECT_EQ(gen::range(0, n) | count, n);
228   }
229 }
230
231 TEST(Gen, RangeWithStep) {
232   EXPECT_EQ(50, range(5, 25, 5) | sum);
233 }
234
235 TEST(Gen, FromIterators) {
236   vector<int> source {2, 3, 5, 7, 11};
237   auto gen = from(folly::range(source.begin() + 1, source.end() - 1));
238   EXPECT_EQ(3 * 5 * 7, gen | product);
239 }
240
241 TEST(Gen, FromMap) {
242   auto source = seq(0, 10)
243               | map([](int i) { return std::make_pair(i, i * i); })
244               | as<std::map<int, int>>();
245   auto gen = fromConst(source)
246            | map([&](const std::pair<const int, int>& p) {
247                return p.second - p.first;
248              });
249   EXPECT_EQ(330, gen | sum);
250 }
251
252 TEST(Gen, Filter) {
253   const auto expected = vector<int>{1, 2, 4, 5, 7, 8};
254   auto actual =
255       seq(1, 9)
256     | filter([](int x) { return x % 3; })
257     | as<vector<int>>();
258   EXPECT_EQ(expected, actual);
259 }
260
261 TEST(Gen, FilterDefault) {
262   {
263     // Default filter should remove 0s
264     const auto expected = vector<int>{1, 1, 2, 3};
265     auto actual =
266         from({0, 1, 1, 0, 2, 3, 0})
267       | filter()
268       | as<vector>();
269     EXPECT_EQ(expected, actual);
270   }
271   {
272     // Default filter should remove nullptrs
273     int a = 5;
274     int b = 3;
275     int c = 0;
276     const auto expected = vector<int*>{&a, &b, &c};
277     auto actual =
278         from({(int*)nullptr, &a, &b, &c, (int*)nullptr})
279       | filter()
280       | as<vector>();
281     EXPECT_EQ(expected, actual);
282   }
283   {
284     // Default filter on Optionals should remove folly::null
285     const auto expected =
286         vector<Optional<int>>{Optional<int>(5), Optional<int>(0)};
287     const auto actual =
288         from({Optional<int>(5), Optional<int>(), Optional<int>(0)})
289       | filter()
290       | as<vector>();
291     EXPECT_EQ(expected, actual);
292   }
293 }
294
295 TEST(Gen, FilterSink) {
296   auto actual
297     = seq(1, 2)
298     | map([](int x) { return vector<int>{x}; })
299     | filter([](vector<int> v) { return !v.empty(); })
300     | as<vector>();
301   EXPECT_FALSE(from(actual) | rconcat | isEmpty);
302 }
303
304 TEST(Gen, Contains) {
305   {
306     auto gen =
307         seq(1, 9)
308       | map(square);
309     EXPECT_TRUE(gen | contains(49));
310     EXPECT_FALSE(gen | contains(50));
311   }
312   {
313     auto gen =
314         seq(1) // infinite, to prove laziness
315       | map(square)
316       | eachTo<std::string>();
317
318     // std::string gen, const char* needle
319     EXPECT_TRUE(gen | take(9999) | contains("49"));
320   }
321 }
322
323 TEST(Gen, Take) {
324   {
325     auto expected = vector<int>{1, 4, 9, 16};
326     auto actual =
327       seq(1, 1000)
328       | mapped([](int x) { return x * x; })
329       | take(4)
330       | as<vector<int>>();
331     EXPECT_EQ(expected, actual);
332   }
333   {
334     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
335     auto actual
336       = ((seq(0) | take(2)) +
337          (seq(4) | take(2)) +
338          (seq(8) | take(2)))
339       | take(5)
340       | as<vector>();
341     EXPECT_EQ(expected, actual);
342   }
343   {
344     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
345     auto actual
346       = seq(0)
347       | mapped([](int i) {
348           return seq(i * 4) | take(2);
349         })
350       | concat
351       | take(5)
352       | as<vector>();
353     EXPECT_EQ(expected, actual);
354   }
355   {
356     int64_t limit = 5;
357     take(limit - 5);
358     EXPECT_THROW(take(limit - 6), std::invalid_argument);
359   }
360 }
361
362
363 TEST(Gen, Stride) {
364   {
365     EXPECT_THROW(stride(0), std::invalid_argument);
366   }
367   {
368     auto expected = vector<int>{1, 2, 3, 4};
369     auto actual
370       = seq(1, 4)
371       | stride(1)
372       | as<vector<int>>();
373     EXPECT_EQ(expected, actual);
374   }
375   {
376     auto expected = vector<int>{1, 3, 5, 7};
377     auto actual
378       = seq(1, 8)
379       | stride(2)
380       | as<vector<int>>();
381     EXPECT_EQ(expected, actual);
382   }
383   {
384     auto expected = vector<int>{1, 4, 7, 10};
385     auto actual
386       = seq(1, 12)
387       | stride(3)
388       | as<vector<int>>();
389     EXPECT_EQ(expected, actual);
390   }
391   {
392     auto expected = vector<int>{1, 3, 5, 7, 9, 1, 4, 7, 10};
393     auto actual
394       = ((seq(1, 10) | stride(2)) +
395          (seq(1, 10) | stride(3)))
396       | as<vector<int>>();
397     EXPECT_EQ(expected, actual);
398   }
399   EXPECT_EQ(500, seq(1) | take(1000) | stride(2) | count);
400   EXPECT_EQ(10, seq(1) | take(1000) | stride(2) | take(10) | count);
401 }
402
403 TEST(Gen, Sample) {
404   std::mt19937 rnd(42);
405
406   auto sampler =
407       seq(1, 100)
408     | sample(50, rnd);
409   std::unordered_map<int,int> hits;
410   const int kNumIters = 80;
411   for (int i = 0; i < kNumIters; i++) {
412     auto vec = sampler | as<vector<int>>();
413     EXPECT_EQ(vec.size(), 50);
414     auto uniq = fromConst(vec) | as<set<int>>();
415     EXPECT_EQ(uniq.size(), vec.size());  // sampling without replacement
416     for (auto v: vec) {
417       ++hits[v];
418     }
419   }
420
421   // In 80 separate samples of our range, we should have seen every value
422   // at least once and no value all 80 times. (The odds of either of those
423   // events is 1/2^80).
424   EXPECT_EQ(hits.size(), 100);
425   for (auto hit: hits) {
426     EXPECT_GT(hit.second, 0);
427     EXPECT_LT(hit.second, kNumIters);
428   }
429
430   auto small =
431       seq(1, 5)
432     | sample(10);
433   EXPECT_EQ((small | sum), 15);
434   EXPECT_EQ((small | take(3) | count), 3);
435 }
436
437 TEST(Gen, Skip) {
438   auto gen =
439       seq(1, 1000)
440     | mapped([](int x) { return x * x; })
441     | skip(4)
442     | take(4);
443   EXPECT_EQ((vector<int>{25, 36, 49, 64}), gen | as<vector>());
444 }
445
446 TEST(Gen, Until) {
447   {
448     auto expected = vector<int>{1, 4, 9, 16};
449     auto actual
450       = seq(1, 1000)
451       | mapped([](int x) { return x * x; })
452       | until([](int x) { return x > 20; })
453       | as<vector<int>>();
454     EXPECT_EQ(expected, actual);
455   }
456   {
457     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
458     auto actual
459       = ((seq(0) | until([](int i) { return i > 1; })) +
460          (seq(4) | until([](int i) { return i > 5; })) +
461          (seq(8) | until([](int i) { return i > 9; })))
462       | until([](int i) { return i > 8; })
463       | as<vector<int>>();
464     EXPECT_EQ(expected, actual);
465   }
466   /*
467   {
468     auto expected = vector<int>{ 0, 1, 5, 6, 10 };
469     auto actual
470       = seq(0)
471       | mapped([](int i) {
472           return seq(i * 5) | until([=](int j) { return j > i * 5 + 1; });
473         })
474       | concat
475       | until([](int i) { return i > 10; })
476       | as<vector<int>>();
477     EXPECT_EQ(expected, actual);
478   }
479     */
480 }
481
482 TEST(Gen, Visit) {
483   auto increment = [](int& i) { ++i; };
484   auto clone = map([](int i) { return i; });
485   { // apply()
486     auto expected = 10;
487     auto actual = seq(0) | clone | visit(increment) | take(4) | sum;
488     EXPECT_EQ(expected, actual);
489   }
490   { // foreach()
491     auto expected = 10;
492     auto actual = seq(0, 3) | clone | visit(increment) | sum;
493     EXPECT_EQ(expected, actual);
494   }
495   { // tee-like
496     std::vector<int> x2, x4;
497     std::vector<int> expected2{0, 1, 4, 9};
498     std::vector<int> expected4{0, 1, 16, 81};
499
500     auto tee = [](std::vector<int>& container) {
501       return visit([&](int value) { container.push_back(value); });
502     };
503     EXPECT_EQ(
504         98, seq(0, 3) | map(square) | tee(x2) | map(square) | tee(x4) | sum);
505     EXPECT_EQ(expected2, x2);
506     EXPECT_EQ(expected4, x4);
507   }
508 }
509
510 TEST(Gen, Composed) {
511   // Operator, Operator
512   auto valuesOf =
513       filter([](Optional<int>& o) { return o.hasValue(); })
514     | map([](Optional<int>& o) -> int& { return o.value(); });
515   std::vector<Optional<int>> opts {
516     none, 4, none, 6, none
517   };
518   EXPECT_EQ(4 * 4 + 6 * 6, from(opts) | valuesOf | map(square) | sum);
519   // Operator, Sink
520   auto sumOpt = valuesOf | sum;
521   EXPECT_EQ(10, from(opts) | sumOpt);
522 }
523
524 TEST(Gen, Chain) {
525   std::vector<int> nums {2, 3, 5, 7};
526   std::map<int, int> mappings { { 3, 9}, {5, 25} };
527   auto gen = from(nums) + (from(mappings) | get<1>());
528   EXPECT_EQ(51, gen | sum);
529   EXPECT_EQ(5, gen | take(2) | sum);
530   EXPECT_EQ(26, gen | take(5) | sum);
531 }
532
533 TEST(Gen, Concat) {
534   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
535   auto gen = from(nums) | rconcat;
536   EXPECT_EQ(17, gen | sum);
537   EXPECT_EQ(10, gen | take(3) | sum);
538 }
539
540 TEST(Gen, ConcatGen) {
541   auto gen = seq(1, 10)
542            | map([](int i) { return seq(1, i); })
543            | concat;
544   EXPECT_EQ(220, gen | sum);
545   EXPECT_EQ(10, gen | take(6) | sum);
546 }
547
548 TEST(Gen, ConcatAlt) {
549   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
550   auto actual = from(nums)
551               | map([](std::vector<int>& v) { return from(v); })
552               | concat
553               | sum;
554   auto expected = 17;
555   EXPECT_EQ(expected, actual);
556 }
557
558 TEST(Gen, Order) {
559   auto expected = vector<int>{0, 3, 5, 6, 7, 8, 9};
560   auto actual =
561       from({8, 6, 7, 5, 3, 0, 9})
562     | order
563     | as<vector>();
564   EXPECT_EQ(expected, actual);
565 }
566
567 TEST(Gen, OrderMoved) {
568   auto expected = vector<int>{0, 9, 25, 36, 49, 64, 81};
569   auto actual =
570       from({8, 6, 7, 5, 3, 0, 9})
571     | move
572     | order
573     | map(square)
574     | as<vector>();
575   EXPECT_EQ(expected, actual);
576 }
577
578 TEST(Gen, OrderTake) {
579   auto expected = vector<int>{9, 8, 7};
580   auto actual =
581       from({8, 6, 7, 5, 3, 0, 9})
582     | orderByDescending(square)
583     | take(3)
584     | as<vector>();
585   EXPECT_EQ(expected, actual);
586 }
587
588 TEST(Gen, Distinct) {
589   auto expected = vector<int>{3, 1, 2};
590   auto actual =
591       from({3, 1, 3, 2, 1, 2, 3})
592     | distinct
593     | as<vector>();
594   EXPECT_EQ(expected, actual);
595 }
596
597 TEST(Gen, DistinctBy) {   //  0  1  4  9  6  5  6  9  4  1  0
598   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
599   auto actual =
600       seq(0, 100)
601     | distinctBy([](int i) { return i * i % 10; })
602     | as<vector>();
603   EXPECT_EQ(expected, actual);
604 }
605
606 TEST(Gen, DistinctMove) {   //  0  1  4  9  6  5  6  9  4  1  0
607   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
608   auto actual = seq(0, 100) |
609       mapped([](int i) { return std::make_unique<int>(i); })
610       // see comment below about selector parameters for Distinct
611       | distinctBy([](const std::unique_ptr<int>& pi) {
612                   return *pi * *pi % 10;
613                 }) |
614       mapped([](std::unique_ptr<int> pi) { return *pi; }) | as<vector>();
615
616   // NOTE(tjackson): the following line intentionally doesn't work:
617   //  | distinctBy([](std::unique_ptr<int> pi) { return *pi * *pi % 10; })
618   // This is because distinctBy because the selector intentionally requires a
619   // const reference.  If it required a move-reference, the value might get
620   // gutted by the selector before said value could be passed to downstream
621   // operators.
622   EXPECT_EQ(expected, actual);
623 }
624
625 TEST(Gen, DistinctInfinite) {
626   // distinct should be able to handle an infinite sequence, provided that, of
627   // of cource, is it eventually made finite before returning the result.
628   auto expected = seq(0) | take(5) | as<vector>(); // 0 1 2 3 4
629
630   auto actual =
631       seq(0)                              // 0 1 2 3 4 5 6 7 ...
632     | mapped([](int i) { return i / 2; }) // 0 0 1 1 2 2 3 3 ...
633     | distinct                            // 0 1 2 3 4 5 6 7 ...
634     | take(5)                             // 0 1 2 3 4
635     | as<vector>();
636
637   EXPECT_EQ(expected, actual);
638 }
639
640 TEST(Gen, DistinctByInfinite) {
641   // Similarly to the DistinctInfinite test case, distinct by should be able to
642   // handle infinite sequences. Note that depending on how many values we take()
643   // at the end, the sequence may infinite loop. This is fine becasue we cannot
644   // solve the halting problem.
645   auto expected = vector<int>{1, 2};
646   auto actual =
647       seq(1)                                    // 1 2 3 4 5 6 7 8 ...
648     | distinctBy([](int i) { return i % 2; })   // 1 2 (but might by infinite)
649     | take(2)                                   // 1 2
650     | as<vector>();
651   // Note that if we had take(3), this would infinite loop
652
653   EXPECT_EQ(expected, actual);
654 }
655
656 TEST(Gen, MinBy) {
657   EXPECT_EQ(7, seq(1, 10)
658              | minBy([](int i) -> double {
659                  double d = i - 6.8;
660                  return d * d;
661                })
662              | unwrap);
663 }
664
665 TEST(Gen, MaxBy) {
666   auto gen = from({"three", "eleven", "four"});
667
668   EXPECT_EQ("eleven", gen | maxBy(&strlen) | unwrap);
669 }
670
671 TEST(Gen, Min) {
672   auto odds = seq(2,10) | filter([](int i){ return i % 2; });
673
674   EXPECT_EQ(3, odds | min);
675 }
676
677 TEST(Gen, Max) {
678   auto odds = seq(2,10) | filter([](int i){ return i % 2; });
679
680   EXPECT_EQ(9, odds | max);
681 }
682
683 TEST(Gen, Append) {
684   string expected = "facebook";
685   string actual = "face";
686   from(StringPiece("book")) | appendTo(actual);
687   EXPECT_EQ(expected, actual);
688 }
689
690 TEST(Gen, FromRValue) {
691   {
692     // AFAICT The C++ Standard does not specify what happens to the rvalue
693     // reference of a std::vector when it is used as the 'other' for an rvalue
694     // constructor.  Use fbvector because we're sure its size will be zero in
695     // this case.
696     fbvector<int> v({1, 2, 3, 4});
697     auto q1 = from(v);
698     EXPECT_EQ(v.size(), 4);  // ensure that the lvalue version was called!
699     auto expected = 1 * 2 * 3 * 4;
700     EXPECT_EQ(expected, q1 | product);
701
702     auto q2 = from(std::move(v));
703     EXPECT_EQ(v.size(), 0);  // ensure that rvalue version was called
704     EXPECT_EQ(expected, q2 | product);
705   }
706   {
707     auto expected = 7;
708     auto q = from([] { return vector<int>({3, 7, 5}); }());
709     EXPECT_EQ(expected, q | max);
710   }
711   {
712     for (auto size : {5, 1024, 16384, 1 << 20}) {
713       auto q1 = from(vector<int>(size, 2));
714       auto q2 = from(vector<int>(size, 3));
715       // If the rvalue specialization is broken/gone, then the compiler will
716       // (disgustingly!) just store a *reference* to the temporary object,
717       // which is bad.  Try to catch this by allocating two temporary vectors
718       // of the same size, so that they'll probably use the same underlying
719       // buffer if q1's vector is destructed before q2's vector is constructed.
720       EXPECT_EQ(size * 2 + size * 3, (q1 | sum) + (q2 | sum));
721     }
722   }
723   {
724     auto q = from(set<int>{1,2,3,2,1});
725     EXPECT_EQ(q | sum, 6);
726   }
727 }
728
729 TEST(Gen, OrderBy) {
730   auto expected = vector<int>{5, 6, 4, 7, 3, 8, 2, 9, 1, 10};
731   auto actual =
732       seq(1, 10)
733     | orderBy([](int x) { return (5.1 - x) * (5.1 - x); })
734     | as<vector>();
735   EXPECT_EQ(expected, actual);
736
737   expected = seq(1, 10) | as<vector>();
738   actual =
739       from(expected)
740     | map([] (int x) { return 11 - x; })
741     | orderBy()
742     | as<vector>();
743   EXPECT_EQ(expected, actual);
744 }
745
746 TEST(Gen, Foldl) {
747   int expected = 2 * 3 * 4 * 5;
748   auto actual =
749       seq(2, 5)
750     | foldl(1, multiply);
751   EXPECT_EQ(expected, actual);
752 }
753
754 TEST(Gen, Reduce) {
755   int expected = 2 + 3 + 4 + 5;
756   auto actual = seq(2, 5) | reduce(add);
757   EXPECT_EQ(expected, actual | unwrap);
758 }
759
760 TEST(Gen, ReduceBad) {
761   auto gen = seq(1) | take(0);
762   auto actual = gen | reduce(add);
763   EXPECT_FALSE(actual); // Empty sequences are okay, they just yeild 'none'
764 }
765
766 TEST(Gen, Moves) {
767   std::vector<unique_ptr<int>> ptrs;
768   ptrs.emplace_back(new int(1));
769   EXPECT_NE(ptrs.front().get(), nullptr);
770   auto ptrs2 = from(ptrs) | move | as<vector>();
771   EXPECT_EQ(ptrs.front().get(), nullptr);
772   EXPECT_EQ(**ptrs2.data(), 1);
773 }
774
775 TEST(Gen, First) {
776   auto gen = seq(0) | filter([](int x) { return x > 3; });
777   EXPECT_EQ(4, gen | first | unwrap);
778 }
779
780 TEST(Gen, FromCopy) {
781   vector<int> v {3, 5};
782   auto src = from(v);
783   auto copy = fromCopy(v);
784   EXPECT_EQ(8, src | sum);
785   EXPECT_EQ(8, copy | sum);
786   v[1] = 7;
787   EXPECT_EQ(10, src | sum);
788   EXPECT_EQ(8, copy | sum);
789 }
790
791 TEST(Gen, Get) {
792   std::map<int, int> pairs {
793     {1, 1},
794     {2, 4},
795     {3, 9},
796     {4, 16},
797   };
798   auto pairSrc = from(pairs);
799   auto keys = pairSrc | get<0>();
800   auto values = pairSrc | get<1>();
801   EXPECT_EQ(10, keys | sum);
802   EXPECT_EQ(30, values | sum);
803   EXPECT_EQ(30, keys | map(square) | sum);
804   pairs[5] = 25;
805   EXPECT_EQ(15, keys | sum);
806   EXPECT_EQ(55, values | sum);
807
808   vector<tuple<int, int, int>> tuples {
809     make_tuple(1, 1, 1),
810     make_tuple(2, 4, 8),
811     make_tuple(3, 9, 27),
812   };
813   EXPECT_EQ(36, from(tuples) | get<2>() | sum);
814 }
815
816 TEST(Gen, notEmpty) {
817   EXPECT_TRUE(seq(0, 1) | notEmpty);
818   EXPECT_TRUE(just(1) | notEmpty);
819   EXPECT_FALSE(gen::range(0, 0) | notEmpty);
820   EXPECT_FALSE(from({1}) | take(0) | notEmpty);
821 }
822
823 TEST(Gen, isEmpty) {
824   EXPECT_FALSE(seq(0, 1) | isEmpty);
825   EXPECT_FALSE(just(1) | isEmpty);
826   EXPECT_TRUE(gen::range(0, 0) | isEmpty);
827   EXPECT_TRUE(from({1}) | take(0) | isEmpty);
828 }
829
830 TEST(Gen, Any) {
831   EXPECT_TRUE(seq(0, 10) | any([](int i) { return i == 7; }));
832   EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; }));
833 }
834
835 TEST(Gen, All) {
836   EXPECT_TRUE(seq(0, 10) | all([](int i) { return i < 11; }));
837   EXPECT_FALSE(seq(0, 10) | all([](int i) { return i < 5; }));
838   EXPECT_FALSE(seq(0) | take(9999) | all([](int i) { return i < 10; }));
839
840   // empty lists satisfies all
841   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i < 50; }));
842   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i > 50; }));
843 }
844
845 TEST(Gen, Yielders) {
846   auto gen = GENERATOR(int) {
847     for (int i = 1; i <= 5; ++i) {
848       yield(i);
849     }
850     yield(7);
851     for (int i = 3; ; ++i) {
852       yield(i * i);
853     }
854   };
855   vector<int> expected {
856     1, 2, 3, 4, 5, 7, 9, 16, 25
857   };
858   EXPECT_EQ(expected, gen | take(9) | as<vector>());
859 }
860
861 TEST(Gen, NestedYield) {
862   auto nums = GENERATOR(int) {
863     for (int i = 1; ; ++i) {
864       yield(i);
865     }
866   };
867   auto gen = GENERATOR(int) {
868     nums | take(10) | yield;
869     seq(1, 5) | [&](int i) {
870       yield(i);
871     };
872   };
873   EXPECT_EQ(70, gen | sum);
874 }
875
876 TEST(Gen, MapYielders) {
877   auto gen = seq(1, 5)
878            | map([](int n) {
879                return GENERATOR(int) {
880                  int i;
881                  for (i = 1; i < n; ++i) {
882                    yield(i);
883                  }
884                  for (; i >= 1; --i) {
885                    yield(i);
886                  }
887                };
888              })
889            | concat;
890   vector<int> expected {
891                 1,
892              1, 2, 1,
893           1, 2, 3, 2, 1,
894        1, 2, 3, 4, 3, 2, 1,
895     1, 2, 3, 4, 5, 4, 3, 2, 1,
896   };
897   EXPECT_EQ(expected, gen | as<vector>());
898 }
899
900 TEST(Gen, VirtualGen) {
901   VirtualGen<int> v(seq(1, 10));
902   EXPECT_EQ(55, v | sum);
903   v = v | map(square);
904   EXPECT_EQ(385, v | sum);
905   v = v | take(5);
906   EXPECT_EQ(55, v | sum);
907   EXPECT_EQ(30, v | take(4) | sum);
908 }
909
910
911 TEST(Gen, CustomType) {
912   struct Foo{
913     int y;
914   };
915   auto gen = from({Foo{2}, Foo{3}})
916            | map([](const Foo& f) { return f.y; });
917   EXPECT_EQ(5, gen | sum);
918 }
919
920 TEST(Gen, NoNeedlessCopies) {
921   auto gen = seq(1, 5) | map([](int x) { return std::make_unique<int>(x); }) |
922       map([](unique_ptr<int> p) { return p; }) |
923       map([](unique_ptr<int>&& p) { return std::move(p); }) |
924       map([](const unique_ptr<int>& p) { return *p; });
925   EXPECT_EQ(15, gen | sum);
926   EXPECT_EQ(6, gen | take(3) | sum);
927 }
928
929 namespace {
930
931 class TestIntSeq : public GenImpl<int, TestIntSeq> {
932  public:
933   TestIntSeq() { }
934
935   template <class Body>
936   bool apply(Body&& body) const {
937     for (int i = 1; i < 6; ++i) {
938       if (!body(i)) {
939         return false;
940       }
941     }
942     return true;
943   }
944
945   TestIntSeq(TestIntSeq&&) noexcept = default;
946   TestIntSeq& operator=(TestIntSeq&&) noexcept = default;
947   TestIntSeq(const TestIntSeq&) = delete;
948   TestIntSeq& operator=(const TestIntSeq&) = delete;
949 };
950
951 } // namespace
952
953 TEST(Gen, NoGeneratorCopies) {
954   EXPECT_EQ(15, TestIntSeq() | sum);
955   auto x = TestIntSeq() | take(3);
956   EXPECT_EQ(6, std::move(x) | sum);
957 }
958
959 TEST(Gen, FromArray) {
960   int source[] = {2, 3, 5, 7};
961   auto gen = from(source);
962   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
963 }
964
965 TEST(Gen, FromStdArray) {
966   std::array<int,4> source {{2, 3, 5, 7}};
967   auto gen = from(source);
968   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
969 }
970
971 TEST(Gen, StringConcat) {
972   auto gen = seq(1, 10)
973            | eachTo<string>()
974            | rconcat;
975   EXPECT_EQ("12345678910", gen | as<string>());
976 }
977
978 struct CopyCounter {
979   static int alive;
980   int copies;
981   int moves;
982
983   CopyCounter() : copies(0), moves(0) {
984     ++alive;
985   }
986
987   CopyCounter(CopyCounter&& source) noexcept {
988     *this = std::move(source);
989     ++alive;
990   }
991
992   CopyCounter(const CopyCounter& source) {
993     *this = source;
994     ++alive;
995   }
996
997   ~CopyCounter() {
998     --alive;
999   }
1000
1001   CopyCounter& operator=(const CopyCounter& source) {
1002     this->copies = source.copies + 1;
1003     this->moves = source.moves;
1004     return *this;
1005   }
1006
1007   CopyCounter& operator=(CopyCounter&& source) {
1008     this->copies = source.copies;
1009     this->moves = source.moves + 1;
1010     return *this;
1011   }
1012 };
1013
1014 int CopyCounter::alive = 0;
1015
1016 TEST(Gen, CopyCount) {
1017   vector<CopyCounter> originals;
1018   originals.emplace_back();
1019   EXPECT_EQ(1, originals.size());
1020   EXPECT_EQ(0, originals.back().copies);
1021
1022   vector<CopyCounter> copies = from(originals) | as<vector>();
1023   EXPECT_EQ(1, copies.back().copies);
1024   EXPECT_EQ(0, copies.back().moves);
1025
1026   vector<CopyCounter> moves = from(originals) | move | as<vector>();
1027   EXPECT_EQ(0, moves.back().copies);
1028   EXPECT_EQ(1, moves.back().moves);
1029 }
1030
1031 // test dynamics with various layers of nested arrays.
1032 TEST(Gen, Dynamic) {
1033   dynamic array1 = dynamic::array(1, 2);
1034   EXPECT_EQ(dynamic(3), from(array1) | sum);
1035   dynamic array2 = folly::dynamic::array(
1036       folly::dynamic::array(1), folly::dynamic::array(1, 2));
1037   EXPECT_EQ(dynamic(4), from(array2) | rconcat | sum);
1038   dynamic array3 = folly::dynamic::array(
1039       folly::dynamic::array(folly::dynamic::array(1)),
1040       folly::dynamic::array(
1041           folly::dynamic::array(1), folly::dynamic::array(1, 2)));
1042   EXPECT_EQ(dynamic(5), from(array3) | rconcat | rconcat | sum);
1043 }
1044
1045 TEST(Gen, DynamicObject) {
1046   const dynamic obj = dynamic::object(1, 2)(3, 4);
1047   EXPECT_EQ(dynamic(4), from(obj.keys()) | sum);
1048   EXPECT_EQ(dynamic(6), from(obj.values()) | sum);
1049   EXPECT_EQ(dynamic(4), from(obj.items()) | get<0>() | sum);
1050   EXPECT_EQ(dynamic(6), from(obj.items()) | get<1>() | sum);
1051 }
1052
1053 TEST(Gen, Collect) {
1054   auto s = from({7, 6, 5, 4, 3}) | as<set<int>>();
1055   EXPECT_EQ(s.size(), 5);
1056 }
1057
1058
1059 TEST(Gen, Cycle) {
1060   {
1061     auto s = from({1, 2});
1062     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1063               s | cycle | take(5) | as<vector>());
1064   }
1065   {
1066     auto s = from({1, 2});
1067     EXPECT_EQ((vector<int> { 1, 2, 1, 2 }),
1068               s | cycle(2) | as<vector>());
1069   }
1070   {
1071     auto s = from({1, 2, 3});
1072     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1073               s | take(2) | cycle | take(5) | as<vector>());
1074   }
1075   {
1076     auto s = empty<int>();
1077     EXPECT_EQ((vector<int> { }),
1078               s | cycle | take(4) | as<vector>());
1079   }
1080   {
1081     int count = 3;
1082     int* pcount = &count;
1083     auto countdown = GENERATOR(int) {
1084       ASSERT_GE(*pcount, 0)
1085         << "Cycle should have stopped when it didnt' get values!";
1086       for (int i = 1; i <= *pcount; ++i) {
1087         yield(i);
1088       }
1089       --*pcount;
1090     };
1091     auto s = countdown;
1092     EXPECT_EQ((vector<int> { 1, 2, 3, 1, 2, 1}),
1093               s | cycle | take(7) | as<vector>());
1094     // take necessary as cycle returns an infinite generator
1095   }
1096 }
1097
1098 TEST(Gen, Dereference) {
1099   {
1100     const int x = 4, y = 2;
1101     auto s = from(std::initializer_list<const int*>({&x, nullptr, &y}));
1102     EXPECT_EQ(6, s | dereference | sum);
1103   }
1104   {
1105     vector<int> a { 1, 2 };
1106     vector<int> b { 3, 4 };
1107     vector<vector<int>*> pv { &a, nullptr, &b };
1108     from(pv)
1109       | dereference
1110       | [&](vector<int>& v) {
1111           v.push_back(5);
1112         };
1113     EXPECT_EQ(3, a.size());
1114     EXPECT_EQ(3, b.size());
1115     EXPECT_EQ(5, a.back());
1116     EXPECT_EQ(5, b.back());
1117   }
1118   {
1119     vector<std::map<int, int>> maps {
1120       {
1121         { 2, 31 },
1122         { 3, 41 },
1123       },
1124       {
1125         { 3, 52 },
1126         { 4, 62 },
1127       },
1128       {
1129         { 4, 73 },
1130         { 5, 83 },
1131       },
1132     };
1133     EXPECT_EQ(
1134       93,
1135       from(maps)
1136       | map([](std::map<int, int>& m) {
1137           return get_ptr(m, 3);
1138         })
1139       | dereference
1140       | sum);
1141   }
1142   {
1143     vector<unique_ptr<int>> ups;
1144     ups.emplace_back(new int(3));
1145     ups.emplace_back();
1146     ups.emplace_back(new int(7));
1147     EXPECT_EQ(10, from(ups) | dereference | sum);
1148     EXPECT_EQ(10, from(ups) | move | dereference | sum);
1149   }
1150 }
1151
1152 namespace {
1153 struct DereferenceWrapper {
1154   string data;
1155   string& operator*() & {
1156     return data;
1157   }
1158   string&& operator*() && {
1159     return std::move(data);
1160   }
1161   explicit operator bool() {
1162     return true;
1163   }
1164 };
1165 bool operator==(const DereferenceWrapper& a, const DereferenceWrapper& b) {
1166   return a.data == b.data;
1167 }
1168 void PrintTo(const DereferenceWrapper& a, std::ostream* o) {
1169   *o << "Wrapper{\"" << cEscape<string>(a.data) << "\"}";
1170 }
1171 } // namespace
1172
1173 TEST(Gen, DereferenceWithLValueRef) {
1174   auto original = vector<DereferenceWrapper>{{"foo"}, {"bar"}};
1175   auto copy = original;
1176   auto expected = vector<string>{"foo", "bar"};
1177   auto actual = from(original) | dereference | as<vector>();
1178   EXPECT_EQ(expected, actual);
1179   EXPECT_EQ(copy, original);
1180 }
1181
1182 TEST(Gen, DereferenceWithRValueRef) {
1183   auto original = vector<DereferenceWrapper>{{"foo"}, {"bar"}};
1184   auto empty = vector<DereferenceWrapper>{{}, {}};
1185   auto expected = vector<string>{"foo", "bar"};
1186   auto actual = from(original) | move | dereference | as<vector>();
1187   EXPECT_EQ(expected, actual);
1188   EXPECT_EQ(empty, original);
1189 }
1190
1191 TEST(Gen, Indirect) {
1192   vector<int> vs{1};
1193   EXPECT_EQ(&vs[0], from(vs) | indirect | first | unwrap);
1194 }
1195
1196 TEST(Gen, Guard) {
1197   using std::runtime_error;
1198   EXPECT_THROW(from({"1", "a", "3"})
1199                | eachTo<int>()
1200                | sum,
1201                runtime_error);
1202   EXPECT_EQ(4,
1203             from({"1", "a", "3"})
1204             | guard<runtime_error>([](runtime_error&, const char*) {
1205                 return true; // continue
1206               })
1207             | eachTo<int>()
1208             | sum);
1209   EXPECT_EQ(1,
1210             from({"1", "a", "3"})
1211             | guard<runtime_error>([](runtime_error&, const char*) {
1212                 return false; // break
1213               })
1214             | eachTo<int>()
1215             | sum);
1216   EXPECT_THROW(from({"1", "a", "3"})
1217                 | guard<runtime_error>([](runtime_error&, const char* v) {
1218                     if (v[0] == 'a') {
1219                       throw;
1220                     }
1221                     return true;
1222                   })
1223                | eachTo<int>()
1224                | sum,
1225                runtime_error);
1226 }
1227
1228 TEST(Gen, Batch) {
1229   EXPECT_EQ((vector<vector<int>> { {1} }),
1230             seq(1, 1) | batch(5) | as<vector>());
1231   EXPECT_EQ((vector<vector<int>> { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11} }),
1232             seq(1, 11) | batch(3) | as<vector>());
1233   EXPECT_THROW(seq(1, 1) | batch(0) | as<vector>(),
1234                std::invalid_argument);
1235 }
1236
1237 TEST(Gen, BatchMove) {
1238   auto expected = vector<vector<int>>{ {0, 1}, {2, 3}, {4} };
1239   auto actual = seq(0, 4) |
1240       mapped([](int i) { return std::make_unique<int>(i); }) | batch(2) |
1241       mapped([](std::vector<std::unique_ptr<int>>& pVector) {
1242                   std::vector<int> iVector;
1243                   for (const auto& p : pVector) {
1244                     iVector.push_back(*p);
1245                   };
1246                   return iVector;
1247                 }) |
1248       as<vector>();
1249   EXPECT_EQ(expected, actual);
1250 }
1251
1252 TEST(Gen, Window) {
1253   auto expected = seq(0, 10) | as<std::vector>();
1254   for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1255     // no early stop
1256     auto actual = seq(0, 10) |
1257         mapped([](int i) { return std::make_unique<int>(i); }) | window(4) |
1258         dereference | as<std::vector>();
1259     EXPECT_EQ(expected, actual) << windowSize;
1260   }
1261   for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1262     // pre-window take
1263     auto actual = seq(0) |
1264         mapped([](int i) { return std::make_unique<int>(i); }) | take(11) |
1265         window(4) | dereference | as<std::vector>();
1266     EXPECT_EQ(expected, actual) << windowSize;
1267   }
1268   for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1269     // post-window take
1270     auto actual = seq(0) |
1271         mapped([](int i) { return std::make_unique<int>(i); }) | window(4) |
1272         take(11) | dereference | as<std::vector>();
1273     EXPECT_EQ(expected, actual) << windowSize;
1274   }
1275 }
1276
1277 TEST(Gen, Just) {
1278   {
1279     int x = 3;
1280     auto j = just(x);
1281     EXPECT_EQ(&x, j | indirect | first | unwrap);
1282     x = 4;
1283     EXPECT_EQ(4, j | sum);
1284   }
1285   {
1286     int x = 3;
1287     const int& cx = x;
1288     auto j = just(cx);
1289     EXPECT_EQ(&x, j | indirect | first | unwrap);
1290     x = 5;
1291     EXPECT_EQ(5, j | sum);
1292   }
1293   {
1294     int x = 3;
1295     auto j = just(std::move(x));
1296     EXPECT_NE(&x, j | indirect | first | unwrap);
1297     x = 5;
1298     EXPECT_EQ(3, j | sum);
1299   }
1300 }
1301
1302 TEST(Gen, GroupBy) {
1303   vector<string> strs{"zero", "one", "two",   "three", "four",
1304                       "five", "six", "seven", "eight", "nine"};
1305
1306   auto gb = from(strs) | groupBy([](const string& str) { return str.size(); });
1307
1308   EXPECT_EQ(10, gb | mapOp(count) | sum);
1309   EXPECT_EQ(3, gb | count);
1310
1311   vector<string> mode{"zero", "four", "five", "nine"};
1312   EXPECT_EQ(mode,
1313             gb | maxBy([](const Group<size_t, string>& g) { return g.size(); })
1314                | unwrap
1315                | as<vector>());
1316
1317   vector<string> largest{"three", "seven", "eight"};
1318   EXPECT_EQ(largest,
1319             gb | maxBy([](const Group<size_t, string>& g) { return g.key(); })
1320                | unwrap
1321                | as<vector>());
1322 }
1323
1324 TEST(Gen, Unwrap) {
1325   Optional<int> o(4);
1326   Optional<int> e;
1327   EXPECT_EQ(4, o | unwrap);
1328   EXPECT_THROW(e | unwrap, OptionalEmptyException);
1329
1330   auto oup = folly::make_optional(std::make_unique<int>(5));
1331   // optional has a value, and that value is non-null
1332   EXPECT_TRUE(bool(oup | unwrap));
1333   EXPECT_EQ(5, *(oup | unwrap));
1334   EXPECT_TRUE(oup.hasValue()); // still has a pointer (null or not)
1335   EXPECT_TRUE(bool(oup.value())); // that value isn't null
1336
1337   auto moved1 = std::move(oup) | unwrapOr(std::make_unique<int>(6));
1338   // oup still has a value, but now it's now nullptr since the pointer was moved
1339   // into moved1
1340   EXPECT_TRUE(oup.hasValue());
1341   EXPECT_FALSE(oup.value());
1342   EXPECT_TRUE(bool(moved1));
1343   EXPECT_EQ(5, *moved1);
1344
1345   auto moved2 = std::move(oup) | unwrapOr(std::make_unique<int>(7));
1346   // oup's still-valid nullptr value wins here, the pointer to 7 doesn't apply
1347   EXPECT_FALSE(moved2);
1348
1349   oup.clear();
1350   auto moved3 = std::move(oup) | unwrapOr(std::make_unique<int>(8));
1351   // oup is empty now, so the unwrapOr comes into play.
1352   EXPECT_TRUE(bool(moved3));
1353   EXPECT_EQ(8, *moved3);
1354
1355   {
1356   // mixed types, with common type matching optional
1357     Optional<double> full(3.3);
1358     decltype(full) empty;
1359     auto fallback = unwrapOr(4);
1360     EXPECT_EQ(3.3, full | fallback);
1361     EXPECT_EQ(3.3, std::move(full) | fallback);
1362     EXPECT_EQ(3.3, full | std::move(fallback));
1363     EXPECT_EQ(3.3, std::move(full) | std::move(fallback));
1364     EXPECT_EQ(4.0, empty | fallback);
1365     EXPECT_EQ(4.0, std::move(empty) | fallback);
1366     EXPECT_EQ(4.0, empty | std::move(fallback));
1367     EXPECT_EQ(4.0, std::move(empty) | std::move(fallback));
1368   }
1369
1370   {
1371   // mixed types, with common type matching fallback
1372     Optional<int> full(3);
1373     decltype(full) empty;
1374     auto fallback = unwrapOr(5.0); // type: double
1375     // if we chose 'int' as the common type, we'd see truncation here
1376     EXPECT_EQ(1.5, (full | fallback) / 2);
1377     EXPECT_EQ(1.5, (std::move(full) | fallback) / 2);
1378     EXPECT_EQ(1.5, (full | std::move(fallback)) / 2);
1379     EXPECT_EQ(1.5, (std::move(full) | std::move(fallback)) / 2);
1380     EXPECT_EQ(2.5, (empty | fallback) / 2);
1381     EXPECT_EQ(2.5, (std::move(empty) | fallback) / 2);
1382     EXPECT_EQ(2.5, (empty | std::move(fallback)) / 2);
1383     EXPECT_EQ(2.5, (std::move(empty) | std::move(fallback)) / 2);
1384   }
1385
1386   {
1387     auto opt = folly::make_optional(std::make_shared<int>(8));
1388     auto fallback = unwrapOr(std::make_unique<int>(9));
1389     // fallback must be std::move'd to be used
1390     EXPECT_EQ(8, *(opt | std::move(fallback)));
1391     EXPECT_TRUE(bool(opt.value())); // shared_ptr copied out, not moved
1392     EXPECT_TRUE(bool(opt)); // value still present
1393     EXPECT_TRUE(bool(fallback.value())); // fallback value not needed
1394
1395     EXPECT_EQ(8, *(std::move(opt) | std::move(fallback)));
1396     EXPECT_FALSE(opt.value()); // shared_ptr moved out
1397     EXPECT_TRUE(bool(opt)); // gutted value still present
1398     EXPECT_TRUE(bool(fallback.value())); // fallback value not needed
1399
1400     opt.clear();
1401
1402     EXPECT_FALSE(opt); // opt is empty now
1403     EXPECT_EQ(9, *(std::move(opt) | std::move(fallback)));
1404     EXPECT_FALSE(fallback.value()); // fallback moved out!
1405   }
1406
1407   {
1408     // test with nullptr
1409     vector<int> v{1, 2};
1410     EXPECT_EQ(&v[1], from(v) | indirect | max | unwrap);
1411     v.clear();
1412     EXPECT_FALSE(from(v) | indirect | max | unwrapOr(nullptr));
1413   }
1414
1415   {
1416     // mixed type determined by fallback
1417     Optional<std::nullptr_t> empty;
1418     int x = 3;
1419     EXPECT_EQ(&x, empty | unwrapOr(&x));
1420   }
1421 }
1422
1423 int main(int argc, char *argv[]) {
1424   testing::InitGoogleTest(&argc, argv);
1425   gflags::ParseCommandLineFlags(&argc, &argv, true);
1426   return RUN_ALL_TESTS();
1427 }