folly copyright 2015 -> copyright 2016
[folly.git] / folly / gen / Base-inl.h
index d4b68ebf68cf703550438149fe2b461406cc323b..3b756fbc5ef5d79a0c5712623d5c84784e16a94f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,8 +37,70 @@ struct ArgumentReference
                                     T&& // int -> int&&
                                     >::type> {};
 
+/**
+ * Group - The output objects from the GroupBy operator
+ */
+template <class Key, class Value>
+class Group : public GenImpl<Value&&, Group<Key, Value>> {
+ public:
+  static_assert(!std::is_reference<Key>::value &&
+                    !std::is_reference<Value>::value,
+                "Key and Value must be decayed types");
+
+  typedef std::vector<Value> VectorType;
+  typedef Key KeyType;
+  typedef Value ValueType;
+
+  Group(Key key, VectorType values)
+      : key_(std::move(key)), values_(std::move(values)) {}
+
+  const Key& key() const { return key_; }
+
+  size_t size() const { return values_.size(); }
+  const VectorType& values() const { return values_; }
+  VectorType& values() { return values_; }
+
+  VectorType operator|(const detail::Collect<VectorType>&) const {
+    return values();
+  }
+
+  VectorType operator|(const detail::CollectTemplate<std::vector>&) const {
+    return values();
+  }
+
+  template <class Body>
+  void foreach(Body&& body) const {
+    for (auto& value : values_) {
+      body(std::move(value));
+    }
+  }
+
+  template <class Handler>
+  bool apply(Handler&& handler) const {
+    for (auto& value : values_) {
+      if (!handler(std::move(value))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // GroupBy only takes in finite generators, so we only have finite groups
+  static constexpr bool infinite = false;
+
+ private:
+  Key key_;
+  mutable VectorType values_;
+};
+
 namespace detail {
 
+// Classes used for the implementation of Sources, Operators, and Sinks
+
+/*
+ ******************************* Sources ***************************************
+ */
+
 /*
  * ReferencedSource - Generate values from an STL-like container using
  * iterators from .begin() until .end(). Value type defaults to the type of
@@ -51,23 +113,22 @@ namespace detail {
  *   string& longestName = from(names)
  *                       | maxBy([](string& s) { return s.size() });
  */
-template<class Container,
-         class Value>
-class ReferencedSource :
-    public GenImpl<Value, ReferencedSource<Container, Value>> {
+template <class Container, class Value>
+class ReferencedSource
+    : public GenImpl<Value, ReferencedSource<Container, Value>> {
   Container* container_;
-public:
-  explicit ReferencedSource(Container* container)
-    : container_(container) {}
 
-  template<class Body>
+ public:
+  explicit ReferencedSource(Container* container) : container_(container) {}
+
+  template <class Body>
   void foreach(Body&& body) const {
     for (auto& value : *container_) {
       body(std::forward<Value>(value));
     }
   }
 
-  template<class Handler>
+  template <class Handler>
   bool apply(Handler&& handler) const {
     for (auto& value : *container_) {
       if (!handler(std::forward<Value>(value))) {
@@ -76,6 +137,9 @@ public:
     }
     return true;
   }
+
+  // from takes in a normal stl structure, which are all finite
+  static constexpr bool infinite = false;
 };
 
 /**
@@ -92,45 +156,44 @@ public:
  *
  * Though it is also used for the initializer_list specialization of from().
  */
-template<class StorageType,
-         class Container>
-class CopiedSource :
-  public GenImpl<const StorageType&,
-                 CopiedSource<StorageType, Container>> {
-  static_assert(
-    !std::is_reference<StorageType>::value, "StorageType must be decayed");
+template <class StorageType, class Container>
+class CopiedSource
+    : public GenImpl<const StorageType&, CopiedSource<StorageType, Container>> {
+  static_assert(!std::is_reference<StorageType>::value,
+                "StorageType must be decayed");
+
  public:
   // Generator objects are often copied during normal construction as they are
   // encapsulated by downstream generators. It would be bad if this caused
   // a copy of the entire container each time, and since we're only exposing a
   // const reference to the value, it's safe to share it between multiple
   // generators.
-  static_assert(
-    !std::is_reference<Container>::value,
-    "Can't copy into a reference");
+  static_assert(!std::is_reference<Container>::value,
+                "Can't copy into a reference");
   std::shared_ptr<const Container> copy_;
-public:
+
+ public:
   typedef Container ContainerType;
 
-  template<class SourceContainer>
+  template <class SourceContainer>
   explicit CopiedSource(const SourceContainer& container)
-    : copy_(new Container(begin(container), end(container))) {}
+      : copy_(new Container(begin(container), end(container))) {}
 
-  explicit CopiedSource(Container&& container) :
-    copy_(new Container(std::move(container))) {}
+  explicit CopiedSource(Container&& container)
+      : copy_(new Container(std::move(container))) {}
 
   // To enable re-use of cached results.
   CopiedSource(const CopiedSource<StorageType, Container>& source)
-    : copy_(source.copy_) {}
+      : copy_(source.copy_) {}
 
-  template<class Body>
+  template <class Body>
   void foreach(Body&& body) const {
     for (const auto& value : *copy_) {
       body(value);
     }
   }
 
-  template<class Handler>
+  template <class Handler>
   bool apply(Handler&& handler) const {
     // The collection may be reused by others, we can't allow it to be changed.
     for (const auto& value : *copy_) {
@@ -140,6 +203,9 @@ public:
     }
     return true;
   }
+
+  // from takes in a normal stl structure, which are all finite
+  static constexpr bool infinite = false;
 };
 
 /**
@@ -153,17 +219,16 @@ public:
  *
  * Reminder: Be careful not to invalidate iterators when using ranges like this.
  */
-template<class Iterator>
+template <class Iterator>
 class RangeSource : public GenImpl<typename Range<Iterator>::reference,
                                    RangeSource<Iterator>> {
   Range<Iterator> range_;
+
  public:
-  RangeSource() {}
-  explicit RangeSource(Range<Iterator> range)
-    : range_(std::move(range))
-  {}
+  RangeSource() = default;
+  explicit RangeSource(Range<Iterator> range) : range_(std::move(range)) {}
 
-  template<class Handler>
+  template <class Handler>
   bool apply(Handler&& handler) const {
     for (auto& value : range_) {
       if (!handler(value)) {
@@ -173,12 +238,15 @@ class RangeSource : public GenImpl<typename Range<Iterator>::reference,
     return true;
   }
 
-  template<class Body>
+  template <class Body>
   void foreach(Body&& body) const {
     for (auto& value : range_) {
       body(value);
     }
   }
+
+  // folly::Range only supports finite ranges
+  static constexpr bool infinite = false;
 };
 
 /**
@@ -192,17 +260,19 @@ class RangeSource : public GenImpl<typename Range<Iterator>::reference,
  *   auto indexes = range(0, 10);
  *   auto endless = seq(0); // 0, 1, 2, 3, ...
  */
-template<class Value, class SequenceImpl>
+template <class Value, class SequenceImpl>
 class Sequence : public GenImpl<const Value&, Sequence<Value, SequenceImpl>> {
   static_assert(!std::is_reference<Value>::value &&
-                !std::is_const<Value>::value, "Value mustn't be const or ref.");
+                    !std::is_const<Value>::value,
+                "Value mustn't be const or ref.");
   Value start_;
   SequenceImpl impl_;
-public:
+
+ public:
   explicit Sequence(Value start, SequenceImpl impl)
-      : start_(std::move(start)), impl_(std::move(impl)) { }
+      : start_(std::move(start)), impl_(std::move(impl)) {}
 
-  template<class Handler>
+  template <class Handler>
   bool apply(Handler&& handler) const {
     for (Value current = start_; impl_.test(current); impl_.step(current)) {
       if (!handler(current)) {
@@ -212,71 +282,83 @@ public:
     return true;
   }
 
-  template<class Body>
+  template <class Body>
   void foreach(Body&& body) const {
     for (Value current = start_; impl_.test(current); impl_.step(current)) {
       body(current);
     }
   }
+
+  // Let the implementation say if we are infinite or not
+  static constexpr bool infinite = SequenceImpl::infinite;
 };
 
 /**
  * Sequence implementations (range, sequence, infinite, with/without step)
  **/
-template<class Value>
+template <class Value>
 class RangeImpl {
   Value end_;
+
  public:
-  explicit RangeImpl(Value end) : end_(std::move(end)) { }
+  explicit RangeImpl(Value end) : end_(std::move(end)) {}
   bool test(const Value& current) const { return current < end_; }
   void step(Value& current) const { ++current; }
+  static constexpr bool infinite = false;
 };
 
-template<class Value, class Distance>
+template <class Value, class Distance>
 class RangeWithStepImpl {
   Value end_;
   Distance step_;
+
  public:
   explicit RangeWithStepImpl(Value end, Distance step)
-    : end_(std::move(end)), step_(std::move(step)) { }
+      : end_(std::move(end)), step_(std::move(step)) {}
   bool test(const Value& current) const { return current < end_; }
   void step(Value& current) const { current += step_; }
+  static constexpr bool infinite = false;
 };
 
-template<class Value>
+template <class Value>
 class SeqImpl {
   Value end_;
+
  public:
-  explicit SeqImpl(Value end) : end_(std::move(end)) { }
+  explicit SeqImpl(Value end) : end_(std::move(end)) {}
   bool test(const Value& current) const { return current <= end_; }
   void step(Value& current) const { ++current; }
+  static constexpr bool infinite = false;
 };
 
-template<class Value, class Distance>
+template <class Value, class Distance>
 class SeqWithStepImpl {
   Value end_;
   Distance step_;
+
  public:
   explicit SeqWithStepImpl(Value end, Distance step)
-    : end_(std::move(end)), step_(std::move(step)) { }
+      : end_(std::move(end)), step_(std::move(step)) {}
   bool test(const Value& current) const { return current <= end_; }
   void step(Value& current) const { current += step_; }
+  static constexpr bool infinite = false;
 };
 
-template<class Value>
+template <class Value>
 class InfiniteImpl {
  public:
-  bool test(const Value& current) const { return true; }
+  bool test(const Value& /* current */) const { return true; }
   void step(Value& current) const { ++current; }
+  static constexpr bool infinite = true;
 };
 
 /**
  * GenratorBuilder - Helper for GENERTATOR macro.
  **/
-template<class Value>
+template <class Value>
 struct GeneratorBuilder {
-  template<class Source,
-           class Yield = detail::Yield<Value, Source>>
+  template <class Source,
+            class Yield = detail::Yield<Value, Source>>
   Yield operator+(Source&& source) {
     return Yield(std::forward<Source>(source));
   }
@@ -286,15 +368,14 @@ struct GeneratorBuilder {
  * Yield - For producing values from a user-defined generator by way of a
  * 'yield' function.
  **/
-template<class Value, class Source>
+template <class Value, class Source>
 class Yield : public GenImpl<Value, Yield<Value, Source>> {
   Source source_;
+
  public:
-  explicit Yield(Source source)
-    : source_(std::move(source)) {
-  }
+  explicit Yield(Source source) : source_(std::move(source)) {}
 
-  template<class Handler>
+  template <class Handler>
   bool apply(Handler&& handler) const {
     struct Break {};
     auto body = [&](Value value) {
@@ -310,13 +391,13 @@ class Yield : public GenImpl<Value, Yield<Value, Source>> {
     }
   }
 
-  template<class Body>
+  template <class Body>
   void foreach(Body&& body) const {
     source_(std::forward<Body>(body));
   }
 };
 
-template<class Value>
+template <class Value>
 class Empty : public GenImpl<Value, Empty<Value>> {
  public:
   template <class Handler>
@@ -326,6 +407,9 @@ class Empty : public GenImpl<Value, Empty<Value>> {
 
   template <class Body>
   void foreach(Body&&) const {}
+
+  // No values, so finite
+  static constexpr bool infinite = false;
 };
 
 template <class Value>
@@ -333,6 +417,7 @@ class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
   static_assert(!std::is_reference<Value>::value,
                 "SingleReference requires non-ref types");
   Value* ptr_;
+
  public:
   explicit SingleReference(Value& ref) : ptr_(&ref) {}
 
@@ -345,6 +430,9 @@ class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
   void foreach(Body&& body) const {
     body(*ptr_);
   }
+
+  // One value, so finite
+  static constexpr bool infinite = false;
 };
 
 template <class Value>
@@ -352,6 +440,7 @@ class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
   static_assert(!std::is_reference<Value>::value,
                 "SingleCopy requires non-ref types");
   Value value_;
+
  public:
   explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
 
@@ -364,10 +453,13 @@ class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
   void foreach(Body&& body) const {
     body(value_);
   }
+
+  // One value, so finite
+  static constexpr bool infinite = false;
 };
 
 /*
- * Operators
+ ***************************** Operators ***************************************
  */
 
 /**
@@ -378,37 +470,34 @@ class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
  *
  *   auto squares = seq(1, 10) | map(square) | asVector;
  */
-template<class Predicate>
+template <class Predicate>
 class Map : public Operator<Map<Predicate>> {
   Predicate pred_;
+
  public:
-  Map() {}
-
-  explicit Map(Predicate pred)
-    : pred_(std::move(pred))
-  { }
-
-  template<class Value,
-           class Source,
-           class Result = typename ArgumentReference<
-                            typename std::result_of<Predicate(Value)>::type
-                          >::type>
-  class Generator :
-      public GenImpl<Result, Generator<Value, Source, Result>> {
+  Map() = default;
+
+  explicit Map(Predicate pred) : pred_(std::move(pred)) {}
+
+  template <class Value,
+            class Source,
+            class Result = typename ArgumentReference<
+                typename std::result_of<Predicate(Value)>::type>::type>
+  class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
     Source source_;
     Predicate pred_;
-  public:
+
+   public:
     explicit Generator(Source source, const Predicate& pred)
-      : source_(std::move(source)), pred_(pred) {}
+        : source_(std::move(source)), pred_(pred) {}
 
-    template<class Body>
+    template <class Body>
     void foreach(Body&& body) const {
-      source_.foreach([&](Value value) {
-        body(pred_(std::forward<Value>(value)));
-      });
+      source_.foreach(
+          [&](Value value) { body(pred_(std::forward<Value>(value))); });
     }
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       return source_.apply([&](Value value) {
         return handler(pred_(std::forward<Value>(value)));
@@ -418,22 +507,21 @@ class Map : public Operator<Map<Predicate>> {
     static constexpr bool infinite = Source::infinite;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), pred_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), pred_);
   }
 };
 
-
 /**
  * Filter - For filtering values from a source sequence by a predicate.
  *
@@ -443,38 +531,46 @@ class Map : public Operator<Map<Predicate>> {
  *                 | filter([](const string& str) -> bool {
  *                     return !str.empty();
  *                   });
+ *
+ * Note that if no predicate is provided, the values are casted to bool and
+ * filtered based on that. So if pointers is a vector of pointers,
+ *
+ *   auto nonNull = from(pointers) | filter();
+ *
+ * will give a vector of all the pointers != nullptr.
  */
-template<class Predicate>
+template <class Predicate>
 class Filter : public Operator<Filter<Predicate>> {
   Predicate pred_;
+
  public:
-  Filter() {}
-  explicit Filter(Predicate pred)
-    : pred_(std::move(pred))
-  { }
+  Filter() = default;
+  explicit Filter(Predicate pred) : pred_(std::move(pred)) {}
 
-  template<class Value,
-           class Source>
+  template <class Value, class Source>
   class Generator : public GenImpl<Value, Generator<Value, Source>> {
     Source source_;
     Predicate pred_;
-  public:
+
+   public:
     explicit Generator(Source source, const Predicate& pred)
-      : source_(std::move(source)), pred_(pred) {}
+        : source_(std::move(source)), pred_(pred) {}
 
-    template<class Body>
+    template <class Body>
     void foreach(Body&& body) const {
       source_.foreach([&](Value value) {
-        if (pred_(std::forward<Value>(value))) {
+        // NB: Argument not forwarded to avoid accidental move-construction
+        if (pred_(value)) {
           body(std::forward<Value>(value));
         }
       });
     }
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       return source_.apply([&](Value value) -> bool {
-        if (pred_(std::forward<Value>(value))) {
+        // NB: Argument not forwarded to avoid accidental move-construction
+        if (pred_(value)) {
           return handler(std::forward<Value>(value));
         }
         return true;
@@ -484,16 +580,16 @@ class Filter : public Operator<Filter<Predicate>> {
     static constexpr bool infinite = Source::infinite;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), pred_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), pred_);
   }
@@ -508,25 +604,24 @@ class Filter : public Operator<Filter<Predicate>> {
  *             | until([](Item& item) { return item.score > 100; })
  *             | asVector;
  */
-template<class Predicate>
+template <class Predicate>
 class Until : public Operator<Until<Predicate>> {
   Predicate pred_;
+
  public:
-  Until() {}
-  explicit Until(Predicate pred)
-    : pred_(std::move(pred))
-  {}
+  Until() = default;
+  explicit Until(Predicate pred) : pred_(std::move(pred)) {}
 
-  template<class Value,
-           class Source>
+  template <class Value, 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) {}
+        : source_(std::move(source)), pred_(pred) {}
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       bool cancelled = false;
       source_.apply([&](Value value) -> bool {
@@ -541,24 +636,24 @@ class Until : public Operator<Until<Predicate>> {
       });
       return !cancelled;
     }
+
+    // Theoretically an 'until' might stop an infinite
+    static constexpr bool infinite = false;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), pred_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), pred_);
   }
-
-  // Theoretically an 'until' might stop an infinite
-  static constexpr bool infinite = false;
 };
 
 /**
@@ -572,23 +667,24 @@ class Until : public Operator<Until<Predicate>> {
  */
 class Take : public Operator<Take> {
   size_t count_;
+
  public:
-  explicit Take(size_t count)
-    : count_(count) {}
+  explicit Take(size_t count) : count_(count) {}
 
-  template<class Value,
-           class Source>
-  class Generator :
-      public GenImpl<Value, Generator<Value, Source>> {
+  template <class Value, class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
     Source source_;
     size_t count_;
-  public:
+
+   public:
     explicit Generator(Source source, size_t count)
-      : source_(std::move(source)) , count_(count) {}
+        : source_(std::move(source)), count_(count) {}
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
-      if (count_ == 0) { return false; }
+      if (count_ == 0) {
+        return false;
+      }
       size_t n = count_;
       bool cancelled = false;
       source_.apply([&](Value value) -> bool {
@@ -600,18 +696,21 @@ class Take : public Operator<Take> {
       });
       return !cancelled;
     }
+
+    // take will stop an infinite generator
+    static constexpr bool infinite = false;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), count_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), count_);
   }
@@ -639,42 +738,50 @@ class Stride : public Operator<Stride> {
   class Generator : public GenImpl<Value, Generator<Value, Source>> {
     Source source_;
     size_t stride_;
-  public:
-   Generator(Source source, size_t stride)
-       : source_(std::move(source)), stride_(stride) {}
-
-   template <class Handler>
-   bool apply(Handler&& handler) const {
-     size_t distance = stride_;
-     return source_.apply([&](Value value)->bool {
-       if (++distance >= stride_) {
-         if (!handler(std::forward<Value>(value))) {
-           return false;
-         }
-         distance = 0;
-       }
-       return true;
-     });
-   }
-
-   template <class Body>
-   void foreach(Body&& body) const {
-     size_t distance = stride_;
-     source_.foreach([&](Value value) {
-       if (++distance >= stride_) {
-         body(std::forward<Value>(value));
-         distance = 0;
-       }
-     });
-   }
+
+   public:
+    explicit Generator(Source source, size_t stride)
+        : source_(std::move(source)), stride_(stride) {}
+
+    template <class Handler>
+    bool apply(Handler&& handler) const {
+      size_t distance = stride_;
+      return source_.apply([&](Value value) -> bool {
+        if (++distance >= stride_) {
+          if (!handler(std::forward<Value>(value))) {
+            return false;
+          }
+          distance = 0;
+        }
+        return true;
+      });
+    }
+
+    template <class Body>
+    void foreach(Body&& body) const {
+      size_t distance = stride_;
+      source_.foreach([&](Value value) {
+        if (++distance >= stride_) {
+          body(std::forward<Value>(value));
+          distance = 0;
+        }
+      });
+    }
+
+    // Taking every Nth of an infinite list is still infinte
+    static constexpr bool infinite = Source::infinite;
   };
 
-  template <class Source, class Value, class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), stride_);
   }
 
-  template <class Source, class Value, class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), stride_);
   }
@@ -684,21 +791,22 @@ class Stride : public Operator<Stride> {
  * Sample - For taking a random sample of N elements from a sequence
  * (without replacement).
  */
-template<class Random>
+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>> {
+      : 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,
@@ -706,53 +814,59 @@ class Sample : public Operator<Sample<Random>> {
     Source source_;
     size_t count_;
     mutable Rand rng_;
-  public:
+
+   public:
     explicit Generator(Source source, size_t count, Random rng)
-      : source_(std::move(source)) , count_(count), rng_(std::move(rng)) {}
+        : source_(std::move(source)), count_(count), rng_(std::move(rng)) {}
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
-      if (count_ == 0) { return false; }
+      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);
-            }
+        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;
-        });
+        }
+        ++n;
+      });
 
       // output is unsorted!
