dereference
[folly.git] / folly / experimental / Gen-inl.h
index 5079ae227cb25dc8820db663f09fc0e69828fa6c..7a752d0feffb25718ab0a6bbf609903c539f17d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
+// Ignore shadowing warnings within this file, so includers can use -Wshadow.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+
 namespace folly { namespace gen {
 
 /**
@@ -155,9 +159,11 @@ class GenImpl : public FBounded<Self> {
   typedef typename std::decay<Value>::type StorageType;
 
   /**
-   * apply() - Send all values produced by this generator to given
-   * handler until it returns false. Returns true if the false iff the handler
-   * returned false.
+   * apply() - Send all values produced by this generator to given handler until
+   * the handler returns false. Returns false if and only if the handler passed
+   * in returns false. Note: It should return true even if it completes (without
+   * the handler returning false), as 'Chain' uses the return value of apply to
+   * determine if it should process the second object in its chain.
    */
   template<class Handler>
   bool apply(Handler&& handler) const;
@@ -167,11 +173,17 @@ class GenImpl : public FBounded<Self> {
    */
   template<class Body>
   void foreach(Body&& body) const {
-    this->self().apply([&](Value value) {
+    this->self().apply([&](Value value) -> bool {
+        static_assert(!infinite, "Cannot call foreach on infinite GenImpl");
         body(std::forward<Value>(value));
         return true;
       });
   }
+
+  // Child classes should override if the sequence generated is *definitely*
+  // infinite. 'infinite' may be false_type for some infinite sequences
+  // (due the the Halting Problem).
+  static constexpr bool infinite = false;
 };
 
 template<class LeftValue,
@@ -236,6 +248,8 @@ template<class Value,
 typename std::enable_if<
   IsCompatibleSignature<Handler, void(Value)>::value>::type
 operator|(const GenImpl<Value, Gen>& gen, Handler&& handler) {
+  static_assert(!Gen::infinite,
+                "Cannot pull all values from an infinite sequence.");
   gen.self().foreach(std::forward<Handler>(handler));
 }
 
@@ -247,9 +261,9 @@ template<class Value,
          class Gen,
          class Handler>
 typename std::enable_if<
-  IsCompatibleSignature<Handler, bool(Value)>::value>::type
+  IsCompatibleSignature<Handler, bool(Value)>::value, bool>::type
 operator|(const GenImpl<Value, Gen>& gen, Handler&& handler) {
-  gen.self().apply(std::forward<Handler>(handler));
+  return gen.self().apply(std::forward<Handler>(handler));
 }
 
 /**
@@ -261,7 +275,7 @@ template<class Value,
          class Gen,
          class Op>
 auto operator|(const GenImpl<Value, Gen>& gen, const Operator<Op>& op) ->
-decltype(op.self().compose(gen)) {
+decltype(op.self().compose(gen.self())) {
   return op.self().compose(gen.self());
 }
 
@@ -291,7 +305,7 @@ template<class Container,
          class Value>
 class ReferencedSource :
     public GenImpl<Value, ReferencedSource<Container, Value>> {
-  Container* const container_;
+  Container* container_;
 public:
   explicit ReferencedSource(Container* container)
     : container_(container) {}
@@ -344,7 +358,7 @@ class CopiedSource :
   static_assert(
     !std::is_reference<Container>::value,
     "Can't copy into a reference");
-  const std::shared_ptr<const Container> copy_;
+  std::shared_ptr<const Container> copy_;
 public:
   typedef Container ContainerType;
 
@@ -400,13 +414,14 @@ class Sequence : public GenImpl<const Value&,
                 !std::is_const<Value>::value, "Value mustn't be const or ref.");
   Value bounds_[endless ? 1 : 2];
 public:
-  explicit Sequence(const Value& begin)
-      : bounds_{begin} {
+  explicit Sequence(Value begin)
+      : bounds_{std::move(begin)} {
     static_assert(endless, "Must supply 'end'");
   }
 
-  explicit Sequence(const Value& begin, const Value& end)
-    : bounds_{begin, end} {}
+  Sequence(Value begin,
+           Value end)
+    : bounds_{std::move(begin), std::move(end)} {}
 
   template<class Handler>
   bool apply(Handler&& handler) const {
@@ -438,6 +453,8 @@ public:
       body(arg);
     }
   }
+
+  static constexpr bool infinite = endless;
 };
 
 /**
@@ -451,8 +468,8 @@ public:
 template<class Value, class First, class Second>
 class Chain : public GenImpl<Value,
                              Chain<Value, First, Second>> {
-  const First first_;
-  const Second second_;
+  First first_;
+  Second second_;
 public:
   explicit Chain(First first, Second second)
       : first_(std::move(first))
@@ -469,6 +486,20 @@ public:
     first_.foreach(std::forward<Body>(body));
     second_.foreach(std::forward<Body>(body));
   }
+
+  static constexpr bool infinite = First::infinite || Second::infinite;
+};
+
+/**
+ * GenratorBuilder - Helper for GENERTATOR macro.
+ **/
+template<class Value>
+struct GeneratorBuilder {
+  template<class Source,
+           class Yield = detail::Yield<Value, Source>>
+  Yield operator+(Source&& source) {
+    return Yield(std::forward<Source>(source));
+  }
 };
 
 /**
@@ -477,7 +508,7 @@ public:
  **/
 template<class Value, class Source>
 class Yield : public GenImpl<Value, Yield<Value, Source>> {
-  const Source source_;
+  Source source_;
  public:
   explicit Yield(Source source)
     : source_(std::move(source)) {
@@ -505,6 +536,12 @@ class Yield : public GenImpl<Value, Yield<Value, Source>> {
   }
 };
 
+template<class Value>
+class Empty : public GenImpl<Value, Empty<Value>> {
+ public:
+  template<class Handler>
+  bool apply(Handler&&) const { return true; }
+};
 
 /*
  * Operators
@@ -520,10 +557,12 @@ class Yield : public GenImpl<Value, Yield<Value, Source>> {
  */
 template<class Predicate>
 class Map : public Operator<Map<Predicate>> {
-  const Predicate predicate_;
+  Predicate pred_;
  public:
-  explicit Map(const Predicate& predicate = Predicate())
-    : predicate_(predicate)
+  Map() {}
+
+  explicit Map(Predicate pred)
+    : pred_(std::move(pred))
   { }
 
   template<class Value,
@@ -533,8 +572,8 @@ class Map : public Operator<Map<Predicate>> {
                           >::type>
   class Generator :
       public GenImpl<Result, Generator<Value, Source, Result>> {
-    const Source source_;
-    const Predicate pred_;
+    Source source_;
+    Predicate pred_;
   public:
     explicit Generator(Source source, const Predicate& pred)
       : source_(std::move(source)), pred_(pred) {}
@@ -552,20 +591,22 @@ class Map : public Operator<Map<Predicate>> {
         return handler(pred_(std::forward<Value>(value)));
       });
     }
+
+    static constexpr bool infinite = Source::infinite;
   };
 
   template<class Source,
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
-    return Gen(std::move(source.self()), predicate_);
+    return Gen(std::move(source.self()), pred_);
   }
 
   template<class Source,
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self(), predicate_);
+    return Gen(source.self(), pred_);
   }
 };
 
@@ -582,17 +623,18 @@ class Map : public Operator<Map<Predicate>> {
  */
 template<class Predicate>
 class Filter : public Operator<Filter<Predicate>> {
-  const Predicate predicate_;
+  Predicate pred_;
  public:
-  explicit Filter(const Predicate& predicate)
-    : predicate_(predicate)
+  Filter() {}
+  explicit Filter(Predicate pred)
+    : pred_(std::move(pred))
   { }
 
   template<class Value,
            class Source>
   class Generator : public GenImpl<Value, Generator<Value, Source>> {
-    const Source source_;
-    const Predicate pred_;
+    Source source_;
+    Predicate pred_;
   public:
     explicit Generator(Source source, const Predicate& pred)
       : source_(std::move(source)), pred_(pred) {}
@@ -615,20 +657,22 @@ class Filter : public Operator<Filter<Predicate>> {
         return true;
       });
     }
+
+    static constexpr bool infinite = Source::infinite;
   };
 
   template<class Source,
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
-    return Gen(std::move(source.self()), predicate_);
+    return Gen(std::move(source.self()), pred_);
   }
 
   template<class Source,
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self(), predicate_);
+    return Gen(source.self(), pred_);
   }
 };
 
