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