-      for (auto& val: v) {
+      for (auto& val : v) {
         if (!handler(std::move(val))) {
           return false;
         }
       }
       return true;
     }
+
+    // Only takes N elements, so finite
+    static constexpr bool infinite = false;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source, Random>>
+  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>>
+  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_);
   }
@@ -769,21 +883,20 @@ class Sample : public Operator<Sample<Random>> {
  */
 class Skip : public Operator<Skip> {
   size_t count_;
+
  public:
-  explicit Skip(size_t count)
-    : count_(count) {}
+  explicit Skip(size_t count) : count_(count) {}
 
-  template<class Value,
-           class Source>
-  class Generator :
-      public GenImpl<Value, Generator<Value, Source>> {
+  template <class Value, class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
     Source source_;
     size_t count_;
+
    public:
     explicit Generator(Source source, size_t count)
-      : source_(std::move(source)) , count_(count) {}
+        : source_(std::move(source)), count_(count) {}
 
-    template<class Body>
+    template <class Body>
     void foreach(Body&& body) const {
       if (count_ == 0) {
         source_.foreach(body);
@@ -791,42 +904,43 @@ class Skip : public Operator<Skip> {
       }
       size_t n = 0;
       source_.foreach([&](Value value) {
-          if (n < count_) {
-            ++n;
-          } else {
-            body(std::forward<Value>(value));
-          }
-        });
+        if (n < count_) {
+          ++n;
+        } else {
+          body(std::forward<Value>(value));
+        }
+      });
     }
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       if (count_ == 0) {
         return source_.apply(std::forward<Handler>(handler));
       }
       size_t n = 0;
       return source_.apply([&](Value value) -> bool {
-          if (n < count_) {
-            ++n;
-            return true;
-          }
-          return handler(std::forward<Value>(value));
-        });
+        if (n < count_) {
+          ++n;
+          return true;
+        }
+        return handler(std::forward<Value>(value));
+      });
     }
 