@@ -643,29 +687,36 @@ class Filter : public Operator<Filter<Predicate>> {
  */
 template<class Predicate>
 class Until : public Operator<Until<Predicate>> {
-  const Predicate predicate_;
+  Predicate pred_;
  public:
-  explicit Until(const Predicate& predicate)
-    : predicate_(predicate)
-  { }
+  Until() {}
+  explicit Until(Predicate pred)
+    : pred_(std::move(pred))
+  {}
 
   template<class Value,
-           class Source,
-           class Result = typename std::result_of<Predicate(Value)>::type>
-  class Generator :
-      public GenImpl<Result, Generator<Value, Source, Result>> {
-    const Source source_;
-    const Predicate pred_;
-  public:
+           class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
+    Source source_;
+    Predicate pred_;
+   public:
     explicit Generator(Source source, const Predicate& pred)
       : source_(std::move(source)), pred_(pred) {}
 
     template<class Handler>
     bool apply(Handler&& handler) const {
-      return source_.apply([&](Value value) -> bool {
-        return !pred_(std::forward<Value>(value))
-            && handler(std::forward<Value>(value));
+      bool cancelled = false;
+      source_.apply([&](Value value) -> bool {
+        if (pred_(value)) { // un-forwarded to disable move
+          return false;
+        }
+        if (!handler(std::forward<Value>(value))) {
+          cancelled = true;
+          return false;
+        }
+        return true;
       });
+      return !cancelled;
     }
   };
 
@@ -673,15 +724,18 @@ class Until : public Operator<Until<Predicate>> {
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
-    return Gen(std::move(source.self()), predicate_);
+    return Gen(std::move(source.self()), pred_);
   }
 
   template<class Source,
            class Value,
            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self(), predicate_);
+    return Gen(source.self(), pred_);
   }
+
+  // Theoretically an 'until' might stop an infinite
+  static constexpr bool infinite = false;
 };
 
 /**
@@ -694,8 +748,8 @@ class Until : public Operator<Until<Predicate>> {
  *             | take(10);
  */
 class Take : public Operator<Take> {
-  const size_t count_;
-public:
+  size_t count_;
+ public:
   explicit Take(size_t count)
     : count_(count) {}
 
@@ -703,8 +757,8 @@ public:
            class Source>
   class Generator :
       public GenImpl<Value, Generator<Value, Source>> {
-    const Source source_;
-    const size_t count_;
+    Source source_;
+    size_t count_;
   public:
     explicit Generator(Source source, size_t count)
       : source_(std::move(source)) , count_(count) {}
@@ -713,12 +767,15 @@ public:
     bool apply(Handler&& handler) const {
       if (count_ == 0) { return false; }
       size_t n = count_;
-      return source_.apply([&](Value value) -> bool {
-          if (!handler(std::forward<Value>(value))) {
-            return false;
-          }
-          return --n;
-        });
+      bool cancelled = false;
+      source_.apply([&](Value value) -> bool {
+        if (!handler(std::forward<Value>(value))) {
+          cancelled = true;
+          return false;
+        }
+        return --n;
+      });
+      return !cancelled;
     }
   };
 
@@ -737,6 +794,84 @@ public:
   }
 };
 
