Simplifying GENERATOR to be like ScopeGuard
authorTom Jackson <tjackson@fb.com>
Tue, 4 Dec 2012 01:07:59 +0000 (17:07 -0800)
committerJordan DeLong <jdelong@fb.com>
Sun, 16 Dec 2012 22:46:27 +0000 (14:46 -0800)
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

folly/experimental/Gen-inl.h
folly/experimental/Gen.h
folly/experimental/test/GenTest.cpp

index 414ac66e6996f65d837eccdf5d74ec02eaf7f368..2721a63983a7e304508073259c77052653a3cbb5 100644 (file)
@@ -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
index 457c6e5c3bd2d7fd1d550419d3c1ff23a26b48d1..c02fee28989d4025237f55bd3e5d0052483ac889 100644 (file)
@@ -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
index 142678faee8e060c1d47044d833cb2fbb8a929ae..284a2c0930a52c0bdd27ea901d0b367d083bb01c 100644 (file)
@@ -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 {