+    // Skipping N items of an infinite source is still infinite
     static constexpr bool infinite = Source::infinite;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), count_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), count_);
   }
@@ -845,30 +959,26 @@ class Skip : public Operator<Skip> {
  *                  })
  *                | take(10);
  */
-template<class Selector, class Comparer>
+template <class Selector, class Comparer>
 class Order : public Operator<Order<Selector, Comparer>> {
   Selector selector_;
   Comparer comparer_;
+
  public:
-  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,
-           class StorageType = typename std::decay<Value>::type,
-           class Result = typename std::result_of<Selector(Value)>::type>
-  class Generator :
-    public GenImpl<StorageType&&,
-                   Generator<Value, Source, StorageType, Result>> {
+  Order() = default;
+
+  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,
+            class StorageType = typename std::decay<Value>::type,
+            class Result = typename std::result_of<Selector(Value)>::type>
+  class Generator
+      : public GenImpl<StorageType&&,
+                       Generator<Value, Source, StorageType, Result>> {
     static_assert(!Source::infinite, "Cannot sort infinite source!");
     Source source_;
     Selector selector_;
@@ -884,13 +994,12 @@ class Order : public Operator<Order<Selector, Comparer>> {
       std::sort(vals.begin(), vals.end(), comparer);
       return std::move(vals);
     }
+
    public:
-    Generator(Source source,
-              Selector selector,
-              Comparer comparer)
-      : source_(std::move(source)),
-        selector_(std::move(selector)),
-        comparer_(std::move(comparer)) {}
+    Generator(Source source, Selector selector, Comparer comparer)
+        : source_(std::move(source)),
+          selector_(std::move(selector)),
+          comparer_(std::move(comparer)) {}
 
     VectorType operator|(const Collect<VectorType>&) const {
       return asVector();
@@ -900,14 +1009,14 @@ class Order : public Operator<Order<Selector, Comparer>> {
       return asVector();
     }
 
-    template<class Body>
+    template <class Body>
     void foreach(Body&& body) const {
       for (auto& value : asVector()) {
         body(std::move(value));
       }
     }
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       auto comparer = [&](const StorageType& a, const StorageType& b) {
         // swapped for minHeap
@@ -924,23 +1033,106 @@ class Order : public Operator<Order<Selector, Comparer>> {
       }
       return true;
     }
+
+    // Can only be run on and produce finite generators
+    static constexpr bool infinite = false;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(GenImpl<Value, Source>&& source) const {
     return Gen(std::move(source.self()), selector_, comparer_);
   }
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), selector_, comparer_);
   }
 };
 
