Commit 62cbd21f authored by Tom Jackson's avatar Tom Jackson Committed by Jordan DeLong

Simplifying GENERATOR to be like ScopeGuard

Summary:
It was previously breaking any time a generator included a comma, which
is pretty stupid. Now, it's modelled after `ScopeGuard`, using a little operator
overloading to get rid of the trailing `)` and sidestepping preprocessor issues.

Test Plan: Unit tests

Reviewed By: tudorb@fb.com

FB internal diff: D646825
parent 95ad385e
...@@ -135,6 +135,14 @@ Composed operator|(Operator<Left>&& left, ...@@ -135,6 +135,14 @@ Composed operator|(Operator<Left>&& left,
return Composed(std::move(left.self()), std::move(right.self())); return Composed(std::move(left.self()), std::move(right.self()));
} }
template<class Value,
class Source,
class Yield = detail::Yield<Value, Source>>
Yield operator+(const detail::GeneratorBuilder<Value>&,
Source&& source) {
return Yield(std::forward<Source>(source));
}
/** /**
* GenImpl - Core abstraction of a generator, an object which produces values by * GenImpl - Core abstraction of a generator, an object which produces values by
* passing them to a given handler lambda. All generator implementations must * passing them to a given handler lambda. All generator implementations must
......
...@@ -242,6 +242,9 @@ class CollectTemplate; ...@@ -242,6 +242,9 @@ class CollectTemplate;
template<class Collection> template<class Collection>
class Append; class Append;
template<class Value>
class GeneratorBuilder {};
} }
/** /**
...@@ -310,10 +313,14 @@ Yield generator(Source&& source) { ...@@ -310,10 +313,14 @@ Yield generator(Source&& source) {
return Yield(std::forward<Source>(source)); return Yield(std::forward<Source>(source));
} }
#define GENERATOR(type, body) \ /*
::folly::gen::generator<type>( \ * Create inline generator, used like:
[=](const std::function<void(type)>& yield) \ *
{ body }) * auto gen = GENERATOR(int) { yield(1); yield(2); };
*/
#define GENERATOR(TYPE) \
::folly::gen::detail::GeneratorBuilder<TYPE>() + \
[=](const std::function<void(TYPE)>& yield)
/* /*
* Operator Factories * Operator Factories
......
...@@ -403,7 +403,7 @@ TEST(Gen, Any) { ...@@ -403,7 +403,7 @@ TEST(Gen, Any) {
} }
TEST(Gen, Yielders) { TEST(Gen, Yielders) {
auto gen = GENERATOR(int, { auto gen = GENERATOR(int) {
for (int i = 1; i <= 5; ++i) { for (int i = 1; i <= 5; ++i) {
yield(i); yield(i);
} }
...@@ -411,7 +411,7 @@ TEST(Gen, Yielders) { ...@@ -411,7 +411,7 @@ TEST(Gen, Yielders) {
for (int i = 3; ; ++i) { for (int i = 3; ; ++i) {
yield(i * i); yield(i * i);
} }
}); };
vector<int> expected { vector<int> expected {
1, 2, 3, 4, 5, 7, 9, 16, 25 1, 2, 3, 4, 5, 7, 9, 16, 25
}; };
...@@ -419,30 +419,30 @@ TEST(Gen, Yielders) { ...@@ -419,30 +419,30 @@ TEST(Gen, Yielders) {
} }
TEST(Gen, NestedYield) { TEST(Gen, NestedYield) {
auto nums = GENERATOR(int, { auto nums = GENERATOR(int) {
for (int i = 1; ; ++i) { for (int i = 1; ; ++i) {
yield(i); yield(i);
} }
}); };
auto gen = GENERATOR(int, { auto gen = GENERATOR(int) {
nums | take(10) | yield; nums | take(10) | yield;
seq(1, 5) | [&](int i) { seq(1, 5) | [&](int i) {
yield(i); yield(i);
}; };
}); };
EXPECT_EQ(70, gen | sum); EXPECT_EQ(70, gen | sum);
} }
TEST(Gen, MapYielders) { TEST(Gen, MapYielders) {
auto gen = seq(1, 5) auto gen = seq(1, 5)
| map([](int n) { | map([](int n) {
return GENERATOR(int, { return GENERATOR(int) {
int i; int i;
for (i = 1; i < n; ++i) for (i = 1; i < n; ++i)
yield(i); yield(i);
for (; i >= 1; --i) for (; i >= 1; --i)
yield(i); yield(i);
}); };
}) })
| concat; | concat;
vector<int> expected { vector<int> expected {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment