2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <glog/logging.h>
25 #include <folly/FBVector.h>
26 #include <folly/MapUtil.h>
27 #include <folly/Memory.h>
28 #include <folly/String.h>
29 #include <folly/dynamic.h>
30 #include <folly/experimental/TestUtil.h>
31 #include <folly/gen/Base.h>
32 #include <folly/portability/GTest.h>
34 using namespace folly::gen;
35 using namespace folly;
36 using std::make_tuple;
42 using std::unique_ptr;
45 #define EXPECT_SAME(A, B) \
46 static_assert(std::is_same<A, B>::value, "Mismatched: " #A ", " #B)
47 EXPECT_SAME(int&&, typename ArgumentReference<int>::type);
48 EXPECT_SAME(int&, typename ArgumentReference<int&>::type);
49 EXPECT_SAME(const int&, typename ArgumentReference<const int&>::type);
50 EXPECT_SAME(const int&, typename ArgumentReference<const int>::type);
53 ostream& operator<<(ostream& os, const set<T>& values) {
54 return os << from(values);
58 ostream& operator<<(ostream& os, const vector<T>& values) {
60 for (auto& value : values) {
61 if (&value != &values.front()) {
69 auto square = [](int x) { return x * x; };
70 auto add = [](int a, int b) { return a + b; };
71 auto multiply = [](int a, int b) { return a * b; };
73 auto product = foldl(1, multiply);
75 template <typename A, typename B>
76 ostream& operator<<(ostream& os, const pair<A, B>& pair) {
77 return os << "(" << pair.first << ", " << pair.second << ")";
81 auto gen = seq(1, 10);
82 EXPECT_EQ(10, gen | count);
83 EXPECT_EQ(5, gen | take(5) | count);
87 auto gen = seq(1, 10);
88 EXPECT_EQ((1 + 10) * 10 / 2, gen | sum);
89 EXPECT_EQ((1 + 5) * 5 / 2, gen | take(5) | sum);
95 gen | [&](int x) { accum += x; };
98 gen | take(3) | [&](int x) { accum2 += x; };
103 auto expected = vector<int>{4, 9, 16};
104 auto gen = from({2, 3, 4}) | map(square);
105 EXPECT_EQ((vector<int>{4, 9, 16}), gen | as<vector>());
106 EXPECT_EQ((vector<int>{4, 9}), gen | take(2) | as<vector>());
111 Counter(int start = 0)
115 int count() const { return c; }
116 int incr() { return ++c; }
118 int& ref() { return c; }
119 const int& ref() const { return c; }
123 auto counters = seq(1, 10) | eachAs<Counter>() | as<vector>();
124 EXPECT_EQ(10 * (1 + 10) / 2,
126 | member(&Counter::count)
128 EXPECT_EQ(10 * (1 + 10) / 2,
131 | member(&Counter::count)
133 EXPECT_EQ(10 * (2 + 11) / 2,
135 | member(&Counter::incr)
137 EXPECT_EQ(10 * (3 + 12) / 2,
140 | member(&Counter::incr)
142 EXPECT_EQ(10 * (3 + 12) / 2,
144 | member(&Counter::count)
147 // type-verifications
148 auto m = empty<Counter&>();
149 auto c = empty<const Counter&>();
150 m | member(&Counter::incr) | assert_type<int&&>();
151 m | member(&Counter::count) | assert_type<int&&>();
152 m | member(&Counter::count) | assert_type<int&&>();
153 m | member<Const>(&Counter::ref) | assert_type<const int&>();
154 m | member<Mutable>(&Counter::ref) | assert_type<int&>();
155 c | member<Const>(&Counter::ref) | assert_type<const int&>();
160 X() : a(2), b(3), c(4), d(b) {}
165 int& d; // can't access this with a field pointer.
168 std::vector<X> xs(1);
169 EXPECT_EQ(2, from(xs)
172 EXPECT_EQ(3, from(xs)
175 EXPECT_EQ(4, from(xs)
178 EXPECT_EQ(2, seq(&xs[0], &xs[0])
182 empty<X&>() | field(&X::a) | assert_type<const int&>();
183 empty<X*>() | field(&X::a) | assert_type<const int&>();
184 empty<X&>() | field(&X::b) | assert_type<int&>();
185 empty<X*>() | field(&X::b) | assert_type<int&>();
186 empty<X&>() | field(&X::c) | assert_type<int&>();
187 empty<X*>() | field(&X::c) | assert_type<int&>();
189 empty<X&&>() | field(&X::a) | assert_type<const int&&>();
190 empty<X&&>() | field(&X::b) | assert_type<int&&>();
191 empty<X&&>() | field(&X::c) | assert_type<int&&>();
192 // references don't imply ownership so they're not moved
194 empty<const X&>() | field(&X::a) | assert_type<const int&>();
195 empty<const X*>() | field(&X::a) | assert_type<const int&>();
196 empty<const X&>() | field(&X::b) | assert_type<const int&>();
197 empty<const X*>() | field(&X::b) | assert_type<const int&>();
198 // 'mutable' has no effect on field pointers, by C++ spec
199 empty<const X&>() | field(&X::c) | assert_type<const int&>();
200 empty<const X*>() | field(&X::c) | assert_type<const int&>();
202 // can't form pointer-to-reference field: empty<X&>() | field(&X::d)
206 // cover the fenceposts of the loop unrolling
207 for (int n = 1; n < 100; ++n) {
208 EXPECT_EQ(n, seq(1, n) | count);
209 EXPECT_EQ(n + 1, seq(1) | take(n + 1) | count);
213 TEST(Gen, SeqWithStep) {
214 EXPECT_EQ(75, seq(5, 25, 5) | sum);
217 TEST(Gen, SeqWithStepArray) {
218 const std::array<int, 6> arr{{1, 2, 3, 4, 5, 6}};
219 EXPECT_EQ(9, seq(&arr[0], &arr[5], 2)
220 | map([](const int *i) { return *i; })
225 // cover the fenceposts of the loop unrolling
226 for (int n = 1; n < 100; ++n) {
227 EXPECT_EQ(gen::range(0, n) | count, n);
231 TEST(Gen, RangeWithStep) {
232 EXPECT_EQ(50, range(5, 25, 5) | sum);
235 TEST(Gen, FromIterators) {
236 vector<int> source {2, 3, 5, 7, 11};
237 auto gen = from(folly::range(source.begin() + 1, source.end() - 1));
238 EXPECT_EQ(3 * 5 * 7, gen | product);
242 auto source = seq(0, 10)
243 | map([](int i) { return std::make_pair(i, i * i); })
244 | as<std::map<int, int>>();
245 auto gen = fromConst(source)
246 | map([&](const std::pair<const int, int>& p) {
247 return p.second - p.first;
249 EXPECT_EQ(330, gen | sum);
253 const auto expected = vector<int>{1, 2, 4, 5, 7, 8};
256 | filter([](int x) { return x % 3; })
258 EXPECT_EQ(expected, actual);
261 TEST(Gen, FilterDefault) {
263 // Default filter should remove 0s
264 const auto expected = vector<int>{1, 1, 2, 3};
266 from({0, 1, 1, 0, 2, 3, 0})
269 EXPECT_EQ(expected, actual);
272 // Default filter should remove nullptrs
276 const auto expected = vector<int*>{&a, &b, &c};
278 from({(int*)nullptr, &a, &b, &c, (int*)nullptr})
281 EXPECT_EQ(expected, actual);
284 // Default filter on Optionals should remove folly::null
285 const auto expected =
286 vector<Optional<int>>{Optional<int>(5), Optional<int>(0)};
288 from({Optional<int>(5), Optional<int>(), Optional<int>(0)})
291 EXPECT_EQ(expected, actual);
295 TEST(Gen, FilterSink) {
298 | map([](int x) { return vector<int>{x}; })
299 | filter([](vector<int> v) { return !v.empty(); })
301 EXPECT_FALSE(from(actual) | rconcat | isEmpty);
304 TEST(Gen, Contains) {
309 EXPECT_TRUE(gen | contains(49));
310 EXPECT_FALSE(gen | contains(50));
314 seq(1) // infinite, to prove laziness
316 | eachTo<std::string>();
318 // std::string gen, const char* needle
319 EXPECT_TRUE(gen | take(9999) | contains("49"));
325 auto expected = vector<int>{1, 4, 9, 16};
328 | mapped([](int x) { return x * x; })
331 EXPECT_EQ(expected, actual);
334 auto expected = vector<int>{ 0, 1, 4, 5, 8 };
336 = ((seq(0) | take(2)) +
341 EXPECT_EQ(expected, actual);
344 auto expected = vector<int>{ 0, 1, 4, 5, 8 };
348 return seq(i * 4) | take(2);
353 EXPECT_EQ(expected, actual);
358 EXPECT_THROW(take(limit - 6), std::invalid_argument);
365 EXPECT_THROW(stride(0), std::invalid_argument);
368 auto expected = vector<int>{1, 2, 3, 4};
373 EXPECT_EQ(expected, actual);
376 auto expected = vector<int>{1, 3, 5, 7};
381 EXPECT_EQ(expected, actual);
384 auto expected = vector<int>{1, 4, 7, 10};
389 EXPECT_EQ(expected, actual);
392 auto expected = vector<int>{1, 3, 5, 7, 9, 1, 4, 7, 10};
394 = ((seq(1, 10) | stride(2)) +
395 (seq(1, 10) | stride(3)))
397 EXPECT_EQ(expected, actual);
399 EXPECT_EQ(500, seq(1) | take(1000) | stride(2) | count);
400 EXPECT_EQ(10, seq(1) | take(1000) | stride(2) | take(10) | count);
404 std::mt19937 rnd(42);
409 std::unordered_map<int,int> hits;
410 const int kNumIters = 80;
411 for (int i = 0; i < kNumIters; i++) {
412 auto vec = sampler | as<vector<int>>();
413 EXPECT_EQ(vec.size(), 50);
414 auto uniq = fromConst(vec) | as<set<int>>();
415 EXPECT_EQ(uniq.size(), vec.size()); // sampling without replacement
421 // In 80 separate samples of our range, we should have seen every value
422 // at least once and no value all 80 times. (The odds of either of those
423 // events is 1/2^80).
424 EXPECT_EQ(hits.size(), 100);
425 for (auto hit: hits) {
426 EXPECT_GT(hit.second, 0);
427 EXPECT_LT(hit.second, kNumIters);
433 EXPECT_EQ((small | sum), 15);
434 EXPECT_EQ((small | take(3) | count), 3);
440 | mapped([](int x) { return x * x; })
443 EXPECT_EQ((vector<int>{25, 36, 49, 64}), gen | as<vector>());
448 auto expected = vector<int>{1, 4, 9, 16};
451 | mapped([](int x) { return x * x; })
452 | until([](int x) { return x > 20; })
454 EXPECT_EQ(expected, actual);
457 auto expected = vector<int>{ 0, 1, 4, 5, 8 };
459 = ((seq(0) | until([](int i) { return i > 1; })) +
460 (seq(4) | until([](int i) { return i > 5; })) +
461 (seq(8) | until([](int i) { return i > 9; })))
462 | until([](int i) { return i > 8; })
464 EXPECT_EQ(expected, actual);
468 auto expected = vector<int>{ 0, 1, 5, 6, 10 };
472 return seq(i * 5) | until([=](int j) { return j > i * 5 + 1; });
475 | until([](int i) { return i > 10; })
477 EXPECT_EQ(expected, actual);
483 auto increment = [](int& i) { ++i; };
484 auto clone = map([](int i) { return i; });
487 auto actual = seq(0) | clone | visit(increment) | take(4) | sum;
488 EXPECT_EQ(expected, actual);
492 auto actual = seq(0, 3) | clone | visit(increment) | sum;
493 EXPECT_EQ(expected, actual);
496 std::vector<int> x2, x4;
497 std::vector<int> expected2{0, 1, 4, 9};
498 std::vector<int> expected4{0, 1, 16, 81};
500 auto tee = [](std::vector<int>& container) {
501 return visit([&](int value) { container.push_back(value); });
504 98, seq(0, 3) | map(square) | tee(x2) | map(square) | tee(x4) | sum);
505 EXPECT_EQ(expected2, x2);
506 EXPECT_EQ(expected4, x4);
510 TEST(Gen, Composed) {
511 // Operator, Operator
513 filter([](Optional<int>& o) { return o.hasValue(); })
514 | map([](Optional<int>& o) -> int& { return o.value(); });
515 std::vector<Optional<int>> opts {
516 none, 4, none, 6, none
518 EXPECT_EQ(4 * 4 + 6 * 6, from(opts) | valuesOf | map(square) | sum);
520 auto sumOpt = valuesOf | sum;
521 EXPECT_EQ(10, from(opts) | sumOpt);
525 std::vector<int> nums {2, 3, 5, 7};
526 std::map<int, int> mappings { { 3, 9}, {5, 25} };
527 auto gen = from(nums) + (from(mappings) | get<1>());
528 EXPECT_EQ(51, gen | sum);
529 EXPECT_EQ(5, gen | take(2) | sum);
530 EXPECT_EQ(26, gen | take(5) | sum);
534 std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
535 auto gen = from(nums) | rconcat;
536 EXPECT_EQ(17, gen | sum);
537 EXPECT_EQ(10, gen | take(3) | sum);
540 TEST(Gen, ConcatGen) {
541 auto gen = seq(1, 10)
542 | map([](int i) { return seq(1, i); })
544 EXPECT_EQ(220, gen | sum);
545 EXPECT_EQ(10, gen | take(6) | sum);
548 TEST(Gen, ConcatAlt) {
549 std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
550 auto actual = from(nums)
551 | map([](std::vector<int>& v) { return from(v); })
555 EXPECT_EQ(expected, actual);
559 auto expected = vector<int>{0, 3, 5, 6, 7, 8, 9};
561 from({8, 6, 7, 5, 3, 0, 9})
564 EXPECT_EQ(expected, actual);
567 TEST(Gen, OrderMoved) {
568 auto expected = vector<int>{0, 9, 25, 36, 49, 64, 81};
570 from({8, 6, 7, 5, 3, 0, 9})
575 EXPECT_EQ(expected, actual);
578 TEST(Gen, OrderTake) {
579 auto expected = vector<int>{9, 8, 7};
581 from({8, 6, 7, 5, 3, 0, 9})
582 | orderByDescending(square)
585 EXPECT_EQ(expected, actual);
588 TEST(Gen, Distinct) {
589 auto expected = vector<int>{3, 1, 2};
591 from({3, 1, 3, 2, 1, 2, 3})
594 EXPECT_EQ(expected, actual);
597 TEST(Gen, DistinctBy) { // 0 1 4 9 6 5 6 9 4 1 0
598 auto expected = vector<int>{0, 1, 2, 3, 4, 5};
601 | distinctBy([](int i) { return i * i % 10; })
603 EXPECT_EQ(expected, actual);
606 TEST(Gen, DistinctMove) { // 0 1 4 9 6 5 6 9 4 1 0
607 auto expected = vector<int>{0, 1, 2, 3, 4, 5};
608 auto actual = seq(0, 100) |
609 mapped([](int i) { return std::make_unique<int>(i); })
610 // see comment below about selector parameters for Distinct
611 | distinctBy([](const std::unique_ptr<int>& pi) {
612 return *pi * *pi % 10;
614 mapped([](std::unique_ptr<int> pi) { return *pi; }) | as<vector>();
616 // NOTE(tjackson): the following line intentionally doesn't work:
617 // | distinctBy([](std::unique_ptr<int> pi) { return *pi * *pi % 10; })
618 // This is because distinctBy because the selector intentionally requires a
619 // const reference. If it required a move-reference, the value might get
620 // gutted by the selector before said value could be passed to downstream
622 EXPECT_EQ(expected, actual);
625 TEST(Gen, DistinctInfinite) {
626 // distinct should be able to handle an infinite sequence, provided that, of
627 // of cource, is it eventually made finite before returning the result.
628 auto expected = seq(0) | take(5) | as<vector>(); // 0 1 2 3 4
631 seq(0) // 0 1 2 3 4 5 6 7 ...
632 | mapped([](int i) { return i / 2; }) // 0 0 1 1 2 2 3 3 ...
633 | distinct // 0 1 2 3 4 5 6 7 ...
634 | take(5) // 0 1 2 3 4
637 EXPECT_EQ(expected, actual);
640 TEST(Gen, DistinctByInfinite) {
641 // Similarly to the DistinctInfinite test case, distinct by should be able to
642 // handle infinite sequences. Note that depending on how many values we take()
643 // at the end, the sequence may infinite loop. This is fine becasue we cannot
644 // solve the halting problem.
645 auto expected = vector<int>{1, 2};
647 seq(1) // 1 2 3 4 5 6 7 8 ...
648 | distinctBy([](int i) { return i % 2; }) // 1 2 (but might by infinite)
651 // Note that if we had take(3), this would infinite loop
653 EXPECT_EQ(expected, actual);
657 EXPECT_EQ(7, seq(1, 10)
658 | minBy([](int i) -> double {
666 auto gen = from({"three", "eleven", "four"});
668 EXPECT_EQ("eleven", gen | maxBy(&strlen) | unwrap);
672 auto odds = seq(2,10) | filter([](int i){ return i % 2; });
674 EXPECT_EQ(3, odds | min);
678 auto odds = seq(2,10) | filter([](int i){ return i % 2; });
680 EXPECT_EQ(9, odds | max);
684 string expected = "facebook";
685 string actual = "face";
686 from(StringPiece("book")) | appendTo(actual);
687 EXPECT_EQ(expected, actual);
690 TEST(Gen, FromRValue) {
692 // AFAICT The C++ Standard does not specify what happens to the rvalue
693 // reference of a std::vector when it is used as the 'other' for an rvalue
694 // constructor. Use fbvector because we're sure its size will be zero in
696 fbvector<int> v({1, 2, 3, 4});
698 EXPECT_EQ(v.size(), 4); // ensure that the lvalue version was called!
699 auto expected = 1 * 2 * 3 * 4;
700 EXPECT_EQ(expected, q1 | product);
702 auto q2 = from(std::move(v));
703 EXPECT_EQ(v.size(), 0); // ensure that rvalue version was called
704 EXPECT_EQ(expected, q2 | product);
708 auto q = from([] { return vector<int>({3, 7, 5}); }());
709 EXPECT_EQ(expected, q | max);
712 for (auto size : {5, 1024, 16384, 1 << 20}) {
713 auto q1 = from(vector<int>(size, 2));
714 auto q2 = from(vector<int>(size, 3));
715 // If the rvalue specialization is broken/gone, then the compiler will
716 // (disgustingly!) just store a *reference* to the temporary object,
717 // which is bad. Try to catch this by allocating two temporary vectors
718 // of the same size, so that they'll probably use the same underlying
719 // buffer if q1's vector is destructed before q2's vector is constructed.
720 EXPECT_EQ(size * 2 + size * 3, (q1 | sum) + (q2 | sum));
724 auto q = from(set<int>{1,2,3,2,1});
725 EXPECT_EQ(q | sum, 6);
730 auto expected = vector<int>{5, 6, 4, 7, 3, 8, 2, 9, 1, 10};
733 | orderBy([](int x) { return (5.1 - x) * (5.1 - x); })
735 EXPECT_EQ(expected, actual);
737 expected = seq(1, 10) | as<vector>();
740 | map([] (int x) { return 11 - x; })
743 EXPECT_EQ(expected, actual);
747 int expected = 2 * 3 * 4 * 5;
750 | foldl(1, multiply);
751 EXPECT_EQ(expected, actual);
755 int expected = 2 + 3 + 4 + 5;
756 auto actual = seq(2, 5) | reduce(add);
757 EXPECT_EQ(expected, actual | unwrap);
760 TEST(Gen, ReduceBad) {
761 auto gen = seq(1) | take(0);
762 auto actual = gen | reduce(add);
763 EXPECT_FALSE(actual); // Empty sequences are okay, they just yeild 'none'
767 std::vector<unique_ptr<int>> ptrs;
768 ptrs.emplace_back(new int(1));
769 EXPECT_NE(ptrs.front().get(), nullptr);
770 auto ptrs2 = from(ptrs) | move | as<vector>();
771 EXPECT_EQ(ptrs.front().get(), nullptr);
772 EXPECT_EQ(**ptrs2.data(), 1);
776 auto gen = seq(0) | filter([](int x) { return x > 3; });
777 EXPECT_EQ(4, gen | first | unwrap);
780 TEST(Gen, FromCopy) {
781 vector<int> v {3, 5};
783 auto copy = fromCopy(v);
784 EXPECT_EQ(8, src | sum);
785 EXPECT_EQ(8, copy | sum);
787 EXPECT_EQ(10, src | sum);
788 EXPECT_EQ(8, copy | sum);
792 std::map<int, int> pairs {
798 auto pairSrc = from(pairs);
799 auto keys = pairSrc | get<0>();
800 auto values = pairSrc | get<1>();
801 EXPECT_EQ(10, keys | sum);
802 EXPECT_EQ(30, values | sum);
803 EXPECT_EQ(30, keys | map(square) | sum);
805 EXPECT_EQ(15, keys | sum);
806 EXPECT_EQ(55, values | sum);
808 vector<tuple<int, int, int>> tuples {
811 make_tuple(3, 9, 27),
813 EXPECT_EQ(36, from(tuples) | get<2>() | sum);
816 TEST(Gen, notEmpty) {
817 EXPECT_TRUE(seq(0, 1) | notEmpty);
818 EXPECT_TRUE(just(1) | notEmpty);
819 EXPECT_FALSE(gen::range(0, 0) | notEmpty);
820 EXPECT_FALSE(from({1}) | take(0) | notEmpty);
824 EXPECT_FALSE(seq(0, 1) | isEmpty);
825 EXPECT_FALSE(just(1) | isEmpty);
826 EXPECT_TRUE(gen::range(0, 0) | isEmpty);
827 EXPECT_TRUE(from({1}) | take(0) | isEmpty);
831 EXPECT_TRUE(seq(0, 10) | any([](int i) { return i == 7; }));
832 EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; }));
836 EXPECT_TRUE(seq(0, 10) | all([](int i) { return i < 11; }));
837 EXPECT_FALSE(seq(0, 10) | all([](int i) { return i < 5; }));
838 EXPECT_FALSE(seq(0) | take(9999) | all([](int i) { return i < 10; }));
840 // empty lists satisfies all
841 EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i < 50; }));
842 EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i > 50; }));
845 TEST(Gen, Yielders) {
846 auto gen = GENERATOR(int) {
847 for (int i = 1; i <= 5; ++i) {
851 for (int i = 3; ; ++i) {
855 vector<int> expected {
856 1, 2, 3, 4, 5, 7, 9, 16, 25
858 EXPECT_EQ(expected, gen | take(9) | as<vector>());
861 TEST(Gen, NestedYield) {
862 auto nums = GENERATOR(int) {
863 for (int i = 1; ; ++i) {
867 auto gen = GENERATOR(int) {
868 nums | take(10) | yield;
869 seq(1, 5) | [&](int i) {
873 EXPECT_EQ(70, gen | sum);
876 TEST(Gen, MapYielders) {
879 return GENERATOR(int) {
881 for (i = 1; i < n; ++i) {
884 for (; i >= 1; --i) {
890 vector<int> expected {
895 1, 2, 3, 4, 5, 4, 3, 2, 1,
897 EXPECT_EQ(expected, gen | as<vector>());
900 TEST(Gen, VirtualGen) {
901 VirtualGen<int> v(seq(1, 10));
902 EXPECT_EQ(55, v | sum);
904 EXPECT_EQ(385, v | sum);
906 EXPECT_EQ(55, v | sum);
907 EXPECT_EQ(30, v | take(4) | sum);
911 TEST(Gen, CustomType) {
915 auto gen = from({Foo{2}, Foo{3}})
916 | map([](const Foo& f) { return f.y; });
917 EXPECT_EQ(5, gen | sum);
920 TEST(Gen, NoNeedlessCopies) {
921 auto gen = seq(1, 5) | map([](int x) { return std::make_unique<int>(x); }) |
922 map([](unique_ptr<int> p) { return p; }) |
923 map([](unique_ptr<int>&& p) { return std::move(p); }) |
924 map([](const unique_ptr<int>& p) { return *p; });
925 EXPECT_EQ(15, gen | sum);
926 EXPECT_EQ(6, gen | take(3) | sum);
931 class TestIntSeq : public GenImpl<int, TestIntSeq> {
935 template <class Body>
936 bool apply(Body&& body) const {
937 for (int i = 1; i < 6; ++i) {
945 TestIntSeq(TestIntSeq&&) noexcept = default;
946 TestIntSeq& operator=(TestIntSeq&&) noexcept = default;
947 TestIntSeq(const TestIntSeq&) = delete;
948 TestIntSeq& operator=(const TestIntSeq&) = delete;
953 TEST(Gen, NoGeneratorCopies) {
954 EXPECT_EQ(15, TestIntSeq() | sum);
955 auto x = TestIntSeq() | take(3);
956 EXPECT_EQ(6, std::move(x) | sum);
959 TEST(Gen, FromArray) {
960 int source[] = {2, 3, 5, 7};
961 auto gen = from(source);
962 EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
965 TEST(Gen, FromStdArray) {
966 std::array<int,4> source {{2, 3, 5, 7}};
967 auto gen = from(source);
968 EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
971 TEST(Gen, StringConcat) {
972 auto gen = seq(1, 10)
975 EXPECT_EQ("12345678910", gen | as<string>());
983 CopyCounter() : copies(0), moves(0) {
987 CopyCounter(CopyCounter&& source) noexcept {
988 *this = std::move(source);
992 CopyCounter(const CopyCounter& source) {
1001 CopyCounter& operator=(const CopyCounter& source) {
1002 this->copies = source.copies + 1;
1003 this->moves = source.moves;
1007 CopyCounter& operator=(CopyCounter&& source) {
1008 this->copies = source.copies;
1009 this->moves = source.moves + 1;
1014 int CopyCounter::alive = 0;
1016 TEST(Gen, CopyCount) {
1017 vector<CopyCounter> originals;
1018 originals.emplace_back();
1019 EXPECT_EQ(1, originals.size());
1020 EXPECT_EQ(0, originals.back().copies);
1022 vector<CopyCounter> copies = from(originals) | as<vector>();
1023 EXPECT_EQ(1, copies.back().copies);
1024 EXPECT_EQ(0, copies.back().moves);
1026 vector<CopyCounter> moves = from(originals) | move | as<vector>();
1027 EXPECT_EQ(0, moves.back().copies);
1028 EXPECT_EQ(1, moves.back().moves);
1031 // test dynamics with various layers of nested arrays.
1032 TEST(Gen, Dynamic) {
1033 dynamic array1 = dynamic::array(1, 2);
1034 EXPECT_EQ(dynamic(3), from(array1) | sum);
1035 dynamic array2 = folly::dynamic::array(
1036 folly::dynamic::array(1), folly::dynamic::array(1, 2));
1037 EXPECT_EQ(dynamic(4), from(array2) | rconcat | sum);
1038 dynamic array3 = folly::dynamic::array(
1039 folly::dynamic::array(folly::dynamic::array(1)),
1040 folly::dynamic::array(
1041 folly::dynamic::array(1), folly::dynamic::array(1, 2)));
1042 EXPECT_EQ(dynamic(5), from(array3) | rconcat | rconcat | sum);
1045 TEST(Gen, DynamicObject) {
1046 const dynamic obj = dynamic::object(1, 2)(3, 4);
1047 EXPECT_EQ(dynamic(4), from(obj.keys()) | sum);
1048 EXPECT_EQ(dynamic(6), from(obj.values()) | sum);
1049 EXPECT_EQ(dynamic(4), from(obj.items()) | get<0>() | sum);
1050 EXPECT_EQ(dynamic(6), from(obj.items()) | get<1>() | sum);
1053 TEST(Gen, Collect) {
1054 auto s = from({7, 6, 5, 4, 3}) | as<set<int>>();
1055 EXPECT_EQ(s.size(), 5);
1061 auto s = from({1, 2});
1062 EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1063 s | cycle | take(5) | as<vector>());
1066 auto s = from({1, 2});
1067 EXPECT_EQ((vector<int> { 1, 2, 1, 2 }),
1068 s | cycle(2) | as<vector>());
1071 auto s = from({1, 2, 3});
1072 EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1073 s | take(2) | cycle | take(5) | as<vector>());
1076 auto s = empty<int>();
1077 EXPECT_EQ((vector<int> { }),
1078 s | cycle | take(4) | as<vector>());
1082 int* pcount = &count;
1083 auto countdown = GENERATOR(int) {
1084 ASSERT_GE(*pcount, 0)
1085 << "Cycle should have stopped when it didnt' get values!";
1086 for (int i = 1; i <= *pcount; ++i) {
1092 EXPECT_EQ((vector<int> { 1, 2, 3, 1, 2, 1}),
1093 s | cycle | take(7) | as<vector>());
1094 // take necessary as cycle returns an infinite generator
1098 TEST(Gen, Dereference) {
1100 const int x = 4, y = 2;
1101 auto s = from(std::initializer_list<const int*>({&x, nullptr, &y}));
1102 EXPECT_EQ(6, s | dereference | sum);
1105 vector<int> a { 1, 2 };
1106 vector<int> b { 3, 4 };
1107 vector<vector<int>*> pv { &a, nullptr, &b };
1110 | [&](vector<int>& v) {
1113 EXPECT_EQ(3, a.size());
1114 EXPECT_EQ(3, b.size());
1115 EXPECT_EQ(5, a.back());
1116 EXPECT_EQ(5, b.back());
1119 vector<std::map<int, int>> maps {
1136 | map([](std::map<int, int>& m) {
1137 return get_ptr(m, 3);
1143 vector<unique_ptr<int>> ups;
1144 ups.emplace_back(new int(3));
1146 ups.emplace_back(new int(7));
1147 EXPECT_EQ(10, from(ups) | dereference | sum);
1148 EXPECT_EQ(10, from(ups) | move | dereference | sum);
1153 struct DereferenceWrapper {
1155 string& operator*() & {
1158 string&& operator*() && {
1159 return std::move(data);
1161 explicit operator bool() {
1165 bool operator==(const DereferenceWrapper& a, const DereferenceWrapper& b) {
1166 return a.data == b.data;
1168 void PrintTo(const DereferenceWrapper& a, std::ostream* o) {
1169 *o << "Wrapper{\"" << cEscape<string>(a.data) << "\"}";
1173 TEST(Gen, DereferenceWithLValueRef) {
1174 auto original = vector<DereferenceWrapper>{{"foo"}, {"bar"}};
1175 auto copy = original;
1176 auto expected = vector<string>{"foo", "bar"};
1177 auto actual = from(original) | dereference | as<vector>();
1178 EXPECT_EQ(expected, actual);
1179 EXPECT_EQ(copy, original);
1182 TEST(Gen, DereferenceWithRValueRef) {
1183 auto original = vector<DereferenceWrapper>{{"foo"}, {"bar"}};
1184 auto empty = vector<DereferenceWrapper>{{}, {}};
1185 auto expected = vector<string>{"foo", "bar"};
1186 auto actual = from(original) | move | dereference | as<vector>();
1187 EXPECT_EQ(expected, actual);
1188 EXPECT_EQ(empty, original);
1191 TEST(Gen, Indirect) {
1193 EXPECT_EQ(&vs[0], from(vs) | indirect | first | unwrap);
1197 using std::runtime_error;
1198 EXPECT_THROW(from({"1", "a", "3"})
1203 from({"1", "a", "3"})
1204 | guard<runtime_error>([](runtime_error&, const char*) {
1205 return true; // continue
1210 from({"1", "a", "3"})
1211 | guard<runtime_error>([](runtime_error&, const char*) {
1212 return false; // break
1216 EXPECT_THROW(from({"1", "a", "3"})
1217 | guard<runtime_error>([](runtime_error&, const char* v) {
1229 EXPECT_EQ((vector<vector<int>> { {1} }),
1230 seq(1, 1) | batch(5) | as<vector>());
1231 EXPECT_EQ((vector<vector<int>> { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11} }),
1232 seq(1, 11) | batch(3) | as<vector>());
1233 EXPECT_THROW(seq(1, 1) | batch(0) | as<vector>(),
1234 std::invalid_argument);
1237 TEST(Gen, BatchMove) {
1238 auto expected = vector<vector<int>>{ {0, 1}, {2, 3}, {4} };
1239 auto actual = seq(0, 4) |
1240 mapped([](int i) { return std::make_unique<int>(i); }) | batch(2) |
1241 mapped([](std::vector<std::unique_ptr<int>>& pVector) {
1242 std::vector<int> iVector;
1243 for (const auto& p : pVector) {
1244 iVector.push_back(*p);
1249 EXPECT_EQ(expected, actual);
1253 auto expected = seq(0, 10) | as<std::vector>();
1254 for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1256 auto actual = seq(0, 10) |
1257 mapped([](int i) { return std::make_unique<int>(i); }) | window(4) |
1258 dereference | as<std::vector>();
1259 EXPECT_EQ(expected, actual) << windowSize;
1261 for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1263 auto actual = seq(0) |
1264 mapped([](int i) { return std::make_unique<int>(i); }) | take(11) |
1265 window(4) | dereference | as<std::vector>();
1266 EXPECT_EQ(expected, actual) << windowSize;
1268 for (size_t windowSize = 1; windowSize <= 20; ++windowSize) {
1270 auto actual = seq(0) |
1271 mapped([](int i) { return std::make_unique<int>(i); }) | window(4) |
1272 take(11) | dereference | as<std::vector>();
1273 EXPECT_EQ(expected, actual) << windowSize;
1281 EXPECT_EQ(&x, j | indirect | first | unwrap);
1283 EXPECT_EQ(4, j | sum);
1289 EXPECT_EQ(&x, j | indirect | first | unwrap);
1291 EXPECT_EQ(5, j | sum);
1295 auto j = just(std::move(x));
1296 EXPECT_NE(&x, j | indirect | first | unwrap);
1298 EXPECT_EQ(3, j | sum);
1302 TEST(Gen, GroupBy) {
1303 vector<string> strs{"zero", "one", "two", "three", "four",
1304 "five", "six", "seven", "eight", "nine"};
1306 auto gb = from(strs) | groupBy([](const string& str) { return str.size(); });
1308 EXPECT_EQ(10, gb | mapOp(count) | sum);
1309 EXPECT_EQ(3, gb | count);
1311 vector<string> mode{"zero", "four", "five", "nine"};
1313 gb | maxBy([](const Group<size_t, string>& g) { return g.size(); })
1317 vector<string> largest{"three", "seven", "eight"};
1319 gb | maxBy([](const Group<size_t, string>& g) { return g.key(); })
1327 EXPECT_EQ(4, o | unwrap);
1328 EXPECT_THROW(e | unwrap, OptionalEmptyException);
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
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
1340 EXPECT_TRUE(oup.hasValue());
1341 EXPECT_FALSE(oup.value());
1342 EXPECT_TRUE(bool(moved1));
1343 EXPECT_EQ(5, *moved1);
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);
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);
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));
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);
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
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
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!
1408 // test with nullptr
1409 vector<int> v{1, 2};
1410 EXPECT_EQ(&v[1], from(v) | indirect | max | unwrap);
1412 EXPECT_FALSE(from(v) | indirect | max | unwrapOr(nullptr));
1416 // mixed type determined by fallback
1417 Optional<std::nullptr_t> empty;
1419 EXPECT_EQ(&x, empty | unwrapOr(&x));
1423 int main(int argc, char *argv[]) {
1424 testing::InitGoogleTest(&argc, argv);
1425 gflags::ParseCommandLineFlags(&argc, &argv, true);
1426 return RUN_ALL_TESTS();