+/**
+ * GroupBy - Group values by a given key selector, producing a sequence of
+ * groups.
+ *
+ * This type is usually used through the 'groupBy' helper function, like:
+ *
+ *   auto bests
+ *     = from(places)
+ *     | groupBy([](const Place& p) {
+ *         return p.city;
+ *       })
+ *     | [](Group<std::string, Place>&& g) {
+ *         cout << g.key() << ": " << (g | first).description;
+ *       };
+ */
+template <class Selector>
+class GroupBy : public Operator<GroupBy<Selector>> {
+  Selector selector_;
+
+ public:
+  GroupBy() {}
+
+  explicit GroupBy(Selector selector) : selector_(std::move(selector)) {}
+
+  template <class Value,
+            class Source,
+            class ValueDecayed = typename std::decay<Value>::type,
+            class Key = typename std::result_of<Selector(Value)>::type,
+            class KeyDecayed = typename std::decay<Key>::type>
+  class Generator
+      : public GenImpl<
+            Group<KeyDecayed, ValueDecayed>&&,
+            Generator<Value, Source, ValueDecayed, Key, KeyDecayed>> {
+    static_assert(!Source::infinite, "Cannot group infinite source!");
+    Source source_;
+    Selector selector_;
+
+   public:
+    Generator(Source source, Selector selector)
+        : source_(std::move(source)), selector_(std::move(selector)) {}
+
+    typedef Group<KeyDecayed, ValueDecayed> GroupType;
+
+    template <class Handler>
+    bool apply(Handler&& handler) const {
+      std::unordered_map<KeyDecayed, typename GroupType::VectorType> groups;
+      source_ | [&](Value value) {
+        const Value& cv = value;
+        auto& group = groups[selector_(cv)];
+        group.push_back(std::forward<Value>(value));
+      };
+      for (auto& kg : groups) {
+        GroupType group(kg.first, std::move(kg.second));
+        if (!handler(std::move(group))) {
+          return false;
+        }
+        kg.second.clear();
+      }
+      return true;
+    }
+
+    // Can only be run on and produce finite generators
+    static constexpr bool infinite = false;
+  };
+
+  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_);
+  }
+};
+
 /*
  * 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.
@@ -950,17 +1142,17 @@ class Order : public Operator<Order<Selector, Comparer>> {
  *   auto c =  from(vector) | assert_type<int&>() | sum;
  *
  */
