(Folly/Gen) Make ranges and sequences take a stepping functor
[folly.git] / folly / gen / test / BaseTest.cpp
1 /*
2  * Copyright 2014 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 * (2 + 11) / 2,
126             from(counters)
127           | member(&Counter::incr)
128           | sum);
129   EXPECT_EQ(10 * (2 + 11) / 2,
130             from(counters)
131           | member(&Counter::count)
132           | sum);
133
134   // type-verifications
135   auto m = empty<Counter&>();
136   auto c = empty<const Counter&>();
137   m | member(&Counter::incr) | assert_type<int&&>();
138   m | member(&Counter::count) | assert_type<int&&>();
139   m | member(&Counter::count) | assert_type<int&&>();
140   m | member<Const>(&Counter::ref) | assert_type<const int&>();
141   m | member<Mutable>(&Counter::ref) | assert_type<int&>();
142   c | member<Const>(&Counter::ref) | assert_type<const int&>();
143 }
144
145 TEST(Gen, Field) {
146   struct X {
147     X() : a(2), b(3), c(4), d(b) {}
148
149     const int a;
150     int b;
151     mutable int c;
152     int& d; // can't access this with a field pointer.
153   };
154
155   std::vector<X> xs(1);
156   EXPECT_EQ(2, from(xs)
157              | field(&X::a)
158              | first);
159   EXPECT_EQ(3, from(xs)
160              | field(&X::b)
161              | first);
162   EXPECT_EQ(4, from(xs)
163              | field(&X::c)
164              | first);
165   // type-verification
166   empty<X&>() | field(&X::a) | assert_type<const int&>();
167   empty<X&>() | field(&X::b) | assert_type<int&>();
168   empty<X&>() | field(&X::c) | assert_type<int&>();
169   empty<X&&>() | field(&X::a) | assert_type<const int&&>();
170   empty<X&&>() | field(&X::b) | assert_type<int&&>();
171   empty<X&&>() | field(&X::c) | assert_type<int&&>();
172   // references don't imply ownership so they're not moved
173   empty<const X&>() | field(&X::a) | assert_type<const int&>();
174   empty<const X&>() | field(&X::b) | assert_type<const int&>();
175   // 'mutable' has no effect on field pointers, by C++ spec
176   empty<const X&>() | field(&X::c) | assert_type<const int&>();
177
178   // can't form pointer-to-reference field: empty<X&>() | field(&X::d)
179 }
180
181 TEST(Gen, Seq) {
182   // cover the fenceposts of the loop unrolling
183   for (int n = 1; n < 100; ++n) {
184     EXPECT_EQ(n, seq(1, n) | count);
185     EXPECT_EQ(n + 1, seq(1) | take(n + 1) | count);
186   }
187 }
188
189 TEST(Gen, SeqWithStep) {
190   EXPECT_EQ(75, seq(5, 25, 5) | sum);
191 }
192
193 TEST(Gen, SeqWithStepArray) {
194   const std::array<int, 6> arr{{1, 2, 3, 4, 5, 6}};
195   EXPECT_EQ(9, seq(&arr[0], &arr[5], 2)
196              | map([](const int *i) { return *i; })
197              | sum);
198 }
199
200 TEST(Gen, Range) {
201   // cover the fenceposts of the loop unrolling
202   for (int n = 1; n < 100; ++n) {
203     EXPECT_EQ(gen::range(0, n) | count, n);
204   }
205 }
206
207 TEST(Gen, RangeWithStep) {
208   EXPECT_EQ(50, range(5, 25, 5) | sum);
209 }
210
211 TEST(Gen, FromIterators) {
212   vector<int> source {2, 3, 5, 7, 11};
213   auto gen = from(folly::range(source.begin() + 1, source.end() - 1));
214   EXPECT_EQ(3 * 5 * 7, gen | product);
215 }
216
217 TEST(Gen, FromMap) {
218   auto source = seq(0, 10)
219               | map([](int i) { return std::make_pair(i, i * i); })
220               | as<std::map<int, int>>();
221   auto gen = fromConst(source)
222            | map([&](const std::pair<const int, int>& p) {
223                return p.second - p.first;
224              });
225   EXPECT_EQ(330, gen | sum);
226 }
227
228 TEST(Gen, Filter) {
229   const auto expected = vector<int>{1, 2, 4, 5, 7, 8};
230   auto actual =
231       seq(1, 9)
232     | filter([](int x) { return x % 3; })
233     | as<vector<int>>();
234   EXPECT_EQ(expected, actual);
235 }
236
237 TEST(Gen, Contains) {
238   {
239     auto gen =
240         seq(1, 9)
241       | map(square);
242     EXPECT_TRUE(gen | contains(49));
243     EXPECT_FALSE(gen | contains(50));
244   }
245   {
246     auto gen =
247         seq(1) // infinite, to prove laziness
248       | map(square)
249       | eachTo<std::string>();
250
251     // std::string gen, const char* needle
252     EXPECT_TRUE(gen | take(9999) | contains("49"));
253   }
254 }
255
256 TEST(Gen, Take) {
257   {
258     auto expected = vector<int>{1, 4, 9, 16};
259     auto actual =
260       seq(1, 1000)
261       | mapped([](int x) { return x * x; })
262       | take(4)
263       | as<vector<int>>();
264     EXPECT_EQ(expected, actual);
265   }
266   {
267     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
268     auto actual
269       = ((seq(0) | take(2)) +
270          (seq(4) | take(2)) +
271          (seq(8) | take(2)))
272       | take(5)
273       | as<vector>();
274     EXPECT_EQ(expected, actual);
275   }
276   {
277     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
278     auto actual
279       = seq(0)
280       | mapped([](int i) {
281           return seq(i * 4) | take(2);
282         })
283       | concat
284       | take(5)
285       | as<vector>();
286     EXPECT_EQ(expected, actual);
287   }
288 }
289
290 TEST(Gen, Sample) {
291   std::mt19937 rnd(42);
292
293   auto sampler =
294       seq(1, 100)
295     | sample(50, rnd);
296   std::unordered_map<int,int> hits;
297   const int kNumIters = 80;
298   for (int i = 0; i < kNumIters; i++) {
299     auto vec = sampler | as<vector<int>>();
300     EXPECT_EQ(vec.size(), 50);
301     auto uniq = fromConst(vec) | as<set<int>>();
302     EXPECT_EQ(uniq.size(), vec.size());  // sampling without replacement
303     for (auto v: vec) {
304       ++hits[v];
305     }
306   }
307
308   // In 80 separate samples of our range, we should have seen every value
309   // at least once and no value all 80 times. (The odds of either of those
310   // events is 1/2^80).
311   EXPECT_EQ(hits.size(), 100);
312   for (auto hit: hits) {
313     EXPECT_GT(hit.second, 0);
314     EXPECT_LT(hit.second, kNumIters);
315   }
316
317   auto small =
318       seq(1, 5)
319     | sample(10);
320   EXPECT_EQ((small | sum), 15);
321   EXPECT_EQ((small | take(3) | count), 3);
322 }
323
324 TEST(Gen, Skip) {
325   auto gen =
326       seq(1, 1000)
327     | mapped([](int x) { return x * x; })
328     | skip(4)
329     | take(4);
330   EXPECT_EQ((vector<int>{25, 36, 49, 64}), gen | as<vector>());
331 }
332
333 TEST(Gen, Until) {
334   {
335     auto expected = vector<int>{1, 4, 9, 16};
336     auto actual
337       = seq(1, 1000)
338       | mapped([](int x) { return x * x; })
339       | until([](int x) { return x > 20; })
340       | as<vector<int>>();
341     EXPECT_EQ(expected, actual);
342   }
343   {
344     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
345     auto actual
346       = ((seq(0) | until([](int i) { return i > 1; })) +
347          (seq(4) | until([](int i) { return i > 5; })) +
348          (seq(8) | until([](int i) { return i > 9; })))
349       | until([](int i) { return i > 8; })
350       | as<vector<int>>();
351     EXPECT_EQ(expected, actual);
352   }
353   /*
354   {
355     auto expected = vector<int>{ 0, 1, 5, 6, 10 };
356     auto actual
357       = seq(0)
358       | mapped([](int i) {
359           return seq(i * 5) | until([=](int j) { return j > i * 5 + 1; });
360         })
361       | concat
362       | until([](int i) { return i > 10; })
363       | as<vector<int>>();
364     EXPECT_EQ(expected, actual);
365   }
366   */
367 }
368
369 TEST(Gen, Composed) {
370   // Operator, Operator
371   auto valuesOf =
372       filter([](Optional<int>& o) { return o.hasValue(); })
373     | map([](Optional<int>& o) -> int& { return o.value(); });
374   std::vector<Optional<int>> opts {
375     none, 4, none, 6, none
376   };
377   EXPECT_EQ(4 * 4 + 6 * 6, from(opts) | valuesOf | map(square) | sum);
378   // Operator, Sink
379   auto sumOpt = valuesOf | sum;
380   EXPECT_EQ(10, from(opts) | sumOpt);
381 }
382
383 TEST(Gen, Chain) {
384   std::vector<int> nums {2, 3, 5, 7};
385   std::map<int, int> mappings { { 3, 9}, {5, 25} };
386   auto gen = from(nums) + (from(mappings) | get<1>());
387   EXPECT_EQ(51, gen | sum);
388   EXPECT_EQ(5, gen | take(2) | sum);
389   EXPECT_EQ(26, gen | take(5) | sum);
390 }
391
392 TEST(Gen, Concat) {
393   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
394   auto gen = from(nums) | rconcat;
395   EXPECT_EQ(17, gen | sum);
396   EXPECT_EQ(10, gen | take(3) | sum);
397 }
398
399 TEST(Gen, ConcatGen) {
400   auto gen = seq(1, 10)
401            | map([](int i) { return seq(1, i); })
402            | concat;
403   EXPECT_EQ(220, gen | sum);
404   EXPECT_EQ(10, gen | take(6) | sum);
405 }
406
407 TEST(Gen, ConcatAlt) {
408   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
409   auto actual = from(nums)
410               | map([](std::vector<int>& v) { return from(v); })
411               | concat
412               | sum;
413   auto expected = 17;
414   EXPECT_EQ(expected, actual);
415 }
416
417 TEST(Gen, Order) {
418   auto expected = vector<int>{0, 3, 5, 6, 7, 8, 9};
419   auto actual =
420       from({8, 6, 7, 5, 3, 0, 9})
421     | order
422     | as<vector>();
423   EXPECT_EQ(expected, actual);
424 }
425
426 TEST(Gen, OrderMoved) {
427   auto expected = vector<int>{0, 9, 25, 36, 49, 64, 81};
428   auto actual =
429       from({8, 6, 7, 5, 3, 0, 9})
430     | move
431     | order
432     | map(square)
433     | as<vector>();
434   EXPECT_EQ(expected, actual);
435 }
436
437 TEST(Gen, OrderTake) {
438   auto expected = vector<int>{9, 8, 7};
439   auto actual =
440       from({8, 6, 7, 5, 3, 0, 9})
441     | orderByDescending(square)
442     | take(3)
443     | as<vector>();
444   EXPECT_EQ(expected, actual);
445 }
446
447 TEST(Gen, Distinct) {
448   auto expected = vector<int>{3, 1, 2};
449   auto actual =
450       from({3, 1, 3, 2, 1, 2, 3})
451     | distinct
452     | as<vector>();
453   EXPECT_EQ(expected, actual);
454 }
455
456 TEST(Gen, DistinctBy) {   //  0  1  4  9  6  5  6  9  4  1  0
457   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
458   auto actual =
459       seq(0, 100)
460     | distinctBy([](int i) { return i * i % 10; })
461     | as<vector>();
462   EXPECT_EQ(expected, actual);
463 }
464
465 TEST(Gen, DistinctMove) {   //  0  1  4  9  6  5  6  9  4  1  0
466   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
467   auto actual =
468       seq(0, 100)
469     | mapped([](int i) { return std::unique_ptr<int>(new int(i)); })
470       // see comment below about selector parameters for Distinct
471     | distinctBy([](const std::unique_ptr<int>& pi) { return *pi * *pi % 10; })
472     | mapped([](std::unique_ptr<int> pi) { return *pi; })
473     | as<vector>();
474
475   // NOTE(tjackson): the following line intentionally doesn't work:
476   //  | distinctBy([](std::unique_ptr<int> pi) { return *pi * *pi % 10; })
477   // This is because distinctBy because the selector intentionally requires a
478   // const reference.  If it required a move-reference, the value might get
479   // gutted by the selector before said value could be passed to downstream
480   // operators.
481   EXPECT_EQ(expected, actual);
482 }
483
484 TEST(Gen, MinBy) {
485   EXPECT_EQ(7, seq(1, 10)
486              | minBy([](int i) -> double {
487                  double d = i - 6.8;
488                  return d * d;
489                }));
490 }
491
492 TEST(Gen, MaxBy) {
493   auto gen = from({"three", "eleven", "four"});
494
495   EXPECT_EQ("eleven", gen | maxBy(&strlen));
496 }
497
498 TEST(Gen, Append) {
499   string expected = "facebook";
500   string actual = "face";
501   from(StringPiece("book")) | appendTo(actual);
502   EXPECT_EQ(expected, actual);
503 }
504
505 TEST(Gen, FromRValue) {
506   {
507     // AFAICT The C++ Standard does not specify what happens to the rvalue
508     // reference of a std::vector when it is used as the 'other' for an rvalue
509     // constructor.  Use fbvector because we're sure its size will be zero in
510     // this case.
511     fbvector<int> v({1,2,3,4});
512     auto q1 = from(v);
513     EXPECT_EQ(v.size(), 4);  // ensure that the lvalue version was called!
514     auto expected = 1 * 2 * 3 * 4;
515     EXPECT_EQ(expected, q1 | product);
516
517     auto q2 = from(std::move(v));
518     EXPECT_EQ(v.size(), 0);  // ensure that rvalue version was called
519     EXPECT_EQ(expected, q2 | product);
520   }
521   {
522     auto expected = 7;
523     auto q = from([] {return vector<int>({3,7,5}); }());
524     EXPECT_EQ(expected, q | max);
525   }
526   {
527     for (auto size: {5, 1024, 16384, 1<<20}) {
528       auto q1 = from(vector<int>(size, 2));
529       auto q2 = from(vector<int>(size, 3));
530       // If the rvalue specialization is broken/gone, then the compiler will
531       // (disgustingly!) just store a *reference* to the temporary object,
532       // which is bad.  Try to catch this by allocating two temporary vectors
533       // of the same size, so that they'll probably use the same underlying
534       // buffer if q1's vector is destructed before q2's vector is constructed.
535       EXPECT_EQ(size * 2 + size * 3, (q1 | sum) + (q2 | sum));
536     }
537   }
538   {
539     auto q = from(set<int>{1,2,3,2,1});
540     EXPECT_EQ(q | sum, 6);
541   }
542 }
543
544 TEST(Gen, OrderBy) {
545   auto expected = vector<int>{5, 6, 4, 7, 3, 8, 2, 9, 1, 10};
546   auto actual =
547       seq(1, 10)
548     | orderBy([](int x) { return (5.1 - x) * (5.1 - x); })
549     | as<vector>();
550   EXPECT_EQ(expected, actual);
551 }
552
553 TEST(Gen, Foldl) {
554   int expected = 2 * 3 * 4 * 5;
555   auto actual =
556       seq(2, 5)
557     | foldl(1, multiply);
558   EXPECT_EQ(expected, actual);
559 }
560
561 TEST(Gen, Reduce) {
562   int expected = 2 + 3 + 4 + 5;
563   auto actual = seq(2, 5) | reduce(add);
564   EXPECT_EQ(expected, actual);
565 }
566
567 TEST(Gen, ReduceBad) {
568   auto gen = seq(1) | take(0);
569   try {
570     EXPECT_TRUE(true);
571     gen | reduce(add);
572     EXPECT_TRUE(false);
573   } catch (...) {
574   }
575 }
576
577 TEST(Gen, Moves) {
578   std::vector<unique_ptr<int>> ptrs;
579   ptrs.emplace_back(new int(1));
580   EXPECT_NE(ptrs.front().get(), nullptr);
581   auto ptrs2 = from(ptrs) | move | as<vector>();
582   EXPECT_EQ(ptrs.front().get(), nullptr);
583   EXPECT_EQ(**ptrs2.data(), 1);
584 }
585
586 TEST(Gen, First) {
587   auto gen =
588       seq(0)
589     | filter([](int x) { return x > 3; });
590   EXPECT_EQ(4, gen | first);
591 }
592
593 TEST(Gen, FromCopy) {
594   vector<int> v {3, 5};
595   auto src = from(v);
596   auto copy = fromCopy(v);
597   EXPECT_EQ(8, src | sum);
598   EXPECT_EQ(8, copy | sum);
599   v[1] = 7;
600   EXPECT_EQ(10, src | sum);
601   EXPECT_EQ(8, copy | sum);
602 }
603
604 TEST(Gen, Get) {
605   std::map<int, int> pairs {
606     {1, 1},
607     {2, 4},
608     {3, 9},
609     {4, 16},
610   };
611   auto pairSrc = from(pairs);
612   auto keys = pairSrc | get<0>();
613   auto values = pairSrc | get<1>();
614   EXPECT_EQ(10, keys | sum);
615   EXPECT_EQ(30, values | sum);
616   EXPECT_EQ(30, keys | map(square) | sum);
617   pairs[5] = 25;
618   EXPECT_EQ(15, keys | sum);
619   EXPECT_EQ(55, values | sum);
620
621   vector<tuple<int, int, int>> tuples {
622     make_tuple(1, 1, 1),
623     make_tuple(2, 4, 8),
624     make_tuple(3, 9, 27),
625   };
626   EXPECT_EQ(36, from(tuples) | get<2>() | sum);
627 }
628
629 TEST(Gen, Any) {
630   EXPECT_TRUE(seq(0) | any);
631   EXPECT_TRUE(seq(0, 1) | any);
632   EXPECT_TRUE(seq(0, 10) | any([](int i) { return i == 7; }));
633   EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; }));
634
635   EXPECT_TRUE(from({1}) | any);
636   EXPECT_FALSE(gen::range(0, 0) | any);
637   EXPECT_FALSE(from({1}) | take(0) | any);
638 }
639
640 TEST(Gen, All) {
641   EXPECT_TRUE(seq(0, 10) | all([](int i) { return i < 11; }));
642   EXPECT_FALSE(seq(0, 10) | all([](int i) { return i < 5; }));
643   EXPECT_FALSE(seq(0) | take(9999) | all([](int i) { return i < 10; }));
644
645   // empty lists satisfies all
646   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i < 50; }));
647   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i > 50; }));
648 }
649
650 TEST(Gen, Yielders) {
651   auto gen = GENERATOR(int) {
652     for (int i = 1; i <= 5; ++i) {
653       yield(i);
654     }
655     yield(7);
656     for (int i = 3; ; ++i) {
657       yield(i * i);
658     }
659   };
660   vector<int> expected {
661     1, 2, 3, 4, 5, 7, 9, 16, 25
662   };
663   EXPECT_EQ(expected, gen | take(9) | as<vector>());
664 }
665
666 TEST(Gen, NestedYield) {
667   auto nums = GENERATOR(int) {
668     for (int i = 1; ; ++i) {
669       yield(i);
670     }
671   };
672   auto gen = GENERATOR(int) {
673     nums | take(10) | yield;
674     seq(1, 5) | [&](int i) {
675       yield(i);
676     };
677   };
678   EXPECT_EQ(70, gen | sum);
679 }
680
681 TEST(Gen, MapYielders) {
682   auto gen = seq(1, 5)
683            | map([](int n) {
684                return GENERATOR(int) {
685                  int i;
686                  for (i = 1; i < n; ++i)
687                    yield(i);
688                  for (; i >= 1; --i)
689                    yield(i);
690                };
691              })
692            | concat;
693   vector<int> expected {
694                 1,
695              1, 2, 1,
696           1, 2, 3, 2, 1,
697        1, 2, 3, 4, 3, 2, 1,
698     1, 2, 3, 4, 5, 4, 3, 2, 1,
699   };
700   EXPECT_EQ(expected, gen | as<vector>());
701 }
702
703 TEST(Gen, VirtualGen) {
704   VirtualGen<int> v(seq(1, 10));
705   EXPECT_EQ(55, v | sum);
706   v = v | map(square);
707   EXPECT_EQ(385, v | sum);
708   v = v | take(5);
709   EXPECT_EQ(55, v | sum);
710   EXPECT_EQ(30, v | take(4) | sum);
711 }
712
713
714 TEST(Gen, CustomType) {
715   struct Foo{
716     int y;
717   };
718   auto gen = from({Foo{2}, Foo{3}})
719            | map([](const Foo& f) { return f.y; });
720   EXPECT_EQ(5, gen | sum);
721 }
722
723 TEST(Gen, NoNeedlessCopies) {
724   auto gen = seq(1, 5)
725            | map([](int x) { return unique_ptr<int>(new int(x)); })
726            | map([](unique_ptr<int> p) { return p; })
727            | map([](unique_ptr<int>&& p) { return std::move(p); })
728            | map([](const unique_ptr<int>& p) { return *p; });
729   EXPECT_EQ(15, gen | sum);
730   EXPECT_EQ(6, gen | take(3) | sum);
731 }
732
733 namespace {
734
735 class TestIntSeq : public GenImpl<int, TestIntSeq> {
736  public:
737   TestIntSeq() { }
738
739   template <class Body>
740   bool apply(Body&& body) const {
741     for (int i = 1; i < 6; ++i) {
742       if (!body(i)) {
743         return false;
744       }
745     }
746     return true;
747   }
748
749   TestIntSeq(TestIntSeq&&) = default;
750   TestIntSeq& operator=(TestIntSeq&&) = default;
751   TestIntSeq(const TestIntSeq&) = delete;
752   TestIntSeq& operator=(const TestIntSeq&) = delete;
753 };
754
755 }  // namespace
756
757 TEST(Gen, NoGeneratorCopies) {
758   EXPECT_EQ(15, TestIntSeq() | sum);
759   auto x = TestIntSeq() | take(3);
760   EXPECT_EQ(6, std::move(x) | sum);
761 }
762
763 TEST(Gen, FromArray) {
764   int source[] = {2, 3, 5, 7};
765   auto gen = from(source);
766   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
767 }
768
769 TEST(Gen, FromStdArray) {
770   std::array<int,4> source {{2, 3, 5, 7}};
771   auto gen = from(source);
772   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
773 }
774
775 TEST(Gen, StringConcat) {
776   auto gen = seq(1, 10)
777            | eachTo<string>()
778            | rconcat;
779   EXPECT_EQ("12345678910", gen | as<string>());
780 }
781
782 struct CopyCounter {
783   static int alive;
784   int copies;
785   int moves;
786
787   CopyCounter() : copies(0), moves(0) {
788     ++alive;
789   }
790
791   CopyCounter(CopyCounter&& source) {
792     *this = std::move(source);
793     ++alive;
794   }
795
796   CopyCounter(const CopyCounter& source) {
797     *this = source;
798     ++alive;
799   }
800
801   ~CopyCounter() {
802     --alive;
803   }
804
805   CopyCounter& operator=(const CopyCounter& source) {
806     this->copies = source.copies + 1;
807     this->moves = source.moves;
808     return *this;
809   }
810
811   CopyCounter& operator=(CopyCounter&& source) {
812     this->copies = source.copies;
813     this->moves = source.moves + 1;
814     return *this;
815   }
816 };
817
818 int CopyCounter::alive = 0;
819
820 TEST(Gen, CopyCount) {
821   vector<CopyCounter> originals;
822   originals.emplace_back();
823   EXPECT_EQ(1, originals.size());
824   EXPECT_EQ(0, originals.back().copies);
825
826   vector<CopyCounter> copies = from(originals) | as<vector>();
827   EXPECT_EQ(1, copies.back().copies);
828   EXPECT_EQ(0, copies.back().moves);
829
830   vector<CopyCounter> moves = from(originals) | move | as<vector>();
831   EXPECT_EQ(0, moves.back().copies);
832   EXPECT_EQ(1, moves.back().moves);
833 }
834
835 // test dynamics with various layers of nested arrays.
836 TEST(Gen, Dynamic) {
837   dynamic array1 = {1, 2};
838   EXPECT_EQ(dynamic(3), from(array1) | sum);
839   dynamic array2 = {{1}, {1, 2}};
840   EXPECT_EQ(dynamic(4), from(array2) | rconcat | sum);
841   dynamic array3 = {{{1}}, {{1}, {1, 2}}};
842   EXPECT_EQ(dynamic(5), from(array3) | rconcat | rconcat | sum);
843 }
844
845 TEST(Gen, DynamicObject) {
846   const dynamic obj = dynamic::object(1, 2)(3, 4);
847   EXPECT_EQ(dynamic(4), from(obj.keys()) | sum);
848   EXPECT_EQ(dynamic(6), from(obj.values()) | sum);
849   EXPECT_EQ(dynamic(4), from(obj.items()) | get<0>() | sum);
850   EXPECT_EQ(dynamic(6), from(obj.items()) | get<1>() | sum);
851 }
852
853 TEST(Gen, Collect) {
854   auto s = from({7, 6, 5, 4, 3}) | as<set<int>>();
855   EXPECT_EQ(s.size(), 5);
856 }
857
858
859 TEST(Gen, Cycle) {
860   {
861     auto s = from({1, 2});
862     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
863               s | cycle | take(5) | as<vector>());
864   }
865   {
866     auto s = from({1, 2});
867     EXPECT_EQ((vector<int> { 1, 2, 1, 2 }),
868               s | cycle(2) | as<vector>());
869   }
870   {
871     auto s = from({1, 2, 3});
872     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
873               s | take(2) | cycle | take(5) | as<vector>());
874   }
875   {
876     auto s = empty<int>();
877     EXPECT_EQ((vector<int> { }),
878               s | cycle | take(4) | as<vector>());
879   }
880   {
881     int count = 3;
882     int* pcount = &count;
883     auto countdown = GENERATOR(int) {
884       ASSERT_GE(*pcount, 0)
885         << "Cycle should have stopped when it didnt' get values!";
886       for (int i = 1; i <= *pcount; ++i) {
887         yield(i);
888       }
889       --*pcount;
890     };
891     auto s = countdown;
892     EXPECT_EQ((vector<int> { 1, 2, 3, 1, 2, 1}),
893               s | cycle | as<vector>());
894   }
895 }
896
897 TEST(Gen, Dereference) {
898   {
899     const int x = 4, y = 2;
900     auto s = from(std::initializer_list<const int*>({&x, nullptr, &y}));
901     EXPECT_EQ(6, s | dereference | sum);
902   }
903   {
904     vector<int> a { 1, 2 };
905     vector<int> b { 3, 4 };
906     vector<vector<int>*> pv { &a, nullptr, &b };
907     from(pv)
908       | dereference
909       | [&](vector<int>& v) {
910           v.push_back(5);
911         };
912     EXPECT_EQ(3, a.size());
913     EXPECT_EQ(3, b.size());
914     EXPECT_EQ(5, a.back());
915     EXPECT_EQ(5, b.back());
916   }
917   {
918     vector<std::map<int, int>> maps {
919       {
920         { 2, 31 },
921         { 3, 41 },
922       },
923       {
924         { 3, 52 },
925         { 4, 62 },
926       },
927       {
928         { 4, 73 },
929         { 5, 83 },
930       },
931     };
932     EXPECT_EQ(
933       93,
934       from(maps)
935       | map([](std::map<int, int>& m) {
936           return get_ptr(m, 3);
937         })
938       | dereference
939       | sum);
940   }
941   {
942     vector<unique_ptr<int>> ups;
943     ups.emplace_back(new int(3));
944     ups.emplace_back();
945     ups.emplace_back(new int(7));
946     EXPECT_EQ(10, from(ups) | dereference | sum);
947     EXPECT_EQ(10, from(ups) | move | dereference | sum);
948   }
949 }
950
951 TEST(Gen, Guard) {
952   using std::runtime_error;
953   EXPECT_THROW(from({"1", "a", "3"})
954                | eachTo<int>()
955                | sum,
956                runtime_error);
957   EXPECT_EQ(4,
958             from({"1", "a", "3"})
959             | guard<runtime_error>([](runtime_error&, const char*) {
960                 return true; // continue
961               })
962             | eachTo<int>()
963             | sum);
964   EXPECT_EQ(1,
965             from({"1", "a", "3"})
966             | guard<runtime_error>([](runtime_error&, const char*) {
967                 return false; // break
968               })
969             | eachTo<int>()
970             | sum);
971   EXPECT_THROW(from({"1", "a", "3"})
972                 | guard<runtime_error>([](runtime_error&, const char* v) {
973                     if (v[0] == 'a') {
974                       throw;
975                     }
976                     return true;
977                   })
978                | eachTo<int>()
979                | sum,
980                runtime_error);
981 }
982
983 TEST(Gen, Batch) {
984   EXPECT_EQ((vector<vector<int>> { {1} }),
985             seq(1, 1) | batch(5) | as<vector>());
986   EXPECT_EQ((vector<vector<int>> { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11} }),
987             seq(1, 11) | batch(3) | as<vector>());
988   EXPECT_THROW(seq(1, 1) | batch(0) | as<vector>(),
989                std::invalid_argument);
990 }
991
992 TEST(Gen, BatchMove) {
993   auto expected = vector<vector<int>>{ {0, 1}, {2, 3}, {4} };
994   auto actual =
995       seq(0, 4)
996     | mapped([](int i) { return std::unique_ptr<int>(new int(i)); })
997     | batch(2)
998     | mapped([](std::vector<std::unique_ptr<int>>& pVector) {
999         std::vector<int> iVector;
1000         for (const auto& p : pVector) {
1001           iVector.push_back(*p);
1002         };
1003         return iVector;
1004       })
1005     | as<vector>();
1006   EXPECT_EQ(expected, actual);
1007 }
1008
1009 int main(int argc, char *argv[]) {
1010   testing::InitGoogleTest(&argc, argv);
1011   google::ParseCommandLineFlags(&argc, &argv, true);
1012   return RUN_ALL_TESTS();
1013 }