+/**
+ * Sample - For taking a random sample of N elements from a sequence
+ * (without replacement).
+ */
+template<class Random>
+class Sample : public Operator<Sample<Random>> {
+  size_t count_;
+  Random rng_;
+ public:
+  explicit Sample(size_t count, Random rng)
+    : count_(count), rng_(std::move(rng)) {}
+
+  template<class Value,
+           class Source,
+           class Rand,
+           class StorageType = typename std::decay<Value>::type>
+  class Generator :
+          public GenImpl<StorageType&&,
+                         Generator<Value, Source, Rand, StorageType>> {
+    static_assert(!Source::infinite, "Cannot sample infinite source!");
+    // It's too easy to bite ourselves if random generator is only 16-bit
+    static_assert(Random::max() >= std::numeric_limits<int32_t>::max() - 1,
+                  "Random number generator must support big values");
+    Source source_;
+    size_t count_;
+    mutable Rand rng_;
+  public:
+    explicit Generator(Source source, size_t count, Random rng)
+      : source_(std::move(source)) , count_(count), rng_(std::move(rng)) {}
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      if (count_ == 0) { return false; }
+      std::vector<StorageType> v;
+      v.reserve(count_);
+      // use reservoir sampling to give each source value an equal chance
+      // of appearing in our output.
+      size_t n = 1;
+      source_.foreach([&](Value value) -> void {
+          if (v.size() < count_) {
+            v.push_back(std::forward<Value>(value));
+          } else {
+            // alternatively, we could create a std::uniform_int_distribution
+            // instead of using modulus, but benchmarks show this has
+            // substantial overhead.
+            size_t index = rng_() % n;
+            if (index < v.size()) {
+              v[index] = std::forward<Value>(value);
+            }
+          }
+          ++n;
+        });
+
+      // output is unsorted!
+      for (auto& val: v) {
+        if (!handler(std::move(val))) {
+          return false;
+        }
+      }
+      return true;
+    }
+  };
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source, Random>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()), count_, rng_);
+  }
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source, Random>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self(), count_, rng_);
+  }
+};
+
 /**
  * Skip - For skipping N items from the beginning of a source generator.
  *
@@ -747,8 +882,8 @@ public:
  *             | take(10);
  */
 class Skip : public Operator<Skip> {
-  const size_t count_;
-public:
+  size_t count_;
+ public:
   explicit Skip(size_t count)
     : count_(count) {}
 
@@ -756,9 +891,9 @@ public:
            class Source>
   class Generator :
       public GenImpl<Value, Generator<Value, Source>> {
-    const Source source_;
-    const size_t count_;
-  public:
+    Source source_;
+    size_t count_;
+   public:
     explicit Generator(Source source, size_t count)
       : source_(std::move(source)) , count_(count) {}
 
@@ -781,7 +916,7 @@ public:
     template<class Handler>
     bool apply(Handler&& handler) const {
       if (count_ == 0) {
-        return source_.apply(handler);
+        return source_.apply(std::forward<Handler>(handler));
       }
       size_t n = 0;
       return source_.apply([&](Value value) -> bool {
@@ -792,6 +927,8 @@ public:
           return handler(std::forward<Value>(value));
         });
     }
+
+    static constexpr bool infinite = Source::infinite;
   };
 
   template<class Source,
@@ -824,12 +961,20 @@ public:
  */
 template<class Selector, class Comparer>
 class Order : public Operator<Order<Selector, Comparer>> {
-  const Selector selector_;
-  const Comparer comparer_;
+  Selector selector_;
+  Comparer comparer_;
  public:
-  Order(const Selector& selector = Selector(),
-        const Comparer& comparer = Comparer())
-    : selector_(selector) , comparer_(comparer) {}
+  Order() {}
+
+  explicit Order(Selector selector)
+    : selector_(std::move(selector))
+  {}
+
+  Order(Selector selector,
+        Comparer comparer)
+    : selector_(std::move(selector))
+    , comparer_(std::move(comparer))
+  {}
 
   template<class Value,
            class Source,
@@ -838,9 +983,10 @@ class Order : public Operator<Order<Selector, Comparer>> {
   class Generator :
     public GenImpl<StorageType&&,
                    Generator<Value, Source, StorageType, Result>> {
-    const Source source_;
-    const Selector selector_;
-    const Comparer comparer_;
+    static_assert(!Source::infinite, "Cannot sort infinite source!");
+    Source source_;
+    Selector selector_;
+    Comparer comparer_;
 
     typedef std::vector<StorageType> VectorType;
 
@@ -854,11 +1000,11 @@ class Order : public Operator<Order<Selector, Comparer>> {
     }
    public:
     Generator(Source source,
-              const Selector& selector,
-              const Comparer& comparer)
+              Selector selector,
+              Comparer comparer)
       : source_(std::move(source)),
-        selector_(selector),
-        comparer_(comparer) {}
+        selector_(std::move(selector)),
+        comparer_(std::move(comparer)) {}
 
     VectorType operator|(const Collect<VectorType>&) const {
       return asVector();
@@ -909,6 +1055,190 @@ class Order : public Operator<Order<Selector, Comparer>> {
   }
 };
 
+/*
+ * TypeAssertion - For verifying the exact type of the value produced by a
+ * generator. Useful for testing and debugging, and acts as a no-op at runtime.
+ * Pass-through at runtime. Used through the 'assert_type<>()' factory method
+ * like so:
+ *
+ *   auto c =  from(vector) | assert_type<int&>() | sum;
+ *
+ */
+template<class Expected>
+class TypeAssertion : public Operator<TypeAssertion<Expected>> {
+ public:
+  template<class Source, class Value>
+  const Source& compose(const GenImpl<Value, Source>& source) const {
+    static_assert(std::is_same<Expected, Value>::value,
+                  "assert_type() check failed");
+    return source.self();
+  }
+
+  template<class Source, class Value>
+  Source&& compose(GenImpl<Value, Source>&& source) const {
+    static_assert(std::is_same<Expected, Value>::value,
+                  "assert_type() check failed");
+    return std::move(source.self());
+  }
+};
+
+/**
+ * Distinct - For filtering duplicates out of a sequence. A selector may be
+ * provided to generate a key to uniquify for each value.
+ *
+ * This type is usually used through the 'distinct' helper function, like:
+ *
+ *   auto closest = from(results)
+ *                | distinctBy([](Item& i) {
+ *                    return i.target;
+ *                  })
+ *                | take(10);
+ */
+template<class Selector>
+class Distinct : public Operator<Distinct<Selector>> {
+  Selector selector_;
+ public:
+  Distinct() {}
+
+  explicit Distinct(Selector selector)
+    : selector_(std::move(selector))
+  {}
+
+  template<class Value,
+           class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
+    Source source_;
+    Selector selector_;
+
+    typedef typename std::decay<Value>::type StorageType;
+
+    // selector_ cannot be passed an rvalue or it would end up passing the husk
+    // of a value to the downstream operators.
+    typedef const StorageType& ParamType;
+
+    typedef typename std::result_of<Selector(ParamType)>::type KeyType;
+    typedef typename std::decay<KeyType>::type KeyStorageType;
+
+   public:
+    Generator(Source source,
+              Selector selector)
+      : source_(std::move(source)),
+        selector_(std::move(selector)) {}
+
+    template<class Body>
+    void foreach(Body&& body) const {
+      std::unordered_set<KeyStorageType> keysSeen;
+      source_.foreach([&](Value value) {
+        if (keysSeen.insert(selector_(ParamType(value))).second) {
+          body(std::forward<Value>(value));
+        }
+      });
+    }
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      std::unordered_set<KeyStorageType> keysSeen;
+      return source_.apply([&](Value value) -> bool {
+        if (keysSeen.insert(selector_(ParamType(value))).second) {
+          return handler(std::forward<Value>(value));
+        }
+        return true;
+      });
+    }
+  };
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()), selector_);
+  }
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self(), selector_);
+  }
+};
+
+/**
+ * Batch - For producing fixed-size batches of each value from a source.
+ *
+ * This type is usually used through the 'batch' helper function:
+ *
+ *   auto batchSums
+ *     = seq(1, 10)
+ *     | batch(3)
+ *     | map([](const std::vector<int>& batch) {
+ *         return from(batch) | sum;
+ *       })
+ *     | as<vector>();
+ */
+class Batch : public Operator<Batch> {
+  size_t batchSize_;
+ public:
+  explicit Batch(size_t batchSize)
+    : batchSize_(batchSize) {
+    if (batchSize_ == 0) {
+      throw std::invalid_argument("Batch size must be non-zero!");
+    }
+  }
+
+  template<class Value,
+           class Source,
+           class StorageType = typename std::decay<Value>::type,
+           class VectorType = std::vector<StorageType>>
+  class Generator :
+      public GenImpl<VectorType&,
+                     Generator<Value, Source, StorageType, VectorType>> {
+    Source source_;
+    size_t batchSize_;
+  public:
+    explicit Generator(Source source, size_t batchSize)
+      : source_(std::move(source))
+      , batchSize_(batchSize) {}
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      VectorType batch_;
+      batch_.reserve(batchSize_);
+      bool shouldContinue = source_.apply([&](Value value) -> bool {
+          batch_.push_back(std::forward<Value>(value));
+          if (batch_.size() == batchSize_) {
+            bool needMore = handler(batch_);
+            batch_.clear();
+            return needMore;
+          }
+          // Always need more if the handler is not called.
+          return true;
+        });
+      // Flush everything, if and only if `handler` hasn't returned false.
+      if (shouldContinue && !batch_.empty()) {
+        shouldContinue = handler(batch_);
+        batch_.clear();
+      }
+      return shouldContinue;
+    }
+
+    static constexpr bool infinite = Source::infinite;
+  };
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()), batchSize_);
+  }
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self(), batchSize_);
+  }
+};
+
 /**
  * Composed - For building up a pipeline of operations to perform, absent any
  * particular source generator. Useful for building up custom pipelines.
@@ -923,13 +1253,14 @@ class Order : public Operator<Order<Selector, Comparer>> {
 template<class First,
          class Second>
 class Composed : public Operator<Composed<First, Second>> {
-  const First first_;
-  const Second second_;
-  public:
-    Composed() {}
-    Composed(First first, Second second)
-      : first_(std::move(first))
-      , second_(std::move(second)) {}
+  First first_;
+  Second second_;
+ public:
+  Composed() {}
+
+  Composed(First first, Second second)
+    : first_(std::move(first))
+    , second_(std::move(second)) {}
 
   template<class Source,
            class Value,
@@ -971,17 +1302,20 @@ class Composed : public Operator<Composed<First, Second>> {
 template<class Seed,
          class Fold>
 class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
-  const Seed seed_;
-  const Fold fold_;
+  Seed seed_;
+  Fold fold_;
  public:
-  FoldLeft(const Seed& seed, const Fold& fold)
-    : seed_(seed)
-    , fold_(fold)
+  FoldLeft() {}
+  FoldLeft(Seed seed,
+           Fold fold)
+    : seed_(std::move(seed))
+    , fold_(std::move(fold))
   {}
 
   template<class Source,
            class Value>
   Seed compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot foldl infinite source");
     Seed accum = seed_;
     source | [&](Value v) {
       accum = fold_(std::move(accum), std::forward<Value>(v));
@@ -999,11 +1333,12 @@ class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
  */
 class First : public Operator<First> {
  public:
+  First() { }
+
   template<class Source,
            class Value,
            class StorageType = typename std::decay<Value>::type>
   StorageType compose(const GenImpl<Value, Source>& source) const {
-    static_assert(std::is_same<StorageType, int>::value, "wtf");
     Optional<StorageType> accum;
     source | [&](Value v) -> bool {
       accum = std::forward<Value>(v);
@@ -1018,14 +1353,21 @@ class First : public Operator<First> {
 
 
 /**
- * Any - For determining whether any values are contained in a sequence.
+ * Any - For determining whether any values in a sequence satisfy a predicate.
  *
  * This type is primarily used through the 'any' static value, like:
  *
  *   bool any20xPrimes = seq(200, 210) | filter(isPrime) | any;
+ *
+ * Note that it may also be used like so:
+ *
+ *   bool any20xPrimes = seq(200, 210) | any(isPrime);
+ *
  */
 class Any : public Operator<Any> {
  public:
+  Any() { }
+
   template<class Source,
            class Value>
   bool compose(const GenImpl<Value, Source>& source) const {
@@ -1036,6 +1378,52 @@ class Any : public Operator<Any> {
     };
     return any;
   }
+
+  /**
+   * Convenience function for use like:
+   *
+   *  bool found = gen | any([](int i) { return i * i > 100; });
+   */
+  template<class Predicate,
+           class Filter = Filter<Predicate>,
+           class Composed = Composed<Filter, Any>>
+  Composed operator()(Predicate pred) const {
+    return Composed(Filter(std::move(pred)), Any());
+  }
+};
+
+/**
+ * All - For determining whether all values in a sequence satisfy a predicate.
+ *
+ * This type is primarily used through the 'any' static value, like:
+ *
+ *   bool valid = from(input) | all(validate);
+ *
+ * Note: Passing an empty sequence through 'all()' will always return true.
+ */
+template<class Predicate>
+class All : public Operator<All<Predicate>> {
+  Predicate pred_;
+ public:
+  All() {}
+  explicit All(Predicate pred)
+    : pred_(std::move(pred))
+  { }
+
+  template<class Source,
+           class Value>
+  bool compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot call 'all' on infinite source");
+    bool all = true;
+    source | [&](Value v) -> bool {
+      if (!pred_(std::forward<Value>(v))) {
+        all = false;
+        return false;
+      }
+      return true;
+    };
+    return all;
+  }
 };
 
 /**
@@ -1052,10 +1440,11 @@ class Any : public Operator<Any> {
  */
 template<class Reducer>
 class Reduce : public Operator<Reduce<Reducer>> {
-  const Reducer reducer_;
+  Reducer reducer_;
  public:
-  Reduce(const Reducer& reducer)
-    : reducer_(reducer)
+  Reduce() {}
+  explicit Reduce(Reducer reducer)
+    : reducer_(std::move(reducer))
   {}
 
   template<class Source,
@@ -1086,9 +1475,12 @@ class Reduce : public Operator<Reduce<Reducer>> {
  */
 class Count : public Operator<Count> {
  public:
+  Count() { }
+
   template<class Source,
            class Value>
   size_t compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot count infinite source");
     return foldl(size_t(0),
                  [](size_t accum, Value v) {
                    return accum + 1;
@@ -1105,10 +1497,13 @@ class Count : public Operator<Count> {
  */
 class Sum : public Operator<Sum> {
  public:
+  Sum() : Operator<Sum>() {}
+
   template<class Source,
            class Value,
            class StorageType = typename std::decay<Value>::type>
   StorageType compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot sum infinite source");
     return foldl(StorageType(0),
                  [](StorageType&& accum, Value v) {
                    return std::move(accum) + std::forward<Value>(v);
@@ -1116,6 +1511,35 @@ class Sum : public Operator<Sum> {
   }
 };
 
+/**
+ * Contains - For testing whether a value matching the given value is contained
+ * in a sequence.
+ *
+ * This type should be used through the 'contains' helper method, like:
+ *
+ *   bool contained = seq(1, 10) | map(square) | contains(49);
+ */
+template<class Needle>
+class Contains : public Operator<Contains<Needle>> {
+  Needle needle_;
+ public:
+  explicit Contains(Needle needle)
+    : needle_(std::move(needle))
+  {}
+
+  template<class Source,
+           class Value,
+           class StorageType = typename std::decay<Value>::type>
+  bool compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite,
+                  "Calling contains on an infinite source might cause "
+                  "an infinite loop.");
+    return !(source | [this](Value value) {
+        return !(needle_ == std::forward<Value>(value));
+      });
+  }
+};
+
 /**
  * Min - For a value which minimizes a key, where the key is determined by a
  * given selector, and compared by given comparer.
@@ -1134,10 +1558,16 @@ class Min : public Operator<Min<Selector, Comparer>> {
   Selector selector_;
   Comparer comparer_;
  public:
-  Min(const Selector& selector = Selector(),
-      const Comparer& comparer = Comparer())
-    : selector_(selector)
-    , comparer_(comparer)
+  Min() {}
+
+  explicit Min(Selector selector)
+    : selector_(std::move(selector))
+  {}
+
+  Min(Selector selector,
+        Comparer comparer)
+    : selector_(std::move(selector))
+    , comparer_(std::move(comparer))
   {}
 
   template<class Value,
@@ -1175,7 +1605,7 @@ class Min : public Operator<Min<Selector, Comparer>> {
  */
 template<class Collection>
 class Append : public Operator<Append<Collection>> {
-  Collection* const collection_;
+  Collection* collection_;
  public:
   explicit Append(Collection* collection)
     : collection_(collection)
@@ -1204,6 +1634,8 @@ class Append : public Operator<Append<Collection>> {
 template<class Collection>
 class Collect : public Operator<Collect<Collection>> {
  public:
+  Collect() { }
+
   template<class Value,
            class Source,
            class StorageType = typename std::decay<Value>::type>
@@ -1236,6 +1668,8 @@ template<template<class, class> class Container,
          template<class> class Allocator>
 class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
  public:
+  CollectTemplate() { }
+
   template<class Value,
            class Source,
            class StorageType = typename std::decay<Value>::type,
@@ -1248,6 +1682,7 @@ class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
     return collection;
   }
 };
+
 /**
  * Concat - For flattening generators of generators.
  *
@@ -1265,14 +1700,16 @@ class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
  *     | as<std::set>();
  */
 class Concat : public Operator<Concat> {
-public:
+ public:
+  Concat() { }
+
   template<class Inner,
            class Source,
            class InnerValue = typename std::decay<Inner>::type::ValueType>
   class Generator :
       public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
-    const Source source_;
-  public:
+    Source source_;
+   public:
     explicit Generator(Source source)
       : source_(std::move(source)) {}
 
@@ -1289,6 +1726,8 @@ public:
           inner.foreach(std::forward<Body>(body));
         });
     }
+
+    static constexpr bool infinite = Source::infinite;
   };
 
   template<class Value,
@@ -1307,7 +1746,7 @@ public:
 };
 
 /**
- * RangeConcat - For flattening generators of generators.
+ * RangeConcat - For flattening generators of iterables.
  *
  * This type is usually used through the 'rconcat' static value, like:
  *
@@ -1319,13 +1758,15 @@ public:
  *     | as<std::set>();
  */
 class RangeConcat : public Operator<RangeConcat> {
-public:
-  template<class Source,
-           class Range,
+ public:
+  RangeConcat() { }
+
+  template<class Range,
+           class Source,
            class InnerValue = typename ValueTypeOfRange<Range>::RefType>
   class Generator
-    : public GenImpl<InnerValue, Generator<Source, Range, InnerValue>> {
-    const Source source_;
+    : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
+    Source source_;
    public:
     explicit Generator(Source source)
       : source_(std::move(source)) {}
@@ -1341,7 +1782,7 @@ public:
 
     template<class Handler>
     bool apply(Handler&& handler) const {
-      return source_.apply([&](Range range) {
+      return source_.apply([&](Range range) -> bool {
           for (auto& value : range) {
             if (!handler(value)) {
               return false;
@@ -1354,32 +1795,229 @@ public:
 
   template<class Value,
            class Source,
-           class Gen = Generator<Source, Value>>
+           class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()));
   }
 
   template<class Value,
            class Source,
-           class Gen = Generator<Source, Value>>
+           class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self());
   }
 };
 
-} //::detail
 
 /**
- * Gen<T> - For wrapping template types in simple polymorphic wrapper.
+ * GuardImpl - For handling exceptions from downstream computation. Requires the
+ * type of exception to catch, and handler function to invoke in the event of
+ * the exception. Note that the handler may:
+ *   1) return true to continue processing the sequence
+ *   2) return false to end the sequence immediately
+ *   3) throw, to pass the exception to the next catch
+ * The handler must match the signature 'bool(Exception&, Value)'.
  *
- * This type is usually used through the 'rconcat' static value, like:
+ * This type is used through the `guard` helper, like so:
  *
- *   map<int, vector<int>> adjacency;
- *   auto sinks =
- *       from(adjacency)
- *     | get<1>()
- *     | rconcat()
- *     | as<std::set>();
+ *  auto indexes
+ *    = byLine(STDIN_FILENO)
+ *    | guard<std::runtime_error>([](std::runtime_error& e,
+ *                                   StringPiece sp) {
+ *        LOG(ERROR) << sp << ": " << e.str();
+ *        return true; // continue processing subsequent lines
+ *      })
+ *    | eachTo<int>()
+ *    | as<vector>();
+ *
+ *  TODO(tjackson): Rename this back to Guard.
+ **/
+template<class Exception,
+         class ErrorHandler>
+class GuardImpl : public Operator<GuardImpl<Exception, ErrorHandler>> {
+  ErrorHandler handler_;
+ public:
+  GuardImpl(ErrorHandler handler)
+    : handler_(std::move(handler)) {}
+
+  template<class Value,
+           class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
+    Source source_;
+    ErrorHandler handler_;
+  public:
+    explicit Generator(Source source,
+                       ErrorHandler handler)
+      : source_(std::move(source)),
+        handler_(std::move(handler)) {}
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      return source_.apply([&](Value value) -> bool {
+        try {
+          handler(std::forward<Value>(value));
+          return true;
+        } catch (Exception& e) {
+          return handler_(e, std::forward<Value>(value));
+        }
+      });
+    }
+
+    static constexpr bool infinite = Source::infinite;
+  };
+
+  template<class Value,
+           class Source,
+           class Gen = Generator<Value, Source>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()), handler_);
+  }
+
+  template<class Value,
+           class Source,
+           class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self(), handler_);
+  }
+};
+
+/**
+ * Cycle - For repeating a sequence forever.
+ *
+ * This type is usually used through the 'cycle' static value, like:
+ *
+ *   auto tests
+ *     = from(samples)
+ *     | cycle
+ *     | take(100);
+ */
+class Cycle : public Operator<Cycle> {
+  off_t limit_; // -1 for infinite
+ public:
+  Cycle()
+    : limit_(-1) { }
+
+  explicit Cycle(off_t limit)
+    : limit_(limit) { }
+
+  template<class Value,
+           class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
+    Source source_;
+    off_t limit_; // -1 for infinite
+  public:
+    explicit Generator(Source source, off_t limit)
+      : source_(std::move(source))
+      , limit_(limit) {}
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      bool cont;
+      auto handler2 = [&](Value value) {
+        cont = handler(std::forward<Value>(value));
+        return cont;
+      };
+      for (off_t count = 0; count != limit_; ++count) {
+        cont = false;
+        source_.apply(handler2);
+        if (!cont) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    // not actually infinite, since an empty generator will end the cycles.
+    static constexpr bool infinite = Source::infinite;
+  };
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()), limit_);
+  }
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self(), limit_);
+  }
+
+  /**
+   * Convenience function for use like:
+   *
+   *  auto tripled = gen | cycle(3);
+   */
+  Cycle operator()(off_t limit) const {
+    return Cycle(limit);
+  }
+};
+
+/**
+ * Dereference - For dereferencing a sequence of pointers while filtering out
+ * null pointers.
+ *
+ * This type is usually used through the 'dereference' static value, like:
+ *
+ *   auto refs = from(ptrs) | dereference;
+ */
+class Dereference : public Operator<Dereference> {
+ public:
+  Dereference() {}
+
+  template<class Value,
+           class Source,
+           class Result = decltype(*std::declval<Value>())>
+  class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
+    Source source_;
+  public:
+    explicit Generator(Source source)
+      : source_(std::move(source)) {}
+
+    template<class Body>
+    void foreach(Body&& body) const {
+      source_.foreach([&](Value value) {
+        if (value) {
+          return body(*value);
+        }
+      });
+    }
+
+    template<class Handler>
+    bool apply(Handler&& handler) const {
+      return source_.apply([&](Value value) -> bool {
+        if (value) {
+          return handler(*value);
+        }
+        return true;
+      });
+    }
+
+    // not actually infinite, since an empty generator will end the cycles.
+    static constexpr bool infinite = Source::infinite;
+  };
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(GenImpl<Value, Source>&& source) const {
+    return Gen(std::move(source.self()));
+  }
+
+  template<class Source,
+           class Value,
+           class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self());
+  }
+};
+
+} //::detail
+
+/**
+ * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
  **/
 template<class Value>
 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