-template<class Expected>
+template <class Expected>
 class TypeAssertion : public Operator<TypeAssertion<Expected>> {
  public:
-  template<class Source, class Value>
+  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>
+  template <class Source, class Value>
   Source&& compose(GenImpl<Value, Source>&& source) const {
     static_assert(std::is_same<Expected, Value>::value,
                   "assert_type() check failed");
@@ -980,18 +1172,16 @@ class TypeAssertion : public Operator<TypeAssertion<Expected>> {
  *                  })
  *                | take(10);
  */
-template<class Selector>
+template <class Selector>
 class Distinct : public Operator<Distinct<Selector>> {
   Selector selector_;
+
  public:
-  Distinct() {}
+  Distinct() = default;
 
-  explicit Distinct(Selector selector)
-    : selector_(std::move(selector))
-  {}
+  explicit Distinct(Selector selector) : selector_(std::move(selector)) {}
 
-  template<class Value,
-           class Source>
+  template <class Value, class Source>
   class Generator : public GenImpl<Value, Generator<Value, Source>> {
     Source source_;
     Selector selector_;
@@ -1006,12 +1196,10 @@ class Distinct : public Operator<Distinct<Selector>> {
     typedef typename std::decay<KeyType>::type KeyStorageType;
 
    public:
-    Generator(Source source,
-              Selector selector)
-      : source_(std::move(source)),
-        selector_(std::move(selector)) {}
+    Generator(Source source, Selector selector)
+        : source_(std::move(source)), selector_(std::move(selector)) {}
 
-    template<class Body>
+    template <class Body>
     void foreach(Body&& body) const {
       std::unordered_set<KeyStorageType> keysSeen;
       source_.foreach([&](Value value) {
@@ -1021,7 +1209,7 @@ class Distinct : public Operator<Distinct<Selector>> {
       });
     }
 
-    template<class Handler>
+    template <class Handler>
     bool apply(Handler&& handler) const {
       std::unordered_set<KeyStorageType> keysSeen;
       return source_.apply([&](Value value) -> bool {
@@ -1031,18 +1219,22 @@ class Distinct : public Operator<Distinct<Selector>> {
         return true;
       });
     }
+
+    // While running distinct on an infinite sequence might produce a
+    // conceptually finite sequence, it will take infinite time
+    static constexpr bool infinite = Source::infinite;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  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>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), selector_);
   }
@@ -1052,16 +1244,16 @@ class Distinct : public Operator<Distinct<Selector>> {
  * Composer - Helper class for adapting pipelines into functors. Primarily used
  * for 'mapOp'.
  */
-template<class Operators>
+template <class Operators>
 class Composer {
   Operators op_;
+
  public:
-  explicit Composer(Operators op)
-    : op_(std::move(op)) {}
+  explicit Composer(Operators op) : op_(std::move(op)) {}
 
-  template<class Source,
-           class Ret = decltype(std::declval<Operators>()
-                                  .compose(std::declval<Source>()))>
+  template <class Source,
+            class Ret = decltype(
+                std::declval<Operators>().compose(std::declval<Source>()))>
   Ret operator()(Source&& source) const {
     return op_.compose(std::forward<Source>(source));
   }
@@ -1082,42 +1274,42 @@ class Composer {
  */
 class Batch : public Operator<Batch> {
   size_t batchSize_;
+
  public:
-  explicit Batch(size_t batchSize)
-    : batchSize_(batchSize) {
+  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>> {
+  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:
+
+   public:
     explicit Generator(Source source, size_t batchSize)
-      : source_(std::move(source))
-      , batchSize_(batchSize) {}
+        : source_(std::move(source)), batchSize_(batchSize) {}
 
-    template<class Handler>
+    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;
-        });
+        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_);
@@ -1126,54 +1318,456 @@ class Batch : public Operator<Batch> {
       return shouldContinue;
     }
 
+    // Taking n-tuples of an infinite source is still infinite
     static constexpr bool infinite = Source::infinite;
   };
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
+  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>>
+  template <class Source,
+            class Value,
+            class Gen = Generator<Value, Source>>
   Gen compose(const GenImpl<Value, Source>& source) const {
     return Gen(source.self(), batchSize_);
   }
 };
-/*
- * Sinks
- */
 
 /**
- * FoldLeft - Left-associative functional fold. For producing an aggregate value
- * from a seed and a folder function. Useful for custom aggregators on a
- * sequence.
+ * Concat - For flattening generators of generators.
  *
- * This type is primarily used through the 'foldl' helper method, like:
+ * This type is usually used through the 'concat' static value, like:
  *
- *   double movingAverage = from(values)
- *                        | foldl(0.0, [](double avg, double sample) {
- *                            return sample * 0.1 + avg * 0.9;
- *                          });
- */
-template<class Seed,
-         class Fold>
-class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
+ *   auto edges =
+ *       from(nodes)
+ *     | map([](Node& x) {
+ *           return from(x.neighbors)
+ *                | map([&](Node& y) {
+ *                    return Edge(x, y);
+ *                  });
+ *         })
+ *     | concat
+ *     | as<std::set>();
+ */
+class Concat : public Operator<Concat> {
+ public:
+  Concat() = default;
+
+  template <class Inner,
+            class Source,
+            class InnerValue = typename std::decay<Inner>::type::ValueType>
+  class Generator
+      : public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
+    Source source_;
+
+   public:
+    explicit Generator(Source source) : source_(std::move(source)) {}
+
+    template <class Handler>
+    bool apply(Handler&& handler) const {
+      return source_.apply([&](Inner inner) -> bool {
+        return inner.apply(std::forward<Handler>(handler));
+      });
+    }
+
+    template <class Body>
+    void foreach(Body&& body) const {
+      source_.foreach([&](Inner inner) {
+        inner.foreach(std::forward<Body>(body));
+      });
+    }
+
+    // Resulting concatination is only finite if both Source and Inner are also
+    // finite. In one sence, if dosn't make sence to call concat when the Inner
+    // generator is infinite (you could just call first), so we could also just
+    // static_assert if the inner is infinite. Taking the less restrictive
+    // approch for now.
+    static constexpr bool infinite =
+        Source::infinite || std::decay<Inner>::type::infinite;
+  };
+
+  template <class Value,
+            class Source,
+            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<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self());
+  }
+};
+
+/**
+ * RangeConcat - For flattening generators of iterables.
+ *
+ * This type is usually used through the 'rconcat' static value, like:
+ *
+ *   map<int, vector<int>> adjacency;
+ *   auto sinks =
+ *       from(adjacency)
+ *     | get<1>()
+ *     | rconcat()
+ *     | as<std::set>();
+ */
+class RangeConcat : public Operator<RangeConcat> {
+ public:
+  RangeConcat() = default;
+
+  template <class Range,
+            class Source,
+            class InnerValue = typename ValueTypeOfRange<Range>::RefType>
+  class Generator
+      : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
+    Source source_;
+
+   public:
+    explicit Generator(Source source) : source_(std::move(source)) {}
+
+    template <class Body>
+    void foreach(Body&& body) const {
+      source_.foreach([&](Range range) {
+        for (auto& value : range) {
+          body(value);
+        }
+      });
+    }
+
+    template <class Handler>
+    bool apply(Handler&& handler) const {
+      return source_.apply([&](Range range) -> bool {
+        for (auto& value : range) {
+          if (!handler(value)) {
+            return false;
+          }
+        }
+        return true;
+      });
+    }
+
+    // This is similar to concat, except that the inner iterables all are finite
+    // so the only thing that matters is that the source is infinite.
+    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()));
+  }
+
+  template <class Value,
+            class Source,
+            class Gen = Generator<Value, Source>>
+  Gen compose(const GenImpl<Value, Source>& source) const {
+    return Gen(source.self());
+  }
+};
+
+/**
+ * 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 used through the `guard` helper, like so:
+ *
+ *  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:
+  explicit 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));
+        }
+      });
+    }
+
+    // Just passes value though, length unaffected
+    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_);
+  }
+};
+
+/**
+ * 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() = default;
+
+  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;
+      });
+    }
+
+    // Just passes value though, length unaffected
+    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());
+  }
+};
+
+/**
+ * Indirect - For producing a sequence of the addresses of the values in the
+ * input.
+ *
+ * This type is usually used through the 'indirect' static value, like:
+ *
+ *   auto ptrs = from(refs) | indirect;
+ */
+class Indirect : public Operator<Indirect> {
+ public:
+  Indirect() = default;
+
+  template <class Value,
+            class Source,
+            class Result = typename std::remove_reference<Value>::type*>
+  class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
+    Source source_;
+    static_assert(!std::is_rvalue_reference<Value>::value,
+                  "Cannot use indirect on an rvalue");
+
+   public:
+    explicit Generator(Source source) : source_(std::move(source)) {}
+
+    template <class Body>
+    void foreach(Body&& body) const {
+      source_.foreach([&](Value value) {
+        return body(&value);
+      });
+    }
+
+    template <class Handler>
+    bool apply(Handler&& handler) const {
+      return source_.apply([&](Value value) -> bool {
+        return handler(&value);
+      });
+    }
+
+    // Just passes value though, length unaffected
+    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());
+  }
+};
+
+/**
+ * Cycle - For repeating a sequence forever.
+ *
+ * This type is usually used through the 'cycle' static value, like:
+ *
+ *   auto tests
+ *     = from(samples)
+ *     | cycle
+ *     | take(100);
+ *
+ * or in the finite case:
+ *
+ *   auto thrice = g | cycle(3);
+ */
+template <bool forever>
+class Cycle : public Operator<Cycle<forever>> {
+  off_t limit_; // not used if forever == true
+ public:
+  Cycle() = default;
+
+  explicit Cycle(off_t limit) : limit_(limit) {
+    static_assert(
+        !forever,
+        "Cycle limit constructor should not be used when forever == true.");
+  }
+
+  template <class Value, class Source>
+  class Generator : public GenImpl<Value, Generator<Value, Source>> {
+    Source source_;
+    off_t limit_;
+
+   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;
+      };
+      // Becomes an infinte loop if forever == true
+      for (off_t count = 0; (forever || count != limit_); ++count) {
+        cont = false;
+        source_.apply(handler2);
+        if (!cont) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    // This is the hardest one to infer. If we are simply doing a finite cycle,
+    // then (gen | cycle(n)) is infinite if and only if gen is infinite.
+    // However, if we are doing an infinite cycle, (gen | cycle) is infinite
+    // unless gen is empty. However, we will always mark (gen | cycle) as
+    // infinite, because patterns such as (gen | cycle | count) can either take
+    // on exactly one value, or infinite loop.
+    static constexpr bool infinite = forever || 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 finite cycles used like:
+   *
+   *  auto tripled = gen | cycle(3);
+   */
+  Cycle<false> operator()(off_t limit) const { return Cycle<false>(limit); }
+};
+
+/*
+ ******************************* Sinks *****************************************
+ */
+
+/**
+ * FoldLeft - Left-associative functional fold. For producing an aggregate value
+ * from a seed and a folder function. Useful for custom aggregators on a
+ * sequence.
+ *
+ * This type is primarily used through the 'foldl' helper method, like:
+ *
+ *   double movingAverage = from(values)
+ *                        | foldl(0.0, [](double avg, double sample) {
+ *                            return sample * 0.1 + avg * 0.9;
+ *                          });
+ */
+template <class Seed, class Fold>
+class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
   Seed seed_;
   Fold fold_;
+
  public:
-  FoldLeft() {}
-  FoldLeft(Seed seed,
-           Fold fold)
-    : seed_(std::move(seed))
-    , fold_(std::move(fold))
-  {}
-
-  template<class Source,
-           class Value>
+  FoldLeft() = default;
+  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_;
@@ -1193,96 +1787,55 @@ class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
  */
 class First : public Operator<First> {
  public:
-  First() { }
+  First() = default;
 
-  template<class Source,
-           class Value,
-           class StorageType = typename std::decay<Value>::type>
-  StorageType compose(const GenImpl<Value, Source>& source) const {
+  template <class Source,
+            class Value,
+            class StorageType = typename std::decay<Value>::type>
+  Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
     Optional<StorageType> accum;
     source | [&](Value v) -> bool {
       accum = std::forward<Value>(v);
       return false;
     };
-    if (!accum.hasValue()) {
-      throw EmptySequence();
-    }
-    return std::move(accum.value());
+    return accum;
   }
 };
 
-
 /**
- * Any - For determining whether any values in a sequence satisfy a predicate.
+ * IsEmpty - a helper class for isEmpty and notEmpty
  *
- * This type is primarily used through the 'any' static value, like:
+ * Essentially returns 'result' if the source is empty. Note that this cannot be
+ * called on an infinite source, because then there is only one possible return
+ * value.
  *
- *   bool any20xPrimes = seq(200, 210) | filter(isPrime) | any;
  *
- * Note that it may also be used like so:
+ *  Used primarily through 'isEmpty' and 'notEmpty' static values
  *
- *   bool any20xPrimes = seq(200, 210) | any(isPrime);
+ *  bool hasPrimes = g | filter(prime) | notEmpty;
+ *  bool lacksEvens = g | filter(even) | isEmpty;
  *
+ *  Also used in the implementation of 'any' and 'all'
  */
-class Any : public Operator<Any> {
+template <bool emptyResult>
+class IsEmpty : public Operator<IsEmpty<emptyResult>> {
  public:
-  Any() { }
+  IsEmpty() = default;
 
-  template<class Source,
-           class Value>
+  template <class Source, class Value>
   bool compose(const GenImpl<Value, Source>& source) const {
-    bool any = false;
-    source | [&](Value v) -> bool {
-      any = true;
-      return false;
-    };
-    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;
+    static_assert(!Source::infinite,
+                  "Cannot call 'all', 'any', 'isEmpty', or 'notEmpty' on "
+                  "infinite source. 'all' and 'isEmpty' will either return "
+                  "false or hang. 'any' or 'notEmpty' will either return true "
+                  "or hang.");
+    bool ans = emptyResult;
+    source |
+        [&](Value /* v */) -> bool {
+          ans = !emptyResult;
+          return false;
+        };
+    return ans;
   }
 };
 
@@ -1298,19 +1851,19 @@ class All : public Operator<All<Predicate>> {
  *                     return best.size() >= current.size() ? best : current;
  *                   });
  */
-template<class Reducer>
+template <class Reducer>
 class Reduce : public Operator<Reduce<Reducer>> {
   Reducer reducer_;
+
  public:
-  Reduce() {}
-  explicit Reduce(Reducer reducer)
-    : reducer_(std::move(reducer))
-  {}
-
-  template<class Source,
-           class Value,
-           class StorageType = typename std::decay<Value>::type>
-  StorageType compose(const GenImpl<Value, Source>& source) const {
+  Reduce() = default;
+  explicit Reduce(Reducer reducer) : reducer_(std::move(reducer)) {}
+
+  template <class Source,
+            class Value,
+            class StorageType = typename std::decay<Value>::type>
+  Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot reduce infinite source");
     Optional<StorageType> accum;
     source | [&](Value v) {
       if (accum.hasValue()) {
@@ -1319,10 +1872,7 @@ class Reduce : public Operator<Reduce<Reducer>> {
         accum = std::forward<Value>(v);
       }
     };
-    if (!accum.hasValue()) {
-      throw EmptySequence();
-    }
-    return accum.value();
+    return accum;
   }
 };
 
@@ -1335,16 +1885,14 @@ class Reduce : public Operator<Reduce<Reducer>> {
  */
 class Count : public Operator<Count> {
  public:
-  Count() { }
+  Count() = default;
 
-  template<class Source,
-           class Value>
+  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;
-                 }).compose(source);
+                 [](size_t accum, Value /* v */) { return accum + 1; })
+        .compose(source);
   }
 };
 
