Consistently have the namespace closing comment
[folly.git] / folly / gen / Base-inl.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_GEN_BASE_H_
18 #error This file may only be included from folly/gen/Base.h
19 #endif
20
21 #include <folly/Portability.h>
22
23 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
24 FOLLY_PUSH_WARNING
25 FOLLY_GCC_DISABLE_WARNING("-Wshadow")
26
27 namespace folly {
28 namespace gen {
29
30 /**
31  * ArgumentReference - For determining ideal argument type to receive a value.
32  */
33 template <class T>
34 struct ArgumentReference
35     : public std::conditional<
36           std::is_reference<T>::value,
37           T, // T& -> T&, T&& -> T&&, const T& -> const T&
38           typename std::conditional<std::is_const<T>::value,
39                                     T&, // const int -> const int&
40                                     T&& // int -> int&&
41                                     >::type> {};
42
43 /**
44  * Group - The output objects from the GroupBy operator
45  */
46 template <class Key, class Value>
47 class Group : public GenImpl<Value&&, Group<Key, Value>> {
48  public:
49   static_assert(!std::is_reference<Key>::value &&
50                     !std::is_reference<Value>::value,
51                 "Key and Value must be decayed types");
52
53   typedef std::vector<Value> VectorType;
54   typedef Key KeyType;
55   typedef Value ValueType;
56
57   Group(Key key, VectorType values)
58       : key_(std::move(key)), values_(std::move(values)) {}
59
60   const Key& key() const { return key_; }
61
62   size_t size() const { return values_.size(); }
63   const VectorType& values() const { return values_; }
64   VectorType& values() { return values_; }
65
66   VectorType operator|(const detail::Collect<VectorType>&) const {
67     return values();
68   }
69
70   VectorType operator|(const detail::CollectTemplate<std::vector>&) const {
71     return values();
72   }
73
74   template <class Body>
75   void foreach(Body&& body) const {
76     for (auto& value : values_) {
77       body(std::move(value));
78     }
79   }
80
81   template <class Handler>
82   bool apply(Handler&& handler) const {
83     for (auto& value : values_) {
84       if (!handler(std::move(value))) {
85         return false;
86       }
87     }
88     return true;
89   }
90
91   // GroupBy only takes in finite generators, so we only have finite groups
92   static constexpr bool infinite = false;
93
94  private:
95   Key key_;
96   mutable VectorType values_;
97 };
98
99 namespace detail {
100
101 // Classes used for the implementation of Sources, Operators, and Sinks
102
103 /*
104  ******************************* Sources ***************************************
105  */
106
107 /*
108  * ReferencedSource - Generate values from an STL-like container using
109  * iterators from .begin() until .end(). Value type defaults to the type of
110  * *container->begin(). For std::vector<int>, this would be int&. Note that the
111  * value here is a reference, so the values in the vector will be passed by
112  * reference to downstream operators.
113  *
114  * This type is primarily used through the 'from' helper method, like:
115  *
116  *   string& longestName = from(names)
117  *                       | maxBy([](string& s) { return s.size() });
118  */
119 template <class Container, class Value>
120 class ReferencedSource
121     : public GenImpl<Value, ReferencedSource<Container, Value>> {
122   Container* container_;
123
124  public:
125   explicit ReferencedSource(Container* container) : container_(container) {}
126
127   template <class Body>
128   void foreach(Body&& body) const {
129     for (auto& value : *container_) {
130       body(std::forward<Value>(value));
131     }
132   }
133
134   template <class Handler>
135   bool apply(Handler&& handler) const {
136     for (auto& value : *container_) {
137       if (!handler(std::forward<Value>(value))) {
138         return false;
139       }
140     }
141     return true;
142   }
143
144   // from takes in a normal stl structure, which are all finite
145   static constexpr bool infinite = false;
146 };
147
148 /**
149  * CopiedSource - For producing values from eagerly from a sequence of values
150  * whose storage is owned by this class. Useful for preparing a generator for
151  * use after a source collection will no longer be available, or for when the
152  * values are specified literally with an initializer list.
153  *
154  * This type is primarily used through the 'fromCopy' function, like:
155  *
156  *   auto sourceCopy = fromCopy(makeAVector());
157  *   auto sum = sourceCopy | sum;
158  *   auto max = sourceCopy | max;
159  *
160  * Though it is also used for the initializer_list specialization of from().
161  */
162 template <class StorageType, class Container>
163 class CopiedSource
164     : public GenImpl<const StorageType&, CopiedSource<StorageType, Container>> {
165   static_assert(!std::is_reference<StorageType>::value,
166                 "StorageType must be decayed");
167
168  public:
169   // Generator objects are often copied during normal construction as they are
170   // encapsulated by downstream generators. It would be bad if this caused
171   // a copy of the entire container each time, and since we're only exposing a
172   // const reference to the value, it's safe to share it between multiple
173   // generators.
174   static_assert(!std::is_reference<Container>::value,
175                 "Can't copy into a reference");
176   std::shared_ptr<const Container> copy_;
177
178  public:
179   typedef Container ContainerType;
180
181   template <class SourceContainer>
182   explicit CopiedSource(const SourceContainer& container)
183       : copy_(new Container(begin(container), end(container))) {}
184
185   explicit CopiedSource(Container&& container)
186       : copy_(new Container(std::move(container))) {}
187
188   // To enable re-use of cached results.
189   CopiedSource(const CopiedSource<StorageType, Container>& source)
190       : copy_(source.copy_) {}
191
192   template <class Body>
193   void foreach(Body&& body) const {
194     for (const auto& value : *copy_) {
195       body(value);
196     }
197   }
198
199   template <class Handler>
200   bool apply(Handler&& handler) const {
201     // The collection may be reused by others, we can't allow it to be changed.
202     for (const auto& value : *copy_) {
203       if (!handler(value)) {
204         return false;
205       }
206     }
207     return true;
208   }
209
210   // from takes in a normal stl structure, which are all finite
211   static constexpr bool infinite = false;
212 };
213
214 /**
215  * RangeSource - For producing values from a folly::Range. Useful for referring
216  * to a slice of some container.
217  *
218  * This type is primarily used through the 'from' function, like:
219  *
220  *   auto rangeSource = from(folly::range(v.begin(), v.end()));
221  *   auto sum = rangeSource | sum;
222  *
223  * Reminder: Be careful not to invalidate iterators when using ranges like this.
224  */
225 template <class Iterator>
226 class RangeSource : public GenImpl<typename Range<Iterator>::reference,
227                                    RangeSource<Iterator>> {
228   Range<Iterator> range_;
229
230  public:
231   RangeSource() = default;
232   explicit RangeSource(Range<Iterator> range) : range_(std::move(range)) {}
233
234   template <class Handler>
235   bool apply(Handler&& handler) const {
236     for (auto& value : range_) {
237       if (!handler(value)) {
238         return false;
239       }
240     }
241     return true;
242   }
243
244   template <class Body>
245   void foreach(Body&& body) const {
246     for (auto& value : range_) {
247       body(value);
248     }
249   }
250
251   // folly::Range only supports finite ranges
252   static constexpr bool infinite = false;
253 };
254
255 /**
256  * Sequence - For generating values from beginning value, incremented along the
257  * way with the ++ and += operators. Iteration may continue indefinitely.
258  * Value type specified explicitly.
259  *
260  * This type is primarily used through the 'seq' and 'range' function, like:
261  *
262  *   int total = seq(1, 10) | sum;
263  *   auto indexes = range(0, 10);
264  *   auto endless = seq(0); // 0, 1, 2, 3, ...
265  */
266 template <class Value, class SequenceImpl>
267 class Sequence : public GenImpl<const Value&, Sequence<Value, SequenceImpl>> {
268   static_assert(!std::is_reference<Value>::value &&
269                     !std::is_const<Value>::value,
270                 "Value mustn't be const or ref.");
271   Value start_;
272   SequenceImpl impl_;
273
274  public:
275   explicit Sequence(Value start, SequenceImpl impl)
276       : start_(std::move(start)), impl_(std::move(impl)) {}
277
278   template <class Handler>
279   bool apply(Handler&& handler) const {
280     for (Value current = start_; impl_.test(current); impl_.step(current)) {
281       if (!handler(current)) {
282         return false;
283       }
284     }
285     return true;
286   }
287
288   template <class Body>
289   void foreach(Body&& body) const {
290     for (Value current = start_; impl_.test(current); impl_.step(current)) {
291       body(current);
292     }
293   }
294
295   // Let the implementation say if we are infinite or not
296   static constexpr bool infinite = SequenceImpl::infinite;
297 };
298
299 /**
300  * Sequence implementations (range, sequence, infinite, with/without step)
301  **/
302 template <class Value>
303 class RangeImpl {
304   Value end_;
305
306  public:
307   explicit RangeImpl(Value end) : end_(std::move(end)) {}
308   bool test(const Value& current) const { return current < end_; }
309   void step(Value& current) const { ++current; }
310   static constexpr bool infinite = false;
311 };
312
313 template <class Value, class Distance>
314 class RangeWithStepImpl {
315   Value end_;
316   Distance step_;
317
318  public:
319   explicit RangeWithStepImpl(Value end, Distance step)
320       : end_(std::move(end)), step_(std::move(step)) {}
321   bool test(const Value& current) const { return current < end_; }
322   void step(Value& current) const { current += step_; }
323   static constexpr bool infinite = false;
324 };
325
326 template <class Value>
327 class SeqImpl {
328   Value end_;
329
330  public:
331   explicit SeqImpl(Value end) : end_(std::move(end)) {}
332   bool test(const Value& current) const { return current <= end_; }
333   void step(Value& current) const { ++current; }
334   static constexpr bool infinite = false;
335 };
336
337 template <class Value, class Distance>
338 class SeqWithStepImpl {
339   Value end_;
340   Distance step_;
341
342  public:
343   explicit SeqWithStepImpl(Value end, Distance step)
344       : end_(std::move(end)), step_(std::move(step)) {}
345   bool test(const Value& current) const { return current <= end_; }
346   void step(Value& current) const { current += step_; }
347   static constexpr bool infinite = false;
348 };
349
350 template <class Value>
351 class InfiniteImpl {
352  public:
353   bool test(const Value& /* current */) const { return true; }
354   void step(Value& current) const { ++current; }
355   static constexpr bool infinite = true;
356 };
357
358 /**
359  * GenratorBuilder - Helper for GENERTATOR macro.
360  **/
361 template <class Value>
362 struct GeneratorBuilder {
363   template <class Source, class Yield = detail::Yield<Value, Source>>
364   Yield operator+(Source&& source) {
365     return Yield(std::forward<Source>(source));
366   }
367 };
368
369 /**
370  * Yield - For producing values from a user-defined generator by way of a
371  * 'yield' function.
372  **/
373 template <class Value, class Source>
374 class Yield : public GenImpl<Value, Yield<Value, Source>> {
375   Source source_;
376
377  public:
378   explicit Yield(Source source) : source_(std::move(source)) {}
379
380   template <class Handler>
381   bool apply(Handler&& handler) const {
382     struct Break {};
383     auto body = [&](Value value) {
384       if (!handler(std::forward<Value>(value))) {
385         throw Break();
386       }
387     };
388     try {
389       source_(body);
390       return true;
391     } catch (Break&) {
392       return false;
393     }
394   }
395
396   template <class Body>
397   void foreach(Body&& body) const {
398     source_(std::forward<Body>(body));
399   }
400 };
401
402 template <class Value>
403 class Empty : public GenImpl<Value, Empty<Value>> {
404  public:
405   template <class Handler>
406   bool apply(Handler&&) const {
407     return true;
408   }
409
410   template <class Body>
411   void foreach(Body&&) const {}
412
413   // No values, so finite
414   static constexpr bool infinite = false;
415 };
416
417 template <class Value>
418 class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
419   static_assert(!std::is_reference<Value>::value,
420                 "SingleReference requires non-ref types");
421   Value* ptr_;
422
423  public:
424   explicit SingleReference(Value& ref) : ptr_(&ref) {}
425
426   template <class Handler>
427   bool apply(Handler&& handler) const {
428     return handler(*ptr_);
429   }
430
431   template <class Body>
432   void foreach(Body&& body) const {
433     body(*ptr_);
434   }
435
436   // One value, so finite
437   static constexpr bool infinite = false;
438 };
439
440 template <class Value>
441 class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
442   static_assert(!std::is_reference<Value>::value,
443                 "SingleCopy requires non-ref types");
444   Value value_;
445
446  public:
447   explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
448
449   template <class Handler>
450   bool apply(Handler&& handler) const {
451     return handler(value_);
452   }
453
454   template <class Body>
455   void foreach(Body&& body) const {
456     body(value_);
457   }
458
459   // One value, so finite
460   static constexpr bool infinite = false;
461 };
462
463 /*
464  ***************************** Operators ***************************************
465  */
466
467 /**
468  * Map - For producing a sequence of values by passing each value from a source
469  * collection through a predicate.
470  *
471  * This type is usually used through the 'map' or 'mapped' helper function:
472  *
473  *   auto squares = seq(1, 10) | map(square) | as<std::vector>();
474  */
475 template <class Predicate>
476 class Map : public Operator<Map<Predicate>> {
477   Predicate pred_;
478
479  public:
480   Map() = default;
481
482   explicit Map(Predicate pred) : pred_(std::move(pred)) {}
483
484   template <
485       class Value,
486       class Source,
487       class Result = typename ArgumentReference<
488           typename std::result_of<Predicate(Value)>::type>::type>
489   class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
490     Source source_;
491     Predicate pred_;
492
493    public:
494     explicit Generator(Source source, const Predicate& pred)
495         : source_(std::move(source)), pred_(pred) {}
496
497     template <class Body>
498     void foreach(Body&& body) const {
499       source_.foreach(
500           [&](Value value) { body(pred_(std::forward<Value>(value))); });
501     }
502
503     template <class Handler>
504     bool apply(Handler&& handler) const {
505       return source_.apply([&](Value value) {
506         return handler(pred_(std::forward<Value>(value)));
507       });
508     }
509
510     static constexpr bool infinite = Source::infinite;
511   };
512
513   template <class Source, class Value, class Gen = Generator<Value, Source>>
514   Gen compose(GenImpl<Value, Source>&& source) const {
515     return Gen(std::move(source.self()), pred_);
516   }
517
518   template <class Source, class Value, class Gen = Generator<Value, Source>>
519   Gen compose(const GenImpl<Value, Source>& source) const {
520     return Gen(source.self(), pred_);
521   }
522 };
523
524 /**
525  * Filter - For filtering values from a source sequence by a predicate.
526  *
527  * This type is usually used through the 'filter' helper function, like:
528  *
529  *   auto nonEmpty = from(strings)
530  *                 | filter([](const string& str) -> bool {
531  *                     return !str.empty();
532  *                   });
533  *
534  * Note that if no predicate is provided, the values are casted to bool and
535  * filtered based on that. So if pointers is a vector of pointers,
536  *
537  *   auto nonNull = from(pointers) | filter();
538  *
539  * will give a vector of all the pointers != nullptr.
540  */
541 template <class Predicate>
542 class Filter : public Operator<Filter<Predicate>> {
543   Predicate pred_;
544
545  public:
546   Filter() = default;
547   explicit Filter(Predicate pred) : pred_(std::move(pred)) {}
548
549   template <class Value, class Source>
550   class Generator : public GenImpl<Value, Generator<Value, Source>> {
551     Source source_;
552     Predicate pred_;
553
554    public:
555     explicit Generator(Source source, const Predicate& pred)
556         : source_(std::move(source)), pred_(pred) {}
557
558     template <class Body>
559     void foreach(Body&& body) const {
560       source_.foreach([&](Value value) {
561         // NB: Argument not forwarded to avoid accidental move-construction
562         if (pred_(value)) {
563           body(std::forward<Value>(value));
564         }
565       });
566     }
567
568     template <class Handler>
569     bool apply(Handler&& handler) const {
570       return source_.apply([&](Value value) -> bool {
571         // NB: Argument not forwarded to avoid accidental move-construction
572         if (pred_(value)) {
573           return handler(std::forward<Value>(value));
574         }
575         return true;
576       });
577     }
578
579     static constexpr bool infinite = Source::infinite;
580   };
581
582   template <class Source, class Value, class Gen = Generator<Value, Source>>
583   Gen compose(GenImpl<Value, Source>&& source) const {
584     return Gen(std::move(source.self()), pred_);
585   }
586
587   template <class Source, class Value, class Gen = Generator<Value, Source>>
588   Gen compose(const GenImpl<Value, Source>& source) const {
589     return Gen(source.self(), pred_);
590   }
591 };
592
593 /**
594  * Until - For producing values from a source until a predicate is satisfied.
595  *
596  * This type is usually used through the 'until' helper function, like:
597  *
598  *   auto best = from(sortedItems)
599  *             | until([](Item& item) { return item.score > 100; })
600  *             | as<std::vector>();
601  */
602 template <class Predicate>
603 class Until : public Operator<Until<Predicate>> {
604   Predicate pred_;
605
606  public:
607   Until() = default;
608   explicit Until(Predicate pred) : pred_(std::move(pred)) {}
609
610   template <class Value, class Source>
611   class Generator : public GenImpl<Value, Generator<Value, Source>> {
612     Source source_;
613     Predicate pred_;
614
615    public:
616     explicit Generator(Source source, const Predicate& pred)
617         : source_(std::move(source)), pred_(pred) {}
618
619     template <class Handler>
620     bool apply(Handler&& handler) const {
621       bool cancelled = false;
622       source_.apply([&](Value value) -> bool {
623         if (pred_(value)) { // un-forwarded to disable move
624           return false;
625         }
626         if (!handler(std::forward<Value>(value))) {
627           cancelled = true;
628           return false;
629         }
630         return true;
631       });
632       return !cancelled;
633     }
634
635     // Theoretically an 'until' might stop an infinite
636     static constexpr bool infinite = false;
637   };
638
639   template <class Source, class Value, class Gen = Generator<Value, Source>>
640   Gen compose(GenImpl<Value, Source>&& source) const {
641     return Gen(std::move(source.self()), pred_);
642   }
643
644   template <class Source, class Value, class Gen = Generator<Value, Source>>
645   Gen compose(const GenImpl<Value, Source>& source) const {
646     return Gen(source.self(), pred_);
647   }
648 };
649
650 /**
651  * Take - For producing up to N values from a source.
652  *
653  * This type is usually used through the 'take' helper function, like:
654  *
655  *   auto best = from(docs)
656  *             | orderByDescending(scoreDoc)
657  *             | take(10);
658  */
659 class Take : public Operator<Take> {
660   size_t count_;
661
662  public:
663   explicit Take(size_t count) : count_(count) {}
664
665   template <class Value, class Source>
666   class Generator : public GenImpl<Value, Generator<Value, Source>> {
667     Source source_;
668     size_t count_;
669
670    public:
671     explicit Generator(Source source, size_t count)
672         : source_(std::move(source)), count_(count) {}
673
674     template <class Handler>
675     bool apply(Handler&& handler) const {
676       if (count_ == 0) {
677         return false;
678       }
679       size_t n = count_;
680       bool cancelled = false;
681       source_.apply([&](Value value) -> bool {
682         if (!handler(std::forward<Value>(value))) {
683           cancelled = true;
684           return false;
685         }
686         return --n;
687       });
688       return !cancelled;
689     }
690
691     // take will stop an infinite generator
692     static constexpr bool infinite = false;
693   };
694
695   template <class Source, class Value, class Gen = Generator<Value, Source>>
696   Gen compose(GenImpl<Value, Source>&& source) const {
697     return Gen(std::move(source.self()), count_);
698   }
699
700   template <class Source, class Value, class Gen = Generator<Value, Source>>
701   Gen compose(const GenImpl<Value, Source>& source) const {
702     return Gen(source.self(), count_);
703   }
704 };
705
706 /**
707  * Visit - For calling a function on each item before passing it down the
708  * pipeline.
709  *
710  * This type is usually used through the 'visit' helper function:
711  *
712  *   auto printedValues = seq(1) | visit(debugPrint);
713  *   // nothing printed yet
714  *   auto results = take(10) | as<std::vector>();
715  *   // results now populated, 10 values printed
716  */
717 template <class Visitor>
718 class Visit : public Operator<Visit<Visitor>> {
719   Visitor visitor_;
720
721  public:
722   Visit() = default;
723
724   explicit Visit(Visitor visitor) : visitor_(std::move(visitor)) {}
725
726   template <class Value, class Source>
727   class Generator : public GenImpl<Value, Generator<Value, Source>> {
728     Source source_;
729     Visitor visitor_;
730
731    public:
732     explicit Generator(Source source, const Visitor& visitor)
733         : source_(std::move(source)), visitor_(visitor) {}
734
735     template <class Body>
736     void foreach(Body&& body) const {
737       source_.foreach([&](Value value) {
738         visitor_(value); // not forwarding to avoid accidental moves
739         body(std::forward<Value>(value));
740       });
741     }
742
743     template <class Handler>
744     bool apply(Handler&& handler) const {
745       return source_.apply([&](Value value) {
746         visitor_(value); // not forwarding to avoid accidental moves
747         return handler(std::forward<Value>(value));
748       });
749     }
750
751     static constexpr bool infinite = Source::infinite;
752   };
753
754   template <class Source, class Value, class Gen = Generator<Value, Source>>
755   Gen compose(GenImpl<Value, Source>&& source) const {
756     return Gen(std::move(source.self()), visitor_);
757   }
758
759   template <class Source, class Value, class Gen = Generator<Value, Source>>
760   Gen compose(const GenImpl<Value, Source>& source) const {
761     return Gen(source.self(), visitor_);
762   }
763 };
764
765 /**
766  * Stride - For producing every Nth value from a source.
767  *
768  * This type is usually used through the 'stride' helper function, like:
769  *
770  *   auto half = from(samples)
771  *             | stride(2);
772  */
773 class Stride : public Operator<Stride> {
774   size_t stride_;
775
776  public:
777   explicit Stride(size_t stride) : stride_(stride) {
778     if (stride == 0) {
779       throw std::invalid_argument("stride must not be 0");
780     }
781   }
782
783   template <class Value, class Source>
784   class Generator : public GenImpl<Value, Generator<Value, Source>> {
785     Source source_;
786     size_t stride_;
787
788    public:
789     explicit Generator(Source source, size_t stride)
790         : source_(std::move(source)), stride_(stride) {}
791
792     template <class Handler>
793     bool apply(Handler&& handler) const {
794       size_t distance = stride_;
795       return source_.apply([&](Value value) -> bool {
796         if (++distance >= stride_) {
797           if (!handler(std::forward<Value>(value))) {
798             return false;
799           }
800           distance = 0;
801         }
802         return true;
803       });
804     }
805
806     template <class Body>
807     void foreach(Body&& body) const {
808       size_t distance = stride_;
809       source_.foreach([&](Value value) {
810         if (++distance >= stride_) {
811           body(std::forward<Value>(value));
812           distance = 0;
813         }
814       });
815     }
816
817     // Taking every Nth of an infinite list is still infinte
818     static constexpr bool infinite = Source::infinite;
819   };
820
821   template <class Source, class Value, class Gen = Generator<Value, Source>>
822   Gen compose(GenImpl<Value, Source>&& source) const {
823     return Gen(std::move(source.self()), stride_);
824   }
825
826   template <class Source, class Value, class Gen = Generator<Value, Source>>
827   Gen compose(const GenImpl<Value, Source>& source) const {
828     return Gen(source.self(), stride_);
829   }
830 };
831
832 /**
833  * Sample - For taking a random sample of N elements from a sequence
834  * (without replacement).
835  */
836 template <class Random>
837 class Sample : public Operator<Sample<Random>> {
838   size_t count_;
839   Random rng_;
840
841  public:
842   explicit Sample(size_t count, Random rng)
843       : count_(count), rng_(std::move(rng)) {}
844
845   template <
846       class Value,
847       class Source,
848       class Rand,
849       class StorageType = typename std::decay<Value>::type>
850   class Generator
851       : public GenImpl<StorageType&&,
852                        Generator<Value, Source, Rand, StorageType>> {
853     static_assert(!Source::infinite, "Cannot sample infinite source!");
854     // It's too easy to bite ourselves if random generator is only 16-bit
855     static_assert(Random::max() >= std::numeric_limits<int32_t>::max() - 1,
856                   "Random number generator must support big values");
857     Source source_;
858     size_t count_;
859     mutable Rand rng_;
860
861    public:
862     explicit Generator(Source source, size_t count, Random rng)
863         : source_(std::move(source)), count_(count), rng_(std::move(rng)) {}
864
865     template <class Handler>
866     bool apply(Handler&& handler) const {
867       if (count_ == 0) {
868         return false;
869       }
870       std::vector<StorageType> v;
871       v.reserve(count_);
872       // use reservoir sampling to give each source value an equal chance
873       // of appearing in our output.
874       size_t n = 1;
875       source_.foreach([&](Value value) -> void {
876         if (v.size() < count_) {
877           v.push_back(std::forward<Value>(value));
878         } else {
879           // alternatively, we could create a std::uniform_int_distribution
880           // instead of using modulus, but benchmarks show this has
881           // substantial overhead.
882           size_t index = rng_() % n;
883           if (index < v.size()) {
884             v[index] = std::forward<Value>(value);
885           }
886         }
887         ++n;
888       });
889
890       // output is unsorted!
891       for (auto& val : v) {
892         if (!handler(std::move(val))) {
893           return false;
894         }
895       }
896       return true;
897     }
898
899     // Only takes N elements, so finite
900     static constexpr bool infinite = false;
901   };
902
903   template <
904       class Source,
905       class Value,
906       class Gen = Generator<Value, Source, Random>>
907   Gen compose(GenImpl<Value, Source>&& source) const {
908     return Gen(std::move(source.self()), count_, rng_);
909   }
910
911   template <
912       class Source,
913       class Value,
914       class Gen = Generator<Value, Source, Random>>
915   Gen compose(const GenImpl<Value, Source>& source) const {
916     return Gen(source.self(), count_, rng_);
917   }
918 };
919
920 /**
921  * Skip - For skipping N items from the beginning of a source generator.
922  *
923  * This type is usually used through the 'skip' helper function, like:
924  *
925  *   auto page = from(results)
926  *             | skip(pageSize * startPage)
927  *             | take(10);
928  */
929 class Skip : public Operator<Skip> {
930   size_t count_;
931
932  public:
933   explicit Skip(size_t count) : count_(count) {}
934
935   template <class Value, class Source>
936   class Generator : public GenImpl<Value, Generator<Value, Source>> {
937     Source source_;
938     size_t count_;
939
940    public:
941     explicit Generator(Source source, size_t count)
942         : source_(std::move(source)), count_(count) {}
943
944     template <class Body>
945     void foreach(Body&& body) const {
946       if (count_ == 0) {
947         source_.foreach(body);
948         return;
949       }
950       size_t n = 0;
951       source_.foreach([&](Value value) {
952         if (n < count_) {
953           ++n;
954         } else {
955           body(std::forward<Value>(value));
956         }
957       });
958     }
959
960     template <class Handler>
961     bool apply(Handler&& handler) const {
962       if (count_ == 0) {
963         return source_.apply(std::forward<Handler>(handler));
964       }
965       size_t n = 0;
966       return source_.apply([&](Value value) -> bool {
967         if (n < count_) {
968           ++n;
969           return true;
970         }
971         return handler(std::forward<Value>(value));
972       });
973     }
974
975     // Skipping N items of an infinite source is still infinite
976     static constexpr bool infinite = Source::infinite;
977   };
978
979   template <class Source, class Value, class Gen = Generator<Value, Source>>
980   Gen compose(GenImpl<Value, Source>&& source) const {
981     return Gen(std::move(source.self()), count_);
982   }
983
984   template <class Source, class Value, class Gen = Generator<Value, Source>>
985   Gen compose(const GenImpl<Value, Source>& source) const {
986     return Gen(source.self(), count_);
987   }
988 };
989
990 /**
991  * Order - For ordering a sequence of values from a source by key.
992  * The key is extracted by the given selector functor, and this key is then
993  * compared using the specified comparator.
994  *
995  * This type is usually used through the 'order' helper function, like:
996  *
997  *   auto closest = from(places)
998  *                | orderBy([](Place& p) {
999  *                    return -distance(p.location, here);
1000  *                  })
1001  *                | take(10);
1002  */
1003 template <class Selector, class Comparer>
1004 class Order : public Operator<Order<Selector, Comparer>> {
1005   Selector selector_;
1006   Comparer comparer_;
1007
1008  public:
1009   Order() = default;
1010
1011   explicit Order(Selector selector) : selector_(std::move(selector)) {}
1012
1013   Order(Selector selector, Comparer comparer)
1014       : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
1015
1016   template <
1017       class Value,
1018       class Source,
1019       class StorageType = typename std::decay<Value>::type,
1020       class Result = typename std::result_of<Selector(Value)>::type>
1021   class Generator
1022       : public GenImpl<StorageType&&,
1023                        Generator<Value, Source, StorageType, Result>> {
1024     static_assert(!Source::infinite, "Cannot sort infinite source!");
1025     Source source_;
1026     Selector selector_;
1027     Comparer comparer_;
1028
1029     typedef std::vector<StorageType> VectorType;
1030
1031     VectorType asVector() const {
1032       auto comparer = [&](const StorageType& a, const StorageType& b) {
1033         return comparer_(selector_(a), selector_(b));
1034       };
1035       auto vals = source_ | as<VectorType>();
1036       std::sort(vals.begin(), vals.end(), comparer);
1037       return std::move(vals);
1038     }
1039
1040    public:
1041     Generator(Source source, Selector selector, Comparer comparer)
1042         : source_(std::move(source)),
1043           selector_(std::move(selector)),
1044           comparer_(std::move(comparer)) {}
1045
1046     VectorType operator|(const Collect<VectorType>&) const {
1047       return asVector();
1048     }
1049
1050     VectorType operator|(const CollectTemplate<std::vector>&) const {
1051       return asVector();
1052     }
1053
1054     template <class Body>
1055     void foreach(Body&& body) const {
1056       for (auto& value : asVector()) {
1057         body(std::move(value));
1058       }
1059     }
1060
1061     template <class Handler>
1062     bool apply(Handler&& handler) const {
1063       auto comparer = [&](const StorageType& a, const StorageType& b) {
1064         // swapped for minHeap
1065         return comparer_(selector_(b), selector_(a));
1066       };
1067       auto heap = source_ | as<VectorType>();
1068       std::make_heap(heap.begin(), heap.end(), comparer);
1069       while (!heap.empty()) {
1070         std::pop_heap(heap.begin(), heap.end(), comparer);
1071         if (!handler(std::move(heap.back()))) {
1072           return false;
1073         }
1074         heap.pop_back();
1075       }
1076       return true;
1077     }
1078
1079     // Can only be run on and produce finite generators
1080     static constexpr bool infinite = false;
1081   };
1082
1083   template <class Source, class Value, class Gen = Generator<Value, Source>>
1084   Gen compose(GenImpl<Value, Source>&& source) const {
1085     return Gen(std::move(source.self()), selector_, comparer_);
1086   }
1087
1088   template <class Source, class Value, class Gen = Generator<Value, Source>>
1089   Gen compose(const GenImpl<Value, Source>& source) const {
1090     return Gen(source.self(), selector_, comparer_);
1091   }
1092 };
1093
1094 /**
1095  * GroupBy - Group values by a given key selector, producing a sequence of
1096  * groups.
1097  *
1098  * This type is usually used through the 'groupBy' helper function, like:
1099  *
1100  *   auto bests
1101  *     = from(places)
1102  *     | groupBy([](const Place& p) {
1103  *         return p.city;
1104  *       })
1105  *     | [](Group<std::string, Place>&& g) {
1106  *         cout << g.key() << ": " << (g | first).description;
1107  *       };
1108  */
1109 template <class Selector>
1110 class GroupBy : public Operator<GroupBy<Selector>> {
1111   Selector selector_;
1112
1113  public:
1114   GroupBy() {}
1115
1116   explicit GroupBy(Selector selector) : selector_(std::move(selector)) {}
1117
1118   template <
1119       class Value,
1120       class Source,
1121       class ValueDecayed = typename std::decay<Value>::type,
1122       class Key = typename std::result_of<Selector(Value)>::type,
1123       class KeyDecayed = typename std::decay<Key>::type>
1124   class Generator
1125       : public GenImpl<
1126             Group<KeyDecayed, ValueDecayed>&&,
1127             Generator<Value, Source, ValueDecayed, Key, KeyDecayed>> {
1128     static_assert(!Source::infinite, "Cannot group infinite source!");
1129     Source source_;
1130     Selector selector_;
1131
1132    public:
1133     Generator(Source source, Selector selector)
1134         : source_(std::move(source)), selector_(std::move(selector)) {}
1135
1136     typedef Group<KeyDecayed, ValueDecayed> GroupType;
1137
1138     template <class Handler>
1139     bool apply(Handler&& handler) const {
1140       std::unordered_map<KeyDecayed, typename GroupType::VectorType> groups;
1141       source_ | [&](Value value) {
1142         const Value& cv = value;
1143         auto& group = groups[selector_(cv)];
1144         group.push_back(std::forward<Value>(value));
1145       };
1146       for (auto& kg : groups) {
1147         GroupType group(kg.first, std::move(kg.second));
1148         if (!handler(std::move(group))) {
1149           return false;
1150         }
1151         kg.second.clear();
1152       }
1153       return true;
1154     }
1155
1156     // Can only be run on and produce finite generators
1157     static constexpr bool infinite = false;
1158   };
1159
1160   template <class Source, class Value, class Gen = Generator<Value, Source>>
1161   Gen compose(GenImpl<Value, Source>&& source) const {
1162     return Gen(std::move(source.self()), selector_);
1163   }
1164
1165   template <class Source, class Value, class Gen = Generator<Value, Source>>
1166   Gen compose(const GenImpl<Value, Source>& source) const {
1167     return Gen(source.self(), selector_);
1168   }
1169 };
1170
1171 /*
1172  * TypeAssertion - For verifying the exact type of the value produced by a
1173  * generator. Useful for testing and debugging, and acts as a no-op at runtime.
1174  * Pass-through at runtime. Used through the 'assert_type<>()' factory method
1175  * like so:
1176  *
1177  *   auto c =  from(vector) | assert_type<int&>() | sum;
1178  *
1179  */
1180 template <class Expected>
1181 class TypeAssertion : public Operator<TypeAssertion<Expected>> {
1182  public:
1183   template <class Source, class Value>
1184   const Source& compose(const GenImpl<Value, Source>& source) const {
1185     static_assert(std::is_same<Expected, Value>::value,
1186                   "assert_type() check failed");
1187     return source.self();
1188   }
1189
1190   template <class Source, class Value>
1191   Source&& compose(GenImpl<Value, Source>&& source) const {
1192     static_assert(std::is_same<Expected, Value>::value,
1193                   "assert_type() check failed");
1194     return std::move(source.self());
1195   }
1196 };
1197
1198 /**
1199  * Distinct - For filtering duplicates out of a sequence. A selector may be
1200  * provided to generate a key to uniquify for each value.
1201  *
1202  * This type is usually used through the 'distinct' helper function, like:
1203  *
1204  *   auto closest = from(results)
1205  *                | distinctBy([](Item& i) {
1206  *                    return i.target;
1207  *                  })
1208  *                | take(10);
1209  */
1210 template <class Selector>
1211 class Distinct : public Operator<Distinct<Selector>> {
1212   Selector selector_;
1213
1214  public:
1215   Distinct() = default;
1216
1217   explicit Distinct(Selector selector) : selector_(std::move(selector)) {}
1218
1219   template <class Value, class Source>
1220   class Generator : public GenImpl<Value, Generator<Value, Source>> {
1221     Source source_;
1222     Selector selector_;
1223
1224     typedef typename std::decay<Value>::type StorageType;
1225
1226     // selector_ cannot be passed an rvalue or it would end up passing the husk
1227     // of a value to the downstream operators.
1228     typedef const StorageType& ParamType;
1229
1230     typedef typename std::result_of<Selector(ParamType)>::type KeyType;
1231     typedef typename std::decay<KeyType>::type KeyStorageType;
1232
1233    public:
1234     Generator(Source source, Selector selector)
1235         : source_(std::move(source)), selector_(std::move(selector)) {}
1236
1237     template <class Body>
1238     void foreach(Body&& body) const {
1239       std::unordered_set<KeyStorageType> keysSeen;
1240       source_.foreach([&](Value value) {
1241         if (keysSeen.insert(selector_(ParamType(value))).second) {
1242           body(std::forward<Value>(value));
1243         }
1244       });
1245     }
1246
1247     template <class Handler>
1248     bool apply(Handler&& handler) const {
1249       std::unordered_set<KeyStorageType> keysSeen;
1250       return source_.apply([&](Value value) -> bool {
1251         if (keysSeen.insert(selector_(ParamType(value))).second) {
1252           return handler(std::forward<Value>(value));
1253         }
1254         return true;
1255       });
1256     }
1257
1258     // While running distinct on an infinite sequence might produce a
1259     // conceptually finite sequence, it will take infinite time
1260     static constexpr bool infinite = Source::infinite;
1261   };
1262
1263   template <class Source, class Value, class Gen = Generator<Value, Source>>
1264   Gen compose(GenImpl<Value, Source>&& source) const {
1265     return Gen(std::move(source.self()), selector_);
1266   }
1267
1268   template <class Source, class Value, class Gen = Generator<Value, Source>>
1269   Gen compose(const GenImpl<Value, Source>& source) const {
1270     return Gen(source.self(), selector_);
1271   }
1272 };
1273
1274 /**
1275  * Composer - Helper class for adapting pipelines into functors. Primarily used
1276  * for 'mapOp'.
1277  */
1278 template <class Operators>
1279 class Composer {
1280   Operators op_;
1281
1282  public:
1283   explicit Composer(Operators op) : op_(std::move(op)) {}
1284
1285   template <
1286       class Source,
1287       class Ret =
1288           decltype(std::declval<Operators>().compose(std::declval<Source>()))>
1289   Ret operator()(Source&& source) const {
1290     return op_.compose(std::forward<Source>(source));
1291   }
1292 };
1293
1294 /**
1295  * Batch - For producing fixed-size batches of each value from a source.
1296  *
1297  * This type is usually used through the 'batch' helper function:
1298  *
1299  *   auto batchSums
1300  *     = seq(1, 10)
1301  *     | batch(3)
1302  *     | map([](const std::vector<int>& batch) {
1303  *         return from(batch) | sum;
1304  *       })
1305  *     | as<vector>();
1306  */
1307 class Batch : public Operator<Batch> {
1308   size_t batchSize_;
1309
1310  public:
1311   explicit Batch(size_t batchSize) : batchSize_(batchSize) {
1312     if (batchSize_ == 0) {
1313       throw std::invalid_argument("Batch size must be non-zero!");
1314     }
1315   }
1316
1317   template <
1318       class Value,
1319       class Source,
1320       class StorageType = typename std::decay<Value>::type,
1321       class VectorType = std::vector<StorageType>>
1322   class Generator
1323       : public GenImpl<VectorType&,
1324                        Generator<Value, Source, StorageType, VectorType>> {
1325     Source source_;
1326     size_t batchSize_;
1327
1328    public:
1329     explicit Generator(Source source, size_t batchSize)
1330         : source_(std::move(source)), batchSize_(batchSize) {}
1331
1332     template <class Handler>
1333     bool apply(Handler&& handler) const {
1334       VectorType batch_;
1335       batch_.reserve(batchSize_);
1336       bool shouldContinue = source_.apply([&](Value value) -> bool {
1337         batch_.push_back(std::forward<Value>(value));
1338         if (batch_.size() == batchSize_) {
1339           bool needMore = handler(batch_);
1340           batch_.clear();
1341           return needMore;
1342         }
1343         // Always need more if the handler is not called.
1344         return true;
1345       });
1346       // Flush everything, if and only if `handler` hasn't returned false.
1347       if (shouldContinue && !batch_.empty()) {
1348         shouldContinue = handler(batch_);
1349         batch_.clear();
1350       }
1351       return shouldContinue;
1352     }
1353
1354     // Taking n-tuples of an infinite source is still infinite
1355     static constexpr bool infinite = Source::infinite;
1356   };
1357
1358   template <class Source, class Value, class Gen = Generator<Value, Source>>
1359   Gen compose(GenImpl<Value, Source>&& source) const {
1360     return Gen(std::move(source.self()), batchSize_);
1361   }
1362
1363   template <class Source, class Value, class Gen = Generator<Value, Source>>
1364   Gen compose(const GenImpl<Value, Source>& source) const {
1365     return Gen(source.self(), batchSize_);
1366   }
1367 };
1368
1369 /**
1370  * Window - For overlapping the lifetimes of pipeline values, especially with
1371  * Futures.
1372  *
1373  * This type is usually used through the 'window' helper function:
1374  *
1375  *   auto responses
1376  *     = byLine(STDIN)
1377  *     | map(makeRequestFuture)
1378  *     | window(1000)
1379  *     | map(waitFuture)
1380  *     | as<vector>();
1381  */
1382 class Window : public Operator<Window> {
1383   size_t windowSize_;
1384
1385  public:
1386   explicit Window(size_t windowSize) : windowSize_(windowSize) {
1387     if (windowSize_ == 0) {
1388       throw std::invalid_argument("Window size must be non-zero!");
1389     }
1390   }
1391
1392   template <
1393       class Value,
1394       class Source,
1395       class StorageType = typename std::decay<Value>::type>
1396   class Generator
1397       : public GenImpl<StorageType&&, Generator<Value, Source, StorageType>> {
1398     Source source_;
1399     size_t windowSize_;
1400
1401    public:
1402     explicit Generator(Source source, size_t windowSize)
1403         : source_(std::move(source)), windowSize_(windowSize) {}
1404
1405     template <class Handler>
1406     bool apply(Handler&& handler) const {
1407       std::vector<StorageType> buffer;
1408       buffer.reserve(windowSize_);
1409       size_t readIndex = 0;
1410       bool shouldContinue = source_.apply([&](Value value) -> bool {
1411         if (buffer.size() < windowSize_) {
1412           buffer.push_back(std::forward<Value>(value));
1413         } else {
1414           StorageType& entry = buffer[readIndex++];
1415           if (readIndex == windowSize_) {
1416             readIndex = 0;
1417           }
1418           if (!handler(std::move(entry))) {
1419             return false;
1420           }
1421           entry = std::forward<Value>(value);
1422         }
1423         return true;
1424       });
1425       if (!shouldContinue) {
1426         return false;
1427       }
1428       if (buffer.size() < windowSize_) {
1429         for (StorageType& entry : buffer) {
1430           if (!handler(std::move(entry))) {
1431             return false;
1432           }
1433         }
1434       } else {
1435         for (size_t i = readIndex;;) {
1436           StorageType& entry = buffer[i++];
1437           if (!handler(std::move(entry))) {
1438             return false;
1439           }
1440           if (i == windowSize_) {
1441             i = 0;
1442           }
1443           if (i == readIndex) {
1444             break;
1445           }
1446         }
1447       }
1448       return true;
1449     }
1450
1451     // Taking n-tuples of an infinite source is still infinite
1452     static constexpr bool infinite = Source::infinite;
1453   };
1454
1455   template <class Source, class Value, class Gen = Generator<Value, Source>>
1456   Gen compose(GenImpl<Value, Source>&& source) const {
1457     return Gen(std::move(source.self()), windowSize_);
1458   }
1459
1460   template <class Source, class Value, class Gen = Generator<Value, Source>>
1461   Gen compose(const GenImpl<Value, Source>& source) const {
1462     return Gen(source.self(), windowSize_);
1463   }
1464 };
1465
1466 /**
1467  * Concat - For flattening generators of generators.
1468  *
1469  * This type is usually used through the 'concat' static value, like:
1470  *
1471  *   auto edges =
1472  *       from(nodes)
1473  *     | map([](Node& x) {
1474  *           return from(x.neighbors)
1475  *                | map([&](Node& y) {
1476  *                    return Edge(x, y);
1477  *                  });
1478  *         })
1479  *     | concat
1480  *     | as<std::set>();
1481  */
1482 class Concat : public Operator<Concat> {
1483  public:
1484   Concat() = default;
1485
1486   template <
1487       class Inner,
1488       class Source,
1489       class InnerValue = typename std::decay<Inner>::type::ValueType>
1490   class Generator
1491       : public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
1492     Source source_;
1493
1494    public:
1495     explicit Generator(Source source) : source_(std::move(source)) {}
1496
1497     template <class Handler>
1498     bool apply(Handler&& handler) const {
1499       return source_.apply([&](Inner inner) -> bool {
1500         return inner.apply(std::forward<Handler>(handler));
1501       });
1502     }
1503
1504     template <class Body>
1505     void foreach(Body&& body) const {
1506       source_.foreach([&](Inner inner) {
1507         inner.foreach(std::forward<Body>(body));
1508       });
1509     }
1510
1511     // Resulting concatination is only finite if both Source and Inner are also
1512     // finite. In one sence, if dosn't make sence to call concat when the Inner
1513     // generator is infinite (you could just call first), so we could also just
1514     // static_assert if the inner is infinite. Taking the less restrictive
1515     // approch for now.
1516     static constexpr bool infinite =
1517         Source::infinite || std::decay<Inner>::type::infinite;
1518   };
1519
1520   template <class Value, class Source, class Gen = Generator<Value, Source>>
1521   Gen compose(GenImpl<Value, Source>&& source) const {
1522     return Gen(std::move(source.self()));
1523   }
1524
1525   template <class Value, class Source, class Gen = Generator<Value, Source>>
1526   Gen compose(const GenImpl<Value, Source>& source) const {
1527     return Gen(source.self());
1528   }
1529 };
1530
1531 /**
1532  * RangeConcat - For flattening generators of iterables.
1533  *
1534  * This type is usually used through the 'rconcat' static value, like:
1535  *
1536  *   map<int, vector<int>> adjacency;
1537  *   auto sinks =
1538  *       from(adjacency)
1539  *     | get<1>()
1540  *     | rconcat()
1541  *     | as<std::set>();
1542  */
1543 class RangeConcat : public Operator<RangeConcat> {
1544  public:
1545   RangeConcat() = default;
1546
1547   template <
1548       class Range,
1549       class Source,
1550       class InnerValue = typename ValueTypeOfRange<Range>::RefType>
1551   class Generator
1552       : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
1553     Source source_;
1554
1555    public:
1556     explicit Generator(Source source) : source_(std::move(source)) {}
1557
1558     template <class Body>
1559     void foreach(Body&& body) const {
1560       source_.foreach([&](Range range) {
1561         for (auto& value : range) {
1562           body(value);
1563         }
1564       });
1565     }
1566
1567     template <class Handler>
1568     bool apply(Handler&& handler) const {
1569       return source_.apply([&](Range range) -> bool {
1570         for (auto& value : range) {
1571           if (!handler(value)) {
1572             return false;
1573           }
1574         }
1575         return true;
1576       });
1577     }
1578
1579     // This is similar to concat, except that the inner iterables all are finite
1580     // so the only thing that matters is that the source is infinite.
1581     static constexpr bool infinite = Source::infinite;
1582   };
1583
1584   template <class Value, class Source, class Gen = Generator<Value, Source>>
1585   Gen compose(GenImpl<Value, Source>&& source) const {
1586     return Gen(std::move(source.self()));
1587   }
1588
1589   template <class Value, class Source, class Gen = Generator<Value, Source>>
1590   Gen compose(const GenImpl<Value, Source>& source) const {
1591     return Gen(source.self());
1592   }
1593 };
1594
1595 /**
1596  * GuardImpl - For handling exceptions from downstream computation. Requires the
1597  * type of exception to catch, and handler function to invoke in the event of
1598  * the exception. Note that the handler may:
1599  *   1) return true to continue processing the sequence
1600  *   2) return false to end the sequence immediately
1601  *   3) throw, to pass the exception to the next catch
1602  * The handler must match the signature 'bool(Exception&, Value)'.
1603  *
1604  * This type is used through the `guard` helper, like so:
1605  *
1606  *  auto indexes
1607  *    = byLine(STDIN_FILENO)
1608  *    | guard<std::runtime_error>([](std::runtime_error& e,
1609  *                                   StringPiece sp) {
1610  *        LOG(ERROR) << sp << ": " << e.str();
1611  *        return true; // continue processing subsequent lines
1612  *      })
1613  *    | eachTo<int>()
1614  *    | as<vector>();
1615  *
1616  *  TODO(tjackson): Rename this back to Guard.
1617  **/
1618 template <class Exception, class ErrorHandler>
1619 class GuardImpl : public Operator<GuardImpl<Exception, ErrorHandler>> {
1620   ErrorHandler handler_;
1621
1622  public:
1623   explicit GuardImpl(ErrorHandler handler) : handler_(std::move(handler)) {}
1624
1625   template <class Value, class Source>
1626   class Generator : public GenImpl<Value, Generator<Value, Source>> {
1627     Source source_;
1628     ErrorHandler handler_;
1629
1630    public:
1631     explicit Generator(Source source, ErrorHandler handler)
1632         : source_(std::move(source)), handler_(std::move(handler)) {}
1633
1634     template <class Handler>
1635     bool apply(Handler&& handler) const {
1636       return source_.apply([&](Value value) -> bool {
1637         try {
1638           handler(std::forward<Value>(value));
1639           return true;
1640         } catch (Exception& e) {
1641           return handler_(e, std::forward<Value>(value));
1642         }
1643       });
1644     }
1645
1646     // Just passes value though, length unaffected
1647     static constexpr bool infinite = Source::infinite;
1648   };
1649
1650   template <class Value, class Source, class Gen = Generator<Value, Source>>
1651   Gen compose(GenImpl<Value, Source>&& source) const {
1652     return Gen(std::move(source.self()), handler_);
1653   }
1654
1655   template <class Value, class Source, class Gen = Generator<Value, Source>>
1656   Gen compose(const GenImpl<Value, Source>& source) const {
1657     return Gen(source.self(), handler_);
1658   }
1659 };
1660
1661 /**
1662  * Dereference - For dereferencing a sequence of pointers while filtering out
1663  * null pointers.
1664  *
1665  * This type is usually used through the 'dereference' static value, like:
1666  *
1667  *   auto refs = from(ptrs) | dereference;
1668  */
1669 class Dereference : public Operator<Dereference> {
1670  public:
1671   Dereference() = default;
1672
1673   template <
1674       class Value,
1675       class Source,
1676       class Result = decltype(*std::declval<Value>())>
1677   class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1678     Source source_;
1679
1680    public:
1681     explicit Generator(Source source) : source_(std::move(source)) {}
1682
1683     template <class Body>
1684     void foreach(Body&& body) const {
1685       source_.foreach([&](Value value) {
1686         if (value) {
1687           return body(*std::forward<Value>(value));
1688         }
1689       });
1690     }
1691
1692     template <class Handler>
1693     bool apply(Handler&& handler) const {
1694       return source_.apply([&](Value value) -> bool {
1695         if (value) {
1696           return handler(*std::forward<Value>(value));
1697         }
1698         return true;
1699       });
1700     }
1701
1702     // Just passes value though, length unaffected
1703     static constexpr bool infinite = Source::infinite;
1704   };
1705
1706   template <class Source, class Value, class Gen = Generator<Value, Source>>
1707   Gen compose(GenImpl<Value, Source>&& source) const {
1708     return Gen(std::move(source.self()));
1709   }
1710
1711   template <class Source, class Value, class Gen = Generator<Value, Source>>
1712   Gen compose(const GenImpl<Value, Source>& source) const {
1713     return Gen(source.self());
1714   }
1715 };
1716
1717 /**
1718  * Indirect - For producing a sequence of the addresses of the values in the
1719  * input.
1720  *
1721  * This type is usually used through the 'indirect' static value, like:
1722  *
1723  *   auto ptrs = from(refs) | indirect;
1724  */
1725 class Indirect : public Operator<Indirect> {
1726  public:
1727   Indirect() = default;
1728
1729   template <
1730       class Value,
1731       class Source,
1732       class Result = typename std::remove_reference<Value>::type*>
1733   class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1734     Source source_;
1735     static_assert(!std::is_rvalue_reference<Value>::value,
1736                   "Cannot use indirect on an rvalue");
1737
1738    public:
1739     explicit Generator(Source source) : source_(std::move(source)) {}
1740
1741     template <class Body>
1742     void foreach(Body&& body) const {
1743       source_.foreach([&](Value value) {
1744         return body(&std::forward<Value>(value));
1745       });
1746     }
1747
1748     template <class Handler>
1749     bool apply(Handler&& handler) const {
1750       return source_.apply([&](Value value) -> bool {
1751         return handler(&std::forward<Value>(value));
1752       });
1753     }
1754
1755     // Just passes value though, length unaffected
1756     static constexpr bool infinite = Source::infinite;
1757   };
1758
1759   template <class Source, class Value, class Gen = Generator<Value, Source>>
1760   Gen compose(GenImpl<Value, Source>&& source) const {
1761     return Gen(std::move(source.self()));
1762   }
1763
1764   template <class Source, class Value, class Gen = Generator<Value, Source>>
1765   Gen compose(const GenImpl<Value, Source>& source) const {
1766     return Gen(source.self());
1767   }
1768 };
1769
1770 /**
1771  * Cycle - For repeating a sequence forever.
1772  *
1773  * This type is usually used through the 'cycle' static value, like:
1774  *
1775  *   auto tests
1776  *     = from(samples)
1777  *     | cycle
1778  *     | take(100);
1779  *
1780  * or in the finite case:
1781  *
1782  *   auto thrice = g | cycle(3);
1783  */
1784 template <bool forever>
1785 class Cycle : public Operator<Cycle<forever>> {
1786   off_t limit_; // not used if forever == true
1787  public:
1788   Cycle() = default;
1789
1790   explicit Cycle(off_t limit) : limit_(limit) {
1791     static_assert(
1792         !forever,
1793         "Cycle limit constructor should not be used when forever == true.");
1794   }
1795
1796   template <class Value, class Source>
1797   class Generator : public GenImpl<Value, Generator<Value, Source>> {
1798     Source source_;
1799     off_t limit_;
1800
1801    public:
1802     explicit Generator(Source source, off_t limit)
1803         : source_(std::move(source)), limit_(limit) {}
1804
1805     template <class Handler>
1806     bool apply(Handler&& handler) const {
1807       bool cont;
1808       auto handler2 = [&](Value value) {
1809         cont = handler(std::forward<Value>(value));
1810         return cont;
1811       };
1812       // Becomes an infinte loop if forever == true
1813       for (off_t count = 0; (forever || count != limit_); ++count) {
1814         cont = false;
1815         source_.apply(handler2);
1816         if (!cont) {
1817           return false;
1818         }
1819       }
1820       return true;
1821     }
1822
1823     // This is the hardest one to infer. If we are simply doing a finite cycle,
1824     // then (gen | cycle(n)) is infinite if and only if gen is infinite.
1825     // However, if we are doing an infinite cycle, (gen | cycle) is infinite
1826     // unless gen is empty. However, we will always mark (gen | cycle) as
1827     // infinite, because patterns such as (gen | cycle | count) can either take
1828     // on exactly one value, or infinite loop.
1829     static constexpr bool infinite = forever || Source::infinite;
1830   };
1831
1832   template <class Source, class Value, class Gen = Generator<Value, Source>>
1833   Gen compose(GenImpl<Value, Source>&& source) const {
1834     return Gen(std::move(source.self()), limit_);
1835   }
1836
1837   template <class Source, class Value, class Gen = Generator<Value, Source>>
1838   Gen compose(const GenImpl<Value, Source>& source) const {
1839     return Gen(source.self(), limit_);
1840   }
1841
1842   /**
1843    * Convenience function for finite cycles used like:
1844    *
1845    *  auto tripled = gen | cycle(3);
1846    */
1847   Cycle<false> operator()(off_t limit) const { return Cycle<false>(limit); }
1848 };
1849
1850 /*
1851  ******************************* Sinks *****************************************
1852  */
1853
1854 /**
1855  * FoldLeft - Left-associative functional fold. For producing an aggregate value
1856  * from a seed and a folder function. Useful for custom aggregators on a
1857  * sequence.
1858  *
1859  * This type is primarily used through the 'foldl' helper method, like:
1860  *
1861  *   double movingAverage = from(values)
1862  *                        | foldl(0.0, [](double avg, double sample) {
1863  *                            return sample * 0.1 + avg * 0.9;
1864  *                          });
1865  */
1866 template <class Seed, class Fold>
1867 class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
1868   Seed seed_;
1869   Fold fold_;
1870
1871  public:
1872   FoldLeft() = default;
1873   FoldLeft(Seed seed, Fold fold)
1874       : seed_(std::move(seed)), fold_(std::move(fold)) {}
1875
1876   template <class Source, class Value>
1877   Seed compose(const GenImpl<Value, Source>& source) const {
1878     static_assert(!Source::infinite, "Cannot foldl infinite source");
1879     Seed accum = seed_;
1880     source | [&](Value v) {
1881       accum = fold_(std::move(accum), std::forward<Value>(v));
1882     };
1883     return accum;
1884   }
1885 };
1886
1887 /**
1888  * First - For finding the first value in a sequence.
1889  *
1890  * This type is primarily used through the 'first' static value, like:
1891  *
1892  *   int firstThreeDigitPrime = seq(100) | filter(isPrime) | first;
1893  */
1894 class First : public Operator<First> {
1895  public:
1896   First() = default;
1897
1898   template <
1899       class Source,
1900       class Value,
1901       class StorageType = typename std::decay<Value>::type>
1902   Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
1903     Optional<StorageType> accum;
1904     source | [&](Value v) -> bool {
1905       accum = std::forward<Value>(v);
1906       return false;
1907     };
1908     return accum;
1909   }
1910 };
1911
1912 /**
1913  * IsEmpty - a helper class for isEmpty and notEmpty
1914  *
1915  * Essentially returns 'result' if the source is empty. Note that this cannot be
1916  * called on an infinite source, because then there is only one possible return
1917  * value.
1918  *
1919  *
1920  *  Used primarily through 'isEmpty' and 'notEmpty' static values
1921  *
1922  *  bool hasPrimes = g | filter(prime) | notEmpty;
1923  *  bool lacksEvens = g | filter(even) | isEmpty;
1924  *
1925  *  Also used in the implementation of 'any' and 'all'
1926  */
1927 template <bool emptyResult>
1928 class IsEmpty : public Operator<IsEmpty<emptyResult>> {
1929  public:
1930   IsEmpty() = default;
1931
1932   template <class Source, class Value>
1933   bool compose(const GenImpl<Value, Source>& source) const {
1934     static_assert(!Source::infinite,
1935                   "Cannot call 'all', 'any', 'isEmpty', or 'notEmpty' on "
1936                   "infinite source. 'all' and 'isEmpty' will either return "
1937                   "false or hang. 'any' or 'notEmpty' will either return true "
1938                   "or hang.");
1939     bool ans = emptyResult;
1940     source |
1941         [&](Value /* v */) -> bool {
1942           ans = !emptyResult;
1943           return false;
1944         };
1945     return ans;
1946   }
1947 };
1948
1949 /**
1950  * Reduce - Functional reduce, for recursively combining values from a source
1951  * using a reducer function until there is only one item left. Useful for
1952  * combining values when an empty sequence doesn't make sense.
1953  *
1954  * This type is primarily used through the 'reduce' helper method, like:
1955  *
1956  *   sring longest = from(names)
1957  *                 | reduce([](string&& best, string& current) {
1958  *                     return best.size() >= current.size() ? best : current;
1959  *                   });
1960  */
1961 template <class Reducer>
1962 class Reduce : public Operator<Reduce<Reducer>> {
1963   Reducer reducer_;
1964
1965  public:
1966   Reduce() = default;
1967   explicit Reduce(Reducer reducer) : reducer_(std::move(reducer)) {}
1968
1969   template <
1970       class Source,
1971       class Value,
1972       class StorageType = typename std::decay<Value>::type>
1973   Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
1974     static_assert(!Source::infinite, "Cannot reduce infinite source");
1975     Optional<StorageType> accum;
1976     source | [&](Value v) {
1977       if (auto target = accum.get_pointer()) {
1978         *target = reducer_(std::move(*target), std::forward<Value>(v));
1979       } else {
1980         accum = std::forward<Value>(v);
1981       }
1982     };
1983     return accum;
1984   }
1985 };
1986
1987 /**
1988  * Count - for simply counting the items in a collection.
1989  *
1990  * This type is usually used through its singleton, 'count':
1991  *
1992  *   auto shortPrimes = seq(1, 100) | filter(isPrime) | count;
1993  */
1994 class Count : public Operator<Count> {
1995  public:
1996   Count() = default;
1997
1998   template <class Source, class Value>
1999   size_t compose(const GenImpl<Value, Source>& source) const {
2000     static_assert(!Source::infinite, "Cannot count infinite source");
2001     return foldl(size_t(0),
2002                  [](size_t accum, Value /* v */) { return accum + 1; })
2003         .compose(source);
2004   }
2005 };
2006
2007 /**
2008  * Sum - For simply summing up all the values from a source.
2009  *
2010  * This type is usually used through its singleton, 'sum':
2011  *
2012  *   auto gaussSum = seq(1, 100) | sum;
2013  */
2014 class Sum : public Operator<Sum> {
2015  public:
2016   Sum() = default;
2017
2018   template <
2019       class Source,
2020       class Value,
2021       class StorageType = typename std::decay<Value>::type>
2022   StorageType compose(const GenImpl<Value, Source>& source) const {
2023     static_assert(!Source::infinite, "Cannot sum infinite source");
2024     return foldl(StorageType(0),
2025                  [](StorageType&& accum, Value v) {
2026                    return std::move(accum) + std::forward<Value>(v);
2027                  }).compose(source);
2028   }
2029 };
2030
2031 /**
2032  * Contains - For testing whether a value matching the given value is contained
2033  * in a sequence.
2034  *
2035  * This type should be used through the 'contains' helper method, like:
2036  *
2037  *   bool contained = seq(1, 10) | map(square) | contains(49);
2038  */
2039 template <class Needle>
2040 class Contains : public Operator<Contains<Needle>> {
2041   Needle needle_;
2042
2043  public:
2044   explicit Contains(Needle needle) : needle_(std::move(needle)) {}
2045
2046   template <
2047       class Source,
2048       class Value,
2049       class StorageType = typename std::decay<Value>::type>
2050   bool compose(const GenImpl<Value, Source>& source) const {
2051     static_assert(!Source::infinite,
2052                   "Calling contains on an infinite source might cause "
2053                   "an infinite loop.");
2054     return !(source | [this](Value value) {
2055       return !(needle_ == std::forward<Value>(value));
2056     });
2057   }
2058 };
2059
2060 /**
2061  * Min - For a value which minimizes a key, where the key is determined by a
2062  * given selector, and compared by given comparer.
2063  *
2064  * This type is usually used through the singletone 'min' or through the helper
2065  * functions 'minBy' and 'maxBy'.
2066  *
2067  *   auto oldest = from(people)
2068  *               | minBy([](Person& p) {
2069  *                   return p.dateOfBirth;
2070  *                 });
2071  */
2072 template <class Selector, class Comparer>
2073 class Min : public Operator<Min<Selector, Comparer>> {
2074   Selector selector_;
2075   Comparer comparer_;
2076
2077   template <typename T>
2078   const T& asConst(const T& t) const {
2079     return t;
2080   }
2081
2082  public:
2083   Min() = default;
2084
2085   explicit Min(Selector selector) : selector_(std::move(selector)) {}
2086
2087   Min(Selector selector, Comparer comparer)
2088       : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
2089
2090   template <
2091       class Value,
2092       class Source,
2093       class StorageType = typename std::decay<Value>::type,
2094       class Key = typename std::decay<
2095           typename std::result_of<Selector(Value)>::type>::type>
2096   Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
2097     static_assert(!Source::infinite,
2098                   "Calling min or max on an infinite source will cause "
2099                   "an infinite loop.");
2100     Optional<StorageType> min;
2101     Optional<Key> minKey;
2102     source | [&](Value v) {
2103       Key key = selector_(asConst(v)); // so that selector_ cannot mutate v
2104       if (auto lastKey = minKey.get_pointer()) {
2105         if (!comparer_(key, *lastKey)) {
2106           return;
2107         }
2108       }
2109       minKey = std::move(key);
2110       min = std::forward<Value>(v);
2111     };
2112     return min;
2113   }
2114 };
2115
2116 /**
2117  * Append - For collecting values from a source into a given output container
2118  * by appending.
2119  *
2120  * This type is usually used through the helper function 'appendTo', like:
2121  *
2122  *   vector<int64_t> ids;
2123  *   from(results) | map([](Person& p) { return p.id })
2124  *                 | appendTo(ids);
2125  */
2126 template <class Collection>
2127 class Append : public Operator<Append<Collection>> {
2128   Collection* collection_;
2129
2130  public:
2131   explicit Append(Collection* collection) : collection_(collection) {}
2132
2133   template <class Value, class Source>
2134   Collection& compose(const GenImpl<Value, Source>& source) const {
2135     static_assert(!Source::infinite, "Cannot appendTo with infinite source");
2136     source | [&](Value v) {
2137       collection_->insert(collection_->end(), std::forward<Value>(v));
2138     };
2139     return *collection_;
2140   }
2141 };
2142
2143 /**
2144  * Collect - For collecting values from a source in a collection of the desired
2145  * type.
2146  *
2147  * This type is usually used through the helper function 'as', like:
2148  *
2149  *   std::string upper = from(stringPiece)
2150  *                     | map(&toupper)
2151  *                     | as<std::string>();
2152  */
2153 template <class Collection>
2154 class Collect : public Operator<Collect<Collection>> {
2155  public:
2156   Collect() = default;
2157
2158   template <
2159       class Value,
2160       class Source,
2161       class StorageType = typename std::decay<Value>::type>
2162   Collection compose(const GenImpl<Value, Source>& source) const {
2163     static_assert(!Source::infinite,
2164                   "Cannot convert infinite source to object with as.");
2165     Collection collection;
2166     source | [&](Value v) {
2167       collection.insert(collection.end(), std::forward<Value>(v));
2168     };
2169     return collection;
2170   }
2171 };
2172
2173 /**
2174  * CollectTemplate - For collecting values from a source in a collection
2175  * constructed using the specified template type. Given the type of values
2176  * produced by the given generator, the collection type will be:
2177  *   Container<Value, Allocator<Value>>
2178  *
2179  * The allocator defaults to std::allocator, so this may be used for the STL
2180  * containers by simply using operators like 'as<set>', 'as<deque>',
2181  * 'as<vector>'. 'as', here is the helper method which is the usual means of
2182  * constructing this operator.
2183  *
2184  * Example:
2185  *
2186  *   set<string> uniqueNames = from(names) | as<set>();
2187  */
2188 template <
2189     template <class, class> class Container,
2190     template <class> class Allocator>
2191 class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
2192  public:
2193   CollectTemplate() = default;
2194
2195   template <
2196       class Value,
2197       class Source,
2198       class StorageType = typename std::decay<Value>::type,
2199       class Collection = Container<StorageType, Allocator<StorageType>>>
2200   Collection compose(const GenImpl<Value, Source>& source) const {
2201     static_assert(!Source::infinite,
2202                   "Cannot convert infinite source to object with as.");
2203     Collection collection;
2204     source | [&](Value v) {
2205       collection.insert(collection.end(), std::forward<Value>(v));
2206     };
2207     return collection;
2208   }
2209 };
2210
2211 /**
2212  * UnwrapOr - For unwrapping folly::Optional values, or providing the given
2213  * fallback value. Usually used through the 'unwrapOr' helper like so:
2214  *
2215  *   auto best = from(scores) | max | unwrapOr(-1);
2216  *
2217  * Note that the fallback value needn't match the value in the Optional it is
2218  * unwrapping. If mis-matched types are supported, the common type of the two is
2219  * returned by value. If the types match, a reference (T&& > T& > const T&) is
2220  * returned.
2221  */
2222 template <class T>
2223 class UnwrapOr {
2224  public:
2225   explicit UnwrapOr(T&& value) : value_(std::move(value)) {}
2226   explicit UnwrapOr(const T& value) : value_(value) {}
2227
2228   T& value() { return value_; }
2229   const T& value() const { return value_; }
2230
2231  private:
2232   T value_;
2233 };
2234
2235 template <class T>
2236 T&& operator|(Optional<T>&& opt, UnwrapOr<T>&& fallback) {
2237   if (T* p = opt.get_pointer()) {
2238     return std::move(*p);
2239   }
2240   return std::move(fallback.value());
2241 }
2242
2243 template <class T>
2244 T& operator|(Optional<T>& opt, UnwrapOr<T>& fallback) {
2245   if (T* p = opt.get_pointer()) {
2246     return *p;
2247   }
2248   return fallback.value();
2249 }
2250
2251 template <class T>
2252 const T& operator|(const Optional<T>& opt, const UnwrapOr<T>& fallback) {
2253   if (const T* p = opt.get_pointer()) {
2254     return *p;
2255   }
2256   return fallback.value();
2257 }
2258
2259 // Mixed type unwrapping always returns values, moving where possible
2260 template <
2261     class T,
2262     class U,
2263     class R = typename std::enable_if<
2264         !std::is_same<T, U>::value,
2265         typename std::common_type<T, U>::type>::type>
2266 R operator|(Optional<T>&& opt, UnwrapOr<U>&& fallback) {
2267   if (T* p = opt.get_pointer()) {
2268     return std::move(*p);
2269   }
2270   return std::move(fallback.value());
2271 }
2272
2273 template <
2274     class T,
2275     class U,
2276     class R = typename std::enable_if<
2277         !std::is_same<T, U>::value,
2278         typename std::common_type<T, U>::type>::type>
2279 R operator|(const Optional<T>& opt, UnwrapOr<U>&& fallback) {
2280   if (const T* p = opt.get_pointer()) {
2281     return *p;
2282   }
2283   return std::move(fallback.value());
2284 }
2285
2286 template <
2287     class T,
2288     class U,
2289     class R = typename std::enable_if<
2290         !std::is_same<T, U>::value,
2291         typename std::common_type<T, U>::type>::type>
2292 R operator|(Optional<T>&& opt, const UnwrapOr<U>& fallback) {
2293   if (T* p = opt.get_pointer()) {
2294     return std::move(*p);
2295   }
2296   return fallback.value();
2297 }
2298
2299 template <
2300     class T,
2301     class U,
2302     class R = typename std::enable_if<
2303         !std::is_same<T, U>::value,
2304         typename std::common_type<T, U>::type>::type>
2305 R operator|(const Optional<T>& opt, const UnwrapOr<U>& fallback) {
2306   if (const T* p = opt.get_pointer()) {
2307     return *p;
2308   }
2309   return fallback.value();
2310 }
2311
2312 /**
2313  * Unwrap - For unwrapping folly::Optional values in a folly::gen style. Usually
2314  * used through the 'unwrap' instace like so:
2315  *
2316  *   auto best = from(scores) | max | unwrap; // may throw
2317  */
2318 class Unwrap {};
2319
2320 template <class T>
2321 T&& operator|(Optional<T>&& opt, const Unwrap&) {
2322   return std::move(opt.value());
2323 }
2324
2325 template <class T>
2326 T& operator|(Optional<T>& opt, const Unwrap&) {
2327   return opt.value();
2328 }
2329
2330 template <class T>
2331 const T& operator|(const Optional<T>& opt, const Unwrap&) {
2332   return opt.value();
2333 }
2334
2335 } // namespace detail
2336
2337 /**
2338  * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
2339  **/
2340 template <class Value>
2341 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
2342   class WrapperBase {
2343    public:
2344     virtual ~WrapperBase() noexcept {}
2345     virtual bool apply(const std::function<bool(Value)>& handler) const = 0;
2346     virtual void foreach(const std::function<void(Value)>& body) const = 0;
2347     virtual std::unique_ptr<const WrapperBase> clone() const = 0;
2348   };
2349
2350   template <class Wrapped>
2351   class WrapperImpl : public WrapperBase {
2352     Wrapped wrapped_;
2353
2354    public:
2355     explicit WrapperImpl(Wrapped wrapped) : wrapped_(std::move(wrapped)) {}
2356
2357     bool apply(const std::function<bool(Value)>& handler) const override {
2358       return wrapped_.apply(handler);
2359     }
2360
2361     void foreach(const std::function<void(Value)>& body) const override {
2362       wrapped_.foreach(body);
2363     }
2364
2365     std::unique_ptr<const WrapperBase> clone() const override {
2366       return std::unique_ptr<const WrapperBase>(new WrapperImpl(wrapped_));
2367     }
2368   };
2369
2370   std::unique_ptr<const WrapperBase> wrapper_;
2371
2372  public:
2373   template <class Self>
2374   /* implicit */ VirtualGen(Self source)
2375       : wrapper_(new WrapperImpl<Self>(std::move(source))) {}
2376
2377   VirtualGen(VirtualGen&& source) noexcept
2378       : wrapper_(std::move(source.wrapper_)) {}
2379
2380   VirtualGen(const VirtualGen& source) : wrapper_(source.wrapper_->clone()) {}
2381
2382   VirtualGen& operator=(const VirtualGen& source) {
2383     wrapper_.reset(source.wrapper_->clone());
2384     return *this;
2385   }
2386
2387   VirtualGen& operator=(VirtualGen&& source) noexcept {
2388     wrapper_ = std::move(source.wrapper_);
2389     return *this;
2390   }
2391
2392   bool apply(const std::function<bool(Value)>& handler) const {
2393     return wrapper_->apply(handler);
2394   }
2395
2396   void foreach(const std::function<void(Value)>& body) const {
2397     wrapper_->foreach(body);
2398   }
2399 };
2400
2401 /**
2402  * non-template operators, statically defined to avoid the need for anything but
2403  * the header.
2404  */
2405 constexpr detail::Sum sum{};
2406
2407 constexpr detail::Count count{};
2408
2409 constexpr detail::First first{};
2410
2411 constexpr detail::IsEmpty<true> isEmpty{};
2412
2413 constexpr detail::IsEmpty<false> notEmpty{};
2414
2415 constexpr detail::Min<Identity, Less> min{};
2416
2417 constexpr detail::Min<Identity, Greater> max{};
2418
2419 constexpr detail::Order<Identity> order{};
2420
2421 constexpr detail::Distinct<Identity> distinct{};
2422
2423 constexpr detail::Map<Move> move{};
2424
2425 constexpr detail::Concat concat{};
2426
2427 constexpr detail::RangeConcat rconcat{};
2428
2429 constexpr detail::Cycle<true> cycle{};
2430
2431 constexpr detail::Dereference dereference{};
2432
2433 constexpr detail::Indirect indirect{};
2434
2435 constexpr detail::Unwrap unwrap{};
2436
2437 template <class Number>
2438 inline detail::Take take(Number count) {
2439   if (count < 0) {
2440     throw std::invalid_argument("Negative value passed to take()");
2441   }
2442   return detail::Take(static_cast<size_t>(count));
2443 }
2444
2445 inline detail::Stride stride(size_t s) { return detail::Stride(s); }
2446
2447 template <class Random = std::default_random_engine>
2448 inline detail::Sample<Random> sample(size_t count, Random rng = Random()) {
2449   return detail::Sample<Random>(count, std::move(rng));
2450 }
2451
2452 inline detail::Skip skip(size_t count) { return detail::Skip(count); }
2453
2454 inline detail::Batch batch(size_t batchSize) {
2455   return detail::Batch(batchSize);
2456 }
2457
2458 inline detail::Window window(size_t windowSize) {
2459   return detail::Window(windowSize);
2460 }
2461
2462 } // namespace gen
2463 } // namespace folly
2464
2465 FOLLY_POP_WARNING