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,
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
* passing them to a given handler lambda. All generator implementations must
......
......@@ -242,6 +242,9 @@ class CollectTemplate;
template<class Collection>
class Append;
template<class Value>
class GeneratorBuilder {};
}
/**
......@@ -310,10 +313,14 @@ Yield generator(Source&& source) {
return Yield(std::forward<Source>(source));
}
#define GENERATOR(type, body) \
::folly::gen::generator<type>( \
[=](const std::function<void(type)>& yield) \
{ body })
/*
* Create inline generator, used like:
*
* auto gen = GENERATOR(int) { yield(1); yield(2); };
*/
#define GENERATOR(TYPE) \
::folly::gen::detail::GeneratorBuilder<TYPE>() + \
[=](const std::function<void(TYPE)>& yield)
/*
* Operator Factories
......
......@@ -403,7 +403,7 @@ TEST(Gen, Any) {
}
TEST(Gen, Yielders) {
auto gen = GENERATOR(int, {
auto gen = GENERATOR(int) {
for (int i = 1; i <= 5; ++i) {
yield(i);
}
......@@ -411,7 +411,7 @@ TEST(Gen, Yielders) {
for (int i = 3; ; ++i) {
yield(i * i);
}
});
};
vector<int> expected {
1, 2, 3, 4, 5, 7, 9, 16, 25
};
......@@ -419,30 +419,30 @@ TEST(Gen, Yielders) {
}
TEST(Gen, NestedYield) {
auto nums = GENERATOR(int, {
auto nums = GENERATOR(int) {
for (int i = 1; ; ++i) {
yield(i);
}
});
auto gen = GENERATOR(int, {
};
auto gen = GENERATOR(int) {
nums | take(10) | yield;
seq(1, 5) | [&](int i) {
yield(i);
};
});
};
EXPECT_EQ(70, gen | sum);
}
TEST(Gen, MapYielders) {
auto gen = seq(1, 5)
| map([](int n) {
return GENERATOR(int, {
return GENERATOR(int) {
int i;
for (i = 1; i < n; ++i)
yield(i);
for (; i >= 1; --i)
yield(i);
});
};
})
| concat;
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