@@ -1357,11 +1905,11 @@ class Count : public Operator<Count> {
  */
 class Sum : public Operator<Sum> {
  public:
-  Sum() : Operator<Sum>() {}
+  Sum() = default;
 
-  template<class Source,
-           class Value,
-           class StorageType = typename std::decay<Value>::type>
+  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),
@@ -1369,568 +1917,301 @@ class Sum : public Operator<Sum> {
                    return std::move(accum) + std::forward<Value>(v);
                  }).compose(source);
   }
-};
-
-/**
- * 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.
- *
- * This type is usually used through the singletone 'min' or through the helper
- * functions 'minBy' and 'maxBy'.
- *
- *   auto oldest = from(people)
- *               | minBy([](Person& p) {
- *                   return p.dateOfBirth;
- *                 });
- */
-template<class Selector,
-         class Comparer>
-class Min : public Operator<Min<Selector, Comparer>> {
-  Selector selector_;
-  Comparer comparer_;
- public:
-  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,
-           class Source,
-           class StorageType = typename std::decay<Value>::type,
-           class Key = typename std::decay<
-               typename std::result_of<Selector(Value)>::type
-             >::type>
-  StorageType compose(const GenImpl<Value, Source>& source) const {
-    Optional<StorageType> min;
-    Optional<Key> minKey;
-    source | [&](Value v) {
-      Key key = selector_(std::forward<Value>(v));
-      if (!minKey.hasValue() || comparer_(key, minKey.value())) {
-        minKey = key;
-        min = std::forward<Value>(v);
-      }
-    };
-    if (!min.hasValue()) {
-      throw EmptySequence();
-    }
-    return min.value();
-  }
-};
-
-/**
- * Append - For collecting values from a source into a given output container
- * by appending.
- *
- * This type is usually used through the helper function 'appendTo', like:
- *
- *   vector<int64_t> ids;
- *   from(results) | map([](Person& p) { return p.id })
- *                 | appendTo(ids);
- */
-template<class Collection>
-class Append : public Operator<Append<Collection>> {
-  Collection* collection_;
- public:
-  explicit Append(Collection* collection)
-    : collection_(collection)
-  {}
-
-  template<class Value,
-           class Source>
-  Collection& compose(const GenImpl<Value, Source>& source) const {
-    source | [&](Value v) {
-      collection_->insert(collection_->end(), std::forward<Value>(v));
-    };
-    return *collection_;
-  }
-};
-
-/**
- * Collect - For collecting values from a source in a collection of the desired
- * type.
- *
- * This type is usually used through the helper function 'as', like:
- *
- *   std::string upper = from(stringPiece)
- *                     | map(&toupper)
- *                     | as<std::string>();
- */
-template<class Collection>
-class Collect : public Operator<Collect<Collection>> {
- public:
-  Collect() { }
-
-  template<class Value,
-           class Source,
-           class StorageType = typename std::decay<Value>::type>
-  Collection compose(const GenImpl<Value, Source>& source) const {
-    Collection collection;
-    source | [&](Value v) {
-      collection.insert(collection.end(), std::forward<Value>(v));
-    };
-    return collection;
-  }
-};
-
-
-/**
- * CollectTemplate - For collecting values from a source in a collection
- * constructed using the specified template type. Given the type of values
- * produced by the given generator, the collection type will be:
- *   Container<Value, Allocator<Value>>
- *
- * The allocator defaults to std::allocator, so this may be used for the STL
- * containers by simply using operators like 'as<set>', 'as<deque>',
- * 'as<vector>'. 'as', here is the helper method which is the usual means of
- * consturcting this operator.
- *
- * Example:
- *
- *   set<string> uniqueNames = from(names) | as<set>();
- */
-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,
-           class Collection = Container<StorageType, Allocator<StorageType>>>
-  Collection compose(const GenImpl<Value, Source>& source) const {
-    Collection collection;
-    source | [&](Value v) {
-      collection.insert(collection.end(), std::forward<Value>(v));
-    };
-    return collection;
-  }
-};
-
-/**
- * Concat - For flattening generators of generators.
- *
- * This type is usually used through the 'concat' static value, like:
- *
- *   auto edges =
- *       from(nodes)
- *     | map([](Node& x) {
- *           return from(x.neighbors)
- *                | map([&](Node& y) {
- *                    return Edge(x, y);
- *                  });
- *         })
- *     | concat
- *     | as<std::set>();
- */
-class Concat : public Operator<Concat> {
- public:
-  Concat() { }
-
-  template<class Inner,
-           class Source,
-           class InnerValue = typename std::decay<Inner>::type::ValueType>
-  class Generator :
-      public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
-    Source source_;
-   public:
-    explicit Generator(Source source)
-      : source_(std::move(source)) {}
-
-    template<class Handler>
-    bool apply(Handler&& handler) const {
-      return source_.apply([&](Inner inner) -> bool {
-          return inner.apply(std::forward<Handler>(handler));
-        });
-    }
-
-    template<class Body>
-    void foreach(Body&& body) const {
-      source_.foreach([&](Inner inner) {
-          inner.foreach(std::forward<Body>(body));
-        });
-    }
-
-    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()));
-  }
-
-  template<class Value,
-           class Source,
-           class Gen = Generator<Value, Source>>
-  Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self());
-  }
-};
-
-/**
- * RangeConcat - For flattening generators of iterables.
- *
- * This type is usually used through the 'rconcat' static value, like:
- *
- *   map<int, vector<int>> adjacency;
- *   auto sinks =
- *       from(adjacency)
- *     | get<1>()
- *     | rconcat()
- *     | as<std::set>();
- */
-class RangeConcat : public Operator<RangeConcat> {
- public:
-  RangeConcat() { }
-
-  template<class Range,
-           class Source,
-           class InnerValue = typename ValueTypeOfRange<Range>::RefType>
-  class Generator
-    : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
-    Source source_;
-   public:
-    explicit Generator(Source source)
-      : source_(std::move(source)) {}
-
-    template<class Body>
-    void foreach(Body&& body) const {
-      source_.foreach([&](Range range) {
-          for (auto& value : range) {
-            body(value);
-          }
-        });
-    }
-
-    template<class Handler>
-    bool apply(Handler&& handler) const {
-      return source_.apply([&](Range range) -> bool {
-          for (auto& value : range) {
-            if (!handler(value)) {
-              return false;
-            }
-          }
-          return true;
-        });
-    }
-  };
-
-  template<class Value,
-           class Source,
-           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<Value, Source>>
-  Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self());
-  }
-};
-
-
-/**
- * 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 used through the `guard` helper, like so:
- *
- *  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:
-  explicit 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;
-  };
+/**
+ * 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_;
 
-  template<class Value,
-           class Source,
-           class Gen = Generator<Value, Source>>
-  Gen compose(GenImpl<Value, Source>&& source) const {
-    return Gen(std::move(source.self()), handler_);
-  }
+ public:
+  explicit Contains(Needle needle) : needle_(std::move(needle)) {}
 
-  template<class Value,
-           class Source,
-           class Gen = Generator<Value, Source>>
-  Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self(), handler_);
+  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));
+    });
   }
 };
 
 /**
- * Cycle - For repeating a sequence forever.
+ * Min - For a value which minimizes a key, where the key is determined by a
+ * given selector, and compared by given comparer.
  *
- * This type is usually used through the 'cycle' static value, like:
+ * This type is usually used through the singletone 'min' or through the helper
+ * functions 'minBy' and 'maxBy'.
  *
- *   auto tests
- *     = from(samples)
- *     | cycle
- *     | take(100);
+ *   auto oldest = from(people)
+ *               | minBy([](Person& p) {
+ *                   return p.dateOfBirth;
+ *                 });
  */