@@ -1393,7 +2031,7 @@ class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
 
   template<class Wrapped>
   class WrapperImpl : public WrapperBase {
-    const Wrapped wrapped_;
+    Wrapped wrapped_;
    public:
     explicit WrapperImpl(Wrapped wrapped)
      : wrapped_(std::move(wrapped)) {
@@ -1457,6 +2095,13 @@ static const detail::Count count;
 
 static const detail::First first;
 
+/**
+ * Use directly for detecting any values, or as a function to detect values
+ * which pass a predicate:
+ *
+ *  auto nonempty = g | any;
+ *  auto evens = g | any(even);
+ */
 static const detail::Any any;
 
 static const detail::Min<Identity, Less> min;
@@ -1465,18 +2110,41 @@ static const detail::Min<Identity, Greater> max;
 
 static const detail::Order<Identity> order;
 
+static const detail::Distinct<Identity> distinct;
+
 static const detail::Map<Move> move;
 
 static const detail::Concat concat;
 
 static const detail::RangeConcat rconcat;
 
+/**
+ * Use directly for infinite sequences, or as a function to limit cycle count.
+ *
+ *  auto forever = g | cycle;
+ *  auto thrice = g | cycle(3);
+ */
+static const detail::Cycle cycle;
+
+static const detail::Dereference dereference;
+
 inline detail::Take take(size_t count) {
   return detail::Take(count);
 }
 
+template<class Random = std::default_random_engine>
+inline detail::Sample<Random> sample(size_t count, Random rng = Random()) {
+  return detail::Sample<Random>(count, std::move(rng));
+}
+
 inline detail::Skip skip(size_t count) {
   return detail::Skip(count);
 }
 
-}} //folly::gen::detail
+inline detail::Batch batch(size_t batchSize) {
+  return detail::Batch(batchSize);
+}
+
+}} //folly::gen
+
+#pragma GCC diagnostic pop