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