-class Cycle : public Operator<Cycle> {
-  off_t limit_; // -1 for infinite
+template <class Selector, class Comparer>
+class Min : public Operator<Min<Selector, Comparer>> {
+  Selector selector_;
+  Comparer comparer_;
+
  public:
-  Cycle()
-    : limit_(-1) { }
+  Min() = default;
 
-  explicit Cycle(off_t limit)
-    : limit_(limit) { }
+  explicit Min(Selector selector) : selector_(std::move(selector)) {}
 
-  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) {}
+  Min(Selector selector, Comparer comparer)
+      : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
 
-    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;
-        }
+  template <class Value,
+            class Source,
+            class StorageType = typename std::decay<Value>::type,
+            class Key = typename std::decay<
+                typename std::result_of<Selector(Value)>::type>::type>
+  Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite,
+                  "Calling min or max on an infinite source will cause "
+                  "an infinite loop.");
+    Optional<StorageType> min;
+    Optional<Key> minKey;
+    source | [&](Value v) {
+      Key key = selector_(std::forward<Value>(v));
+      if (!minKey.hasValue() || comparer_(key, minKey.value())) {
+        minKey = key;
+        min = std::forward<Value>(v);
       }
-      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_);
+    };
+    return min;
   }
+};
 
-  template<class Source,
-           class Value,
-           class Gen = Generator<Value, Source>>
-  Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self(), limit_);
-  }
+/**
+ * Append - For collecting values from a source into a given output container
+ * by appending.
+ *
+ * This type is usually used through the helper function 'appendTo', like:
+ *
+ *   vector<int64_t> ids;
+ *   from(results) | map([](Person& p) { return p.id })
+ *                 | appendTo(ids);
+ */
+template <class Collection>
+class Append : public Operator<Append<Collection>> {
+  Collection* collection_;
 
-  /**
-   * Convenience function for use like:
-   *
-   *  auto tripled = gen | cycle(3);
-   */
-  Cycle operator()(off_t limit) const {
-    return Cycle(limit);
+ public:
+  explicit Append(Collection* collection) : collection_(collection) {}
+
+  template <class Value, class Source>
+  Collection& compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite, "Cannot appendTo with infinite source");
+    source | [&](Value v) {
+      collection_->insert(collection_->end(), std::forward<Value>(v));
+    };
+    return *collection_;
   }
 };
 
 /**
- * Dereference - For dereferencing a sequence of pointers while filtering out
- * null pointers.
+ * Collect - For collecting values from a source in a collection of the desired
+ * type.
  *
- * This type is usually used through the 'dereference' static value, like:
+ * This type is usually used through the helper function 'as', like:
  *
- *   auto refs = from(ptrs) | dereference;
+ *   std::string upper = from(stringPiece)
+ *                     | map(&toupper)
+ *                     | as<std::string>();
  */
-class Dereference : public Operator<Dereference> {
+template <class Collection>
+class Collect : public Operator<Collect<Collection>> {
  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;
-      });
-    }
+  Collect() = default;
 
-    // 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());
+  template <class Value,
+            class Source,
+            class StorageType = typename std::decay<Value>::type>
+  Collection compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite,
+                  "Cannot convert infinite source to object with as.");
+    Collection collection;
+    source | [&](Value v) {
+      collection.insert(collection.end(), std::forward<Value>(v));
+    };
+    return collection;
   }
 };
 
 /**
- * Indirect - For producing a sequence of the addresses of the values in the
- * input.
+ * CollectTemplate - For collecting values from a source in a collection
+ * constructed using the specified template type. Given the type of values
+ * produced by the given generator, the collection type will be:
+ *   Container<Value, Allocator<Value>>
  *
- * This type is usually used through the 'indirect' static value, like:
+ * The allocator defaults to std::allocator, so this may be used for the STL
+ * containers by simply using operators like 'as<set>', 'as<deque>',
+ * 'as<vector>'. 'as', here is the helper method which is the usual means of
+ * constructing this operator.
  *
- *   auto ptrs = from(refs) | indirect;
+ * Example:
+ *
+ *   set<string> uniqueNames = from(names) | as<set>();
  */
-class Indirect : public Operator<Indirect> {
+template <template <class, class> class Container,
+          template <class> class Allocator>
+class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
  public:
-  Indirect() {}
+  CollectTemplate() = default;
 
   template <class Value,
             class Source,
-            class Result = typename std::remove_reference<Value>::type*>
-  class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
-    Source source_;
-    static_assert(!std::is_rvalue_reference<Value>::value,
-                  "Cannot use indirect on an rvalue");
+            class StorageType = typename std::decay<Value>::type,
+            class Collection = Container<StorageType, Allocator<StorageType>>>
+  Collection compose(const GenImpl<Value, Source>& source) const {
+    static_assert(!Source::infinite,
+                  "Cannot convert infinite source to object with as.");
+    Collection collection;
+    source | [&](Value v) {
+      collection.insert(collection.end(), std::forward<Value>(v));
+    };
+    return collection;
+  }
+};
 
-   public:
-    explicit Generator(Source source) : source_(std::move(source)) {}
+/**
+ * UnwrapOr - For unwrapping folly::Optional values, or providing the given
+ * fallback value. Usually used through the 'unwrapOr' helper like so:
+ *
+ *   auto best = from(scores) | max | unwrapOr(-1);
+ *
+ * Note that the fallback value needn't match the value in the Optional it is
+ * unwrapping. If mis-matched types are supported, the common type of the two is
+ * returned by value. If the types match, a reference (T&& > T& > const T&) is
+ * returned.
+ */
+template <class T>
+class UnwrapOr {
+ public:
+  explicit UnwrapOr(T&& value) : value_(std::move(value)) {}
+  explicit UnwrapOr(const T& value) : value_(value) {}
 
-    template <class Body>
-    void foreach (Body&& body) const {
-      source_.foreach([&](Value value) {
-        return body(&value);
-      });
-    }
+  T& value() { return value_; }
+  const T& value() const { return value_; }
 
-    template <class Handler>
-    bool apply(Handler&& handler) const {
-      return source_.apply([&](Value value) -> bool {
-        return handler(&value);
-      });
-    }
+ private:
+  T value_;
+};
 
-    // not actually infinite, since an empty generator will end the cycles.
-    static constexpr bool infinite = Source::infinite;
-  };
+template <class T>
+T&& operator|(Optional<T>&& opt, UnwrapOr<T>&& fallback) {
+  if (T* p = opt.get_pointer()) {
+    return std::move(*p);
+  }
+  return std::move(fallback.value());
+}
 
-  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 T>
+T& operator|(Optional<T>& opt, UnwrapOr<T>& fallback) {
+  if (T* p = opt.get_pointer()) {
+    return *p;
   }
+  return fallback.value();
+}
 
-  template <class Source, class Value, class Gen = Generator<Value, Source>>
-  Gen compose(const GenImpl<Value, Source>& source) const {
-    return Gen(source.self());
+template <class T>
+const T& operator|(const Optional<T>& opt, const UnwrapOr<T>& fallback) {
+  if (const T* p = opt.get_pointer()) {
+    return *p;
   }
-};
+  return fallback.value();
+}
+
+// Mixed type unwrapping always returns values, moving where possible
+template <class T,
+          class U,
+          class R = typename std::enable_if<
+              !std::is_same<T, U>::value,
+              typename std::common_type<T, U>::type>::type>
+R operator|(Optional<T>&& opt, UnwrapOr<U>&& fallback) {
+  if (T* p = opt.get_pointer()) {
+    return std::move(*p);
+  }
+  return std::move(fallback.value());
+}
+
+template <class T,
+          class U,
+          class R = typename std::enable_if<
+              !std::is_same<T, U>::value,
+              typename std::common_type<T, U>::type>::type>
+R operator|(const Optional<T>& opt, UnwrapOr<U>&& fallback) {
+  if (const T* p = opt.get_pointer()) {
+    return *p;
+  }
+  return std::move(fallback.value());
+}
+
+template <class T,
+          class U,
+          class R = typename std::enable_if<
+              !std::is_same<T, U>::value,
+              typename std::common_type<T, U>::type>::type>
+R operator|(Optional<T>&& opt, const UnwrapOr<U>& fallback) {
+  if (T* p = opt.get_pointer()) {
+    return std::move(*p);
+  }
+  return fallback.value();
+}
+
+template <class T,
+          class U,
+          class R = typename std::enable_if<
+              !std::is_same<T, U>::value,
+              typename std::common_type<T, U>::type>::type>
+R operator|(const Optional<T>& opt, const UnwrapOr<U>& fallback) {
+  if (const T* p = opt.get_pointer()) {
+    return *p;
+  }
+  return fallback.value();
+}
+
+/**
+ * Unwrap - For unwrapping folly::Optional values in a folly::gen style. Usually
+ * used through the 'unwrap' instace like so:
+ *
+ *   auto best = from(scores) | max | unwrap; // may throw
+ */
+class Unwrap {};
+
+template <class T>
+T&& operator|(Optional<T>&& opt, const Unwrap&) {
+  return std::move(opt.value());
+}
+
+template <class T>
+T& operator|(Optional<T>& opt, const Unwrap&) {
+  return opt.value();
+}
+
+template <class T>
+const T& operator|(const Optional<T>& opt, const Unwrap&) {
+  return opt.value();
+}
 
 } //::detail
 
 /**
  * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
  **/
-template<class Value>
+template <class Value>
 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
   class WrapperBase {
    public:
@@ -1940,13 +2221,12 @@ class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
     virtual std::unique_ptr<const WrapperBase> clone() const = 0;
   };
 
-  template<class Wrapped>
+  template <class Wrapped>
   class WrapperImpl : public WrapperBase {
     Wrapped wrapped_;
+
    public:
-    explicit WrapperImpl(Wrapped wrapped)
-     : wrapped_(std::move(wrapped)) {
-    }
+    explicit WrapperImpl(Wrapped wrapped) : wrapped_(std::move(wrapped)) {}
 
     virtual bool apply(const std::function<bool(Value)>& handler) const {
       return wrapped_.apply(handler);
@@ -1971,8 +2251,7 @@ class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
   VirtualGen(VirtualGen&& source) noexcept
       : wrapper_(std::move(source.wrapper_)) {}
 
-  VirtualGen(const VirtualGen& source)
-      : wrapper_(source.wrapper_->clone()) {}
+  VirtualGen(const VirtualGen& source) : wrapper_(source.wrapper_->clone()) {}
 
   VirtualGen& operator=(const VirtualGen& source) {
     wrapper_.reset(source.wrapper_->clone());
@@ -1980,7 +2259,7 @@ class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
   }
 
   VirtualGen& operator=(VirtualGen&& source) noexcept {
-    wrapper_= std::move(source.wrapper_);
+    wrapper_ = std::move(source.wrapper_);
     return *this;
   }
 
@@ -1997,68 +2276,59 @@ class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
  * non-template operators, statically defined to avoid the need for anything but
  * the header.
  */
-static const detail::Sum sum;
+constexpr detail::Sum sum{};
 
-static const detail::Count count;
+constexpr detail::Count count{};
 
-static const detail::First first;
+constexpr 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;
+constexpr detail::IsEmpty<true> isEmpty{};
 
-static const detail::Min<Identity, Less> min;
+constexpr detail::IsEmpty<false> notEmpty{};
 
-static const detail::Min<Identity, Greater> max;
+constexpr detail::Min<Identity, Less> min{};
 
-static const detail::Order<Identity> order;
+constexpr detail::Min<Identity, Greater> max{};
 
-static const detail::Distinct<Identity> distinct;
+constexpr detail::Order<Identity> order{};
 
-static const detail::Map<Move> move;
+constexpr detail::Distinct<Identity> distinct{};
 
-static const detail::Concat concat;
+constexpr detail::Map<Move> move{};
 
-static const detail::RangeConcat rconcat;
+constexpr detail::Concat concat{};
 
-/**
- * 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;
+constexpr detail::RangeConcat rconcat{};
 
-static const detail::Dereference dereference;
+constexpr detail::Cycle<true> cycle{};
 
-static const detail::Indirect indirect;
+constexpr detail::Dereference dereference{};
 
-inline detail::Take take(size_t count) {
-  return detail::Take(count);
-}
+constexpr detail::Indirect indirect{};
 
-inline detail::Stride stride(size_t s) {
-  return detail::Stride(s);
+constexpr detail::Unwrap unwrap{};
+
+template <class Number>
+inline detail::Take take(Number count) {
+  if (count < 0) {
+    throw std::invalid_argument("Negative value passed to take()");
+  }
+  return detail::Take(static_cast<size_t>(count));
 }
 
-template<class Random = std::default_random_engine>
+inline detail::Stride stride(size_t s) { return detail::Stride(s); }
+
+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);
-}
+inline detail::Skip skip(size_t count) { return detail::Skip(count); }
 
 inline detail::Batch batch(size_t batchSize) {
   return detail::Batch(batchSize);
 }
 
-}} //folly::gen
+}} // folly::gen
 
 #pragma GCC diagnostic pop