8b0c4dc748e79173dc7b8df62ec1ed19c98d8d8a
[folly.git] / folly / experimental / Gen-inl.h
1 /*
2  * Copyright 2013 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 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
18 #pragma GCC diagnostic push
19 #pragma GCC diagnostic ignored "-Wshadow"
20
21 namespace folly { namespace gen {
22
23 /**
24  * IsCompatibleSignature - Trait type for testing whether a given Functor
25  * matches an expected signature.
26  *
27  * Usage:
28  *   IsCompatibleSignature<FunctorType, bool(int, float)>::value
29  */
30 template<class Candidate, class Expected>
31 class IsCompatibleSignature {
32   static constexpr bool value = false;
33 };
34
35 template<class Candidate,
36          class ExpectedReturn,
37          class... ArgTypes>
38 class IsCompatibleSignature<Candidate, ExpectedReturn(ArgTypes...)> {
39   template<class F,
40            class ActualReturn =
41              decltype(std::declval<F>()(std::declval<ArgTypes>()...)),
42            bool good = std::is_same<ExpectedReturn, ActualReturn>::value>
43   static constexpr bool testArgs(int* p) {
44     return good;
45   }
46
47   template<class F>
48   static constexpr bool testArgs(...) {
49     return false;
50   }
51 public:
52   static constexpr bool value = testArgs<Candidate>(nullptr);
53 };
54
55 /**
56  * ArgumentReference - For determining ideal argument type to receive a value.
57  */
58 template<class T>
59 struct ArgumentReference :
60   public std::conditional<std::is_reference<T>::value,
61                           T, // T& -> T&, T&& -> T&&, const T& -> const T&
62                           typename std::conditional<
63                             std::is_const<T>::value,
64                             T&, // const int -> const int&
65                             T&& // int -> int&&
66                           >::type> {};
67
68 /**
69  * FBounded - Helper type for the curiously recurring template pattern, used
70  * heavily here to enable inlining and obviate virtual functions
71  */
72 template<class Self>
73 struct FBounded {
74   const Self& self() const {
75     return *static_cast<const Self*>(this);
76   }
77
78   Self& self() {
79     return *static_cast<Self*>(this);
80   }
81 };
82
83 /**
84  * Operator - Core abstraction of an operation which may be applied to a
85  * generator. All operators implement a method compose(), which takes a
86  * generator and produces an output generator.
87  */
88 template<class Self>
89 class Operator : public FBounded<Self> {
90  public:
91   /**
92    * compose() - Must be implemented by child class to compose a new Generator
93    * out of a given generator. This function left intentionally unimplemented.
94    */
95   template<class Source,
96            class Value,
97            class ResultGen = void>
98   ResultGen compose(const GenImpl<Value, Source>& source) const;
99
100  protected:
101   Operator() = default;
102   Operator(const Operator&) = default;
103   Operator(Operator&&) = default;
104 };
105
106 /**
107  * operator|() - For composing two operators without binding it to a
108  * particular generator.
109  */
110 template<class Left,
111          class Right,
112          class Composed = detail::Composed<Left, Right>>
113 Composed operator|(const Operator<Left>& left,
114                    const Operator<Right>& right) {
115   return Composed(left.self(), right.self());
116 }
117
118 template<class Left,
119          class Right,
120          class Composed = detail::Composed<Left, Right>>
121 Composed operator|(const Operator<Left>& left,
122                    Operator<Right>&& right) {
123   return Composed(left.self(), std::move(right.self()));
124 }
125
126 template<class Left,
127          class Right,
128          class Composed = detail::Composed<Left, Right>>
129 Composed operator|(Operator<Left>&& left,
130                    const Operator<Right>& right) {
131   return Composed(std::move(left.self()), right.self());
132 }
133
134 template<class Left,
135          class Right,
136          class Composed = detail::Composed<Left, Right>>
137 Composed operator|(Operator<Left>&& left,
138                    Operator<Right>&& right) {
139   return Composed(std::move(left.self()), std::move(right.self()));
140 }
141
142 /**
143  * GenImpl - Core abstraction of a generator, an object which produces values by
144  * passing them to a given handler lambda. All generator implementations must
145  * implement apply(). foreach() may also be implemented to special case the
146  * condition where the entire sequence is consumed.
147  */
148 template<class Value,
149          class Self>
150 class GenImpl : public FBounded<Self> {
151  protected:
152   // To prevent slicing
153   GenImpl() = default;
154   GenImpl(const GenImpl&) = default;
155   GenImpl(GenImpl&&) = default;
156
157  public:
158   typedef Value ValueType;
159   typedef typename std::decay<Value>::type StorageType;
160
161   /**
162    * apply() - Send all values produced by this generator to given
163    * handler until the handler returns false. Returns false if and only if the
164    * handler returns false. Note: It should return true even if it completes
165    * (without the handler returning false), as 'Chain' uses the return value of
166    * apply to determine if it should process the second object in its chain.
167    */
168   template<class Handler>
169   bool apply(Handler&& handler) const;
170
171   /**
172    * foreach() - Send all values produced by this generator to given lambda.
173    */
174   template<class Body>
175   void foreach(Body&& body) const {
176     this->self().apply([&](Value value) -> bool {
177         static_assert(!infinite, "Cannot call foreach on infinite GenImpl");
178         body(std::forward<Value>(value));
179         return true;
180       });
181   }
182
183   // Child classes should override if the sequence generated is *definitely*
184   // infinite. 'infinite' may be false_type for some infinite sequences
185   // (due the the Halting Problem).
186   static constexpr bool infinite = false;
187 };
188
189 template<class LeftValue,
190          class Left,
191          class RightValue,
192          class Right,
193          class Chain = detail::Chain<LeftValue, Left, Right>>
194 Chain operator+(const GenImpl<LeftValue, Left>& left,
195                 const GenImpl<RightValue, Right>& right) {
196   static_assert(
197     std::is_same<LeftValue, RightValue>::value,
198     "Generators may ony be combined if Values are the exact same type.");
199   return Chain(left.self(), right.self());
200 }
201
202 template<class LeftValue,
203          class Left,
204          class RightValue,
205          class Right,
206          class Chain = detail::Chain<LeftValue, Left, Right>>
207 Chain operator+(const GenImpl<LeftValue, Left>& left,
208                 GenImpl<RightValue, Right>&& right) {
209   static_assert(
210     std::is_same<LeftValue, RightValue>::value,
211     "Generators may ony be combined if Values are the exact same type.");
212   return Chain(left.self(), std::move(right.self()));
213 }
214
215 template<class LeftValue,
216          class Left,
217          class RightValue,
218          class Right,
219          class Chain = detail::Chain<LeftValue, Left, Right>>
220 Chain operator+(GenImpl<LeftValue, Left>&& left,
221                 const GenImpl<RightValue, Right>& right) {
222   static_assert(
223     std::is_same<LeftValue, RightValue>::value,
224     "Generators may ony be combined if Values are the exact same type.");
225   return Chain(std::move(left.self()), right.self());
226 }
227
228 template<class LeftValue,
229          class Left,
230          class RightValue,
231          class Right,
232          class Chain = detail::Chain<LeftValue, Left, Right>>
233 Chain operator+(GenImpl<LeftValue, Left>&& left,
234                 GenImpl<RightValue, Right>&& right) {
235   static_assert(
236     std::is_same<LeftValue, RightValue>::value,
237     "Generators may ony be combined if Values are the exact same type.");
238   return Chain(std::move(left.self()), std::move(right.self()));
239 }
240
241 /**
242  * operator|() which enables foreach-like usage:
243  *   gen | [](Value v) -> void {...};
244  */
245 template<class Value,
246          class Gen,
247          class Handler>
248 typename std::enable_if<
249   IsCompatibleSignature<Handler, void(Value)>::value>::type
250 operator|(const GenImpl<Value, Gen>& gen, Handler&& handler) {
251   static_assert(!Gen::infinite,
252                 "Cannot pull all values from an infinite sequence.");
253   gen.self().foreach(std::forward<Handler>(handler));
254 }
255
256 /**
257  * operator|() which enables foreach-like usage with 'break' support:
258  *   gen | [](Value v) -> bool { return shouldContinue(); };
259  */
260 template<class Value,
261          class Gen,
262          class Handler>
263 typename std::enable_if<
264   IsCompatibleSignature<Handler, bool(Value)>::value, bool>::type
265 operator|(const GenImpl<Value, Gen>& gen, Handler&& handler) {
266   return gen.self().apply(std::forward<Handler>(handler));
267 }
268
269 /**
270  * operator|() for composing generators with operators, similar to boosts' range
271  * adaptors:
272  *   gen | map(square) | sum
273  */
274 template<class Value,
275          class Gen,
276          class Op>
277 auto operator|(const GenImpl<Value, Gen>& gen, const Operator<Op>& op) ->
278 decltype(op.self().compose(gen.self())) {
279   return op.self().compose(gen.self());
280 }
281
282 template<class Value,
283          class Gen,
284          class Op>
285 auto operator|(GenImpl<Value, Gen>&& gen, const Operator<Op>& op) ->
286 decltype(op.self().compose(std::move(gen.self()))) {
287   return op.self().compose(std::move(gen.self()));
288 }
289
290 namespace detail {
291
292 /*
293  * ReferencedSource - Generate values from an STL-like container using
294  * iterators from .begin() until .end(). Value type defaults to the type of
295  * *container->begin(). For std::vector<int>, this would be int&. Note that the
296  * value here is a reference, so the values in the vector will be passed by
297  * reference to downstream operators.
298  *
299  * This type is primarily used through the 'from' helper method, like:
300  *
301  *   string& longestName = from(names)
302  *                       | maxBy([](string& s) { return s.size() });
303  */
304 template<class Container,
305          class Value>
306 class ReferencedSource :
307     public GenImpl<Value, ReferencedSource<Container, Value>> {
308   Container* container_;
309 public:
310   explicit ReferencedSource(Container* container)
311     : container_(container) {}
312
313   template<class Body>
314   void foreach(Body&& body) const {
315     for (auto& value : *container_) {
316       body(std::forward<Value>(value));
317     }
318   }
319
320   template<class Handler>
321   bool apply(Handler&& handler) const {
322     for (auto& value : *container_) {
323       if (!handler(std::forward<Value>(value))) {
324         return false;
325       }
326     }
327     return true;
328   }
329 };
330
331 /**
332  * CopiedSource - For producing values from eagerly from a sequence of values
333  * whose storage is owned by this class. Useful for preparing a generator for
334  * use after a source collection will no longer be available, or for when the
335  * values are specified literally with an initializer list.
336  *
337  * This type is primarily used through the 'fromCopy' function, like:
338  *
339  *   auto sourceCopy = fromCopy(makeAVector());
340  *   auto sum = sourceCopy | sum;
341  *   auto max = sourceCopy | max;
342  *
343  * Though it is also used for the initializer_list specialization of from().
344  */
345 template<class StorageType,
346          class Container>
347 class CopiedSource :
348   public GenImpl<const StorageType&,
349                  CopiedSource<StorageType, Container>> {
350   static_assert(
351     !std::is_reference<StorageType>::value, "StorageType must be decayed");
352  public:
353   // Generator objects are often copied during normal construction as they are
354   // encapsulated by downstream generators. It would be bad if this caused
355   // a copy of the entire container each time, and since we're only exposing a
356   // const reference to the value, it's safe to share it between multiple
357   // generators.
358   static_assert(
359     !std::is_reference<Container>::value,
360     "Can't copy into a reference");
361   std::shared_ptr<const Container> copy_;
362 public:
363   typedef Container ContainerType;
364
365   template<class SourceContainer>
366   explicit CopiedSource(const SourceContainer& container)
367     : copy_(new Container(begin(container), end(container))) {}
368
369   explicit CopiedSource(Container&& container) :
370     copy_(new Container(std::move(container))) {}
371
372   // To enable re-use of cached results.
373   CopiedSource(const CopiedSource<StorageType, Container>& source)
374     : copy_(source.copy_) {}
375
376   template<class Body>
377   void foreach(Body&& body) const {
378     for (const auto& value : *copy_) {
379       body(value);
380     }
381   }
382
383   template<class Handler>
384   bool apply(Handler&& handler) const {
385     // The collection may be reused by others, we can't allow it to be changed.
386     for (const auto& value : *copy_) {
387       if (!handler(value)) {
388         return false;
389       }
390     }
391     return true;
392   }
393 };
394
395 /**
396  * Sequence - For generating values from beginning value, incremented along the
397  * way with the ++ and += operators. Iteration may continue indefinitely by
398  * setting the 'endless' template parameter to true. If set to false, iteration
399  * will stop when value reaches 'end', either inclusively or exclusively,
400  * depending on the template parameter 'endInclusive'. Value type specified
401  * explicitly.
402  *
403  * This type is primarily used through the 'seq' and 'range' function, like:
404  *
405  *   int total = seq(1, 10) | sum;
406  *   auto indexes = range(0, 10);
407  */
408 template<class Value,
409          bool endless,
410          bool endInclusive>
411 class Sequence : public GenImpl<const Value&,
412                                 Sequence<Value, endless, endInclusive>> {
413   static_assert(!std::is_reference<Value>::value &&
414                 !std::is_const<Value>::value, "Value mustn't be const or ref.");
415   Value bounds_[endless ? 1 : 2];
416 public:
417   explicit Sequence(Value begin)
418       : bounds_{std::move(begin)} {
419     static_assert(endless, "Must supply 'end'");
420   }
421
422   Sequence(Value begin,
423            Value end)
424     : bounds_{std::move(begin), std::move(end)} {}
425
426   template<class Handler>
427   bool apply(Handler&& handler) const {
428     Value value = bounds_[0];
429     for (;endless || value < bounds_[1]; ++value) {
430       const Value& arg = value;
431       if (!handler(arg)) {
432         return false;
433       }
434     }
435     if (endInclusive && value == bounds_[1]) {
436       const Value& arg = value;
437       if (!handler(arg)) {
438         return false;
439       }
440     }
441     return true;
442   }
443
444   template<class Body>
445   void foreach(Body&& body) const {
446     Value value = bounds_[0];
447     for (;endless || value < bounds_[1]; ++value) {
448       const Value& arg = value;
449       body(arg);
450     }
451     if (endInclusive && value == bounds_[1]) {
452       const Value& arg = value;
453       body(arg);
454     }
455   }
456
457   static constexpr bool infinite = endless;
458 };
459
460 /**
461  * Chain - For concatenating the values produced by two Generators.
462  *
463  * This type is primarily used through using '+' to combine generators, like:
464  *
465  *   auto nums = seq(1, 10) + seq(20, 30);
466  *   int total = nums | sum;
467  */
468 template<class Value, class First, class Second>
469 class Chain : public GenImpl<Value,
470                              Chain<Value, First, Second>> {
471   First first_;
472   Second second_;
473 public:
474   explicit Chain(First first, Second second)
475       : first_(std::move(first))
476       , second_(std::move(second)) {}
477
478   template<class Handler>
479   bool apply(Handler&& handler) const {
480     return first_.apply(std::forward<Handler>(handler))
481         && second_.apply(std::forward<Handler>(handler));
482   }
483
484   template<class Body>
485   void foreach(Body&& body) const {
486     first_.foreach(std::forward<Body>(body));
487     second_.foreach(std::forward<Body>(body));
488   }
489
490   static constexpr bool infinite = First::infinite || Second::infinite;
491 };
492
493 /**
494  * GenratorBuilder - Helper for GENERTATOR macro.
495  **/
496 template<class Value>
497 struct GeneratorBuilder {
498   template<class Source,
499            class Yield = detail::Yield<Value, Source>>
500   Yield operator+(Source&& source) {
501     return Yield(std::forward<Source>(source));
502   }
503 };
504
505 /**
506  * Yield - For producing values from a user-defined generator by way of a
507  * 'yield' function.
508  **/
509 template<class Value, class Source>
510 class Yield : public GenImpl<Value, Yield<Value, Source>> {
511   Source source_;
512  public:
513   explicit Yield(Source source)
514     : source_(std::move(source)) {
515   }
516
517   template<class Handler>
518   bool apply(Handler&& handler) const {
519     struct Break {};
520     auto body = [&](Value value) {
521       if (!handler(std::forward<Value>(value))) {
522         throw Break();
523       }
524     };
525     try {
526       source_(body);
527       return true;
528     } catch (Break&) {
529       return false;
530     }
531   }
532
533   template<class Body>
534   void foreach(Body&& body) const {
535     source_(std::forward<Body>(body));
536   }
537 };
538
539 template<class Value>
540 class Empty : public GenImpl<Value, Empty<Value>> {
541  public:
542   template<class Handler>
543   bool apply(Handler&&) const { return true; }
544 };
545
546 /*
547  * Operators
548  */
549
550 /**
551  * Map - For producing a sequence of values by passing each value from a source
552  * collection through a predicate.
553  *
554  * This type is usually used through the 'map' or 'mapped' helper function:
555  *
556  *   auto squares = seq(1, 10) | map(square) | asVector;
557  */
558 template<class Predicate>
559 class Map : public Operator<Map<Predicate>> {
560   Predicate pred_;
561  public:
562   Map() {}
563
564   explicit Map(Predicate pred)
565     : pred_(std::move(pred))
566   { }
567
568   template<class Value,
569            class Source,
570            class Result = typename ArgumentReference<
571                             typename std::result_of<Predicate(Value)>::type
572                           >::type>
573   class Generator :
574       public GenImpl<Result, Generator<Value, Source, Result>> {
575     Source source_;
576     Predicate pred_;
577   public:
578     explicit Generator(Source source, const Predicate& pred)
579       : source_(std::move(source)), pred_(pred) {}
580
581     template<class Body>
582     void foreach(Body&& body) const {
583       source_.foreach([&](Value value) {
584         body(pred_(std::forward<Value>(value)));
585       });
586     }
587
588     template<class Handler>
589     bool apply(Handler&& handler) const {
590       return source_.apply([&](Value value) {
591         return handler(pred_(std::forward<Value>(value)));
592       });
593     }
594
595     static constexpr bool infinite = Source::infinite;
596   };
597
598   template<class Source,
599            class Value,
600            class Gen = Generator<Value, Source>>
601   Gen compose(GenImpl<Value, Source>&& source) const {
602     return Gen(std::move(source.self()), pred_);
603   }
604
605   template<class Source,
606            class Value,
607            class Gen = Generator<Value, Source>>
608   Gen compose(const GenImpl<Value, Source>& source) const {
609     return Gen(source.self(), pred_);
610   }
611 };
612
613
614 /**
615  * Filter - For filtering values from a source sequence by a predicate.
616  *
617  * This type is usually used through the 'filter' helper function, like:
618  *
619  *   auto nonEmpty = from(strings)
620  *                 | filter([](const string& str) -> bool {
621  *                     return !str.empty();
622  *                   });
623  */
624 template<class Predicate>
625 class Filter : public Operator<Filter<Predicate>> {
626   Predicate pred_;
627  public:
628   Filter() {}
629   explicit Filter(Predicate pred)
630     : pred_(std::move(pred))
631   { }
632
633   template<class Value,
634            class Source>
635   class Generator : public GenImpl<Value, Generator<Value, Source>> {
636     Source source_;
637     Predicate pred_;
638   public:
639     explicit Generator(Source source, const Predicate& pred)
640       : source_(std::move(source)), pred_(pred) {}
641
642     template<class Body>
643     void foreach(Body&& body) const {
644       source_.foreach([&](Value value) {
645         if (pred_(std::forward<Value>(value))) {
646           body(std::forward<Value>(value));
647         }
648       });
649     }
650
651     template<class Handler>
652     bool apply(Handler&& handler) const {
653       return source_.apply([&](Value value) -> bool {
654         if (pred_(std::forward<Value>(value))) {
655           return handler(std::forward<Value>(value));
656         }
657         return true;
658       });
659     }
660
661     static constexpr bool infinite = Source::infinite;
662   };
663
664   template<class Source,
665            class Value,
666            class Gen = Generator<Value, Source>>
667   Gen compose(GenImpl<Value, Source>&& source) const {
668     return Gen(std::move(source.self()), pred_);
669   }
670
671   template<class Source,
672            class Value,
673            class Gen = Generator<Value, Source>>
674   Gen compose(const GenImpl<Value, Source>& source) const {
675     return Gen(source.self(), pred_);
676   }
677 };
678
679 /**
680  * Until - For producing values from a source until a predicate is satisfied.
681  *
682  * This type is usually used through the 'until' helper function, like:
683  *
684  *   auto best = from(sortedItems)
685  *             | until([](Item& item) { return item.score > 100; })
686  *             | asVector;
687  */
688 template<class Predicate>
689 class Until : public Operator<Until<Predicate>> {
690   Predicate pred_;
691  public:
692   Until() {}
693   explicit Until(Predicate pred)
694     : pred_(std::move(pred))
695   {}
696
697   template<class Value,
698            class Source,
699            class Result = typename std::result_of<Predicate(Value)>::type>
700   class Generator :
701       public GenImpl<Result, Generator<Value, Source, Result>> {
702     Source source_;
703     Predicate pred_;
704    public:
705     explicit Generator(Source source, const Predicate& pred)
706       : source_(std::move(source)), pred_(pred) {}
707
708     template<class Handler>
709     bool apply(Handler&& handler) const {
710       return source_.apply([&](Value value) -> bool {
711         return !pred_(std::forward<Value>(value))
712             && handler(std::forward<Value>(value));
713       });
714     }
715   };
716
717   template<class Source,
718            class Value,
719            class Gen = Generator<Value, Source>>
720   Gen compose(GenImpl<Value, Source>&& source) const {
721     return Gen(std::move(source.self()), pred_);
722   }
723
724   template<class Source,
725            class Value,
726            class Gen = Generator<Value, Source>>
727   Gen compose(const GenImpl<Value, Source>& source) const {
728     return Gen(source.self(), pred_);
729   }
730
731   // Theoretically an 'until' might stop an infinite
732   static constexpr bool infinite = false;
733 };
734
735 /**
736  * Take - For producing up to N values from a source.
737  *
738  * This type is usually used through the 'take' helper function, like:
739  *
740  *   auto best = from(docs)
741  *             | orderByDescending(scoreDoc)
742  *             | take(10);
743  */
744 class Take : public Operator<Take> {
745   size_t count_;
746  public:
747   explicit Take(size_t count)
748     : count_(count) {}
749
750   template<class Value,
751            class Source>
752   class Generator :
753       public GenImpl<Value, Generator<Value, Source>> {
754     Source source_;
755     size_t count_;
756   public:
757     explicit Generator(Source source, size_t count)
758       : source_(std::move(source)) , count_(count) {}
759
760     template<class Handler>
761     bool apply(Handler&& handler) const {
762       if (count_ == 0) { return false; }
763       size_t n = count_;
764       return source_.apply([&](Value value) -> bool {
765           if (!handler(std::forward<Value>(value))) {
766             return false;
767           }
768           return --n;
769         });
770     }
771   };
772
773   template<class Source,
774            class Value,
775            class Gen = Generator<Value, Source>>
776   Gen compose(GenImpl<Value, Source>&& source) const {
777     return Gen(std::move(source.self()), count_);
778   }
779
780   template<class Source,
781            class Value,
782            class Gen = Generator<Value, Source>>
783   Gen compose(const GenImpl<Value, Source>& source) const {
784     return Gen(source.self(), count_);
785   }
786 };
787
788 /**
789  * Sample - For taking a random sample of N elements from a sequence
790  * (without replacement).
791  */
792 template<class Random>
793 class Sample : public Operator<Sample<Random>> {
794   size_t count_;
795   Random rng_;
796  public:
797   explicit Sample(size_t count, Random rng)
798     : count_(count), rng_(std::move(rng)) {}
799
800   template<class Value,
801            class Source,
802            class Rand,
803            class StorageType = typename std::decay<Value>::type>
804   class Generator :
805           public GenImpl<StorageType&&,
806                          Generator<Value, Source, Rand, StorageType>> {
807     static_assert(!Source::infinite, "Cannot sample infinite source!");
808     // It's too easy to bite ourselves if random generator is only 16-bit
809     static_assert(Random::max() >= std::numeric_limits<int32_t>::max() - 1,
810                   "Random number generator must support big values");
811     Source source_;
812     size_t count_;
813     mutable Rand rng_;
814   public:
815     explicit Generator(Source source, size_t count, Random rng)
816       : source_(std::move(source)) , count_(count), rng_(std::move(rng)) {}
817
818     template<class Handler>
819     bool apply(Handler&& handler) const {
820       if (count_ == 0) { return false; }
821       std::vector<StorageType> v;
822       v.reserve(count_);
823       // use reservoir sampling to give each source value an equal chance
824       // of appearing in our output.
825       size_t n = 1;
826       source_.foreach([&](Value value) -> void {
827           if (v.size() < count_) {
828             v.push_back(std::forward<Value>(value));
829           } else {
830             // alternatively, we could create a std::uniform_int_distribution
831             // instead of using modulus, but benchmarks show this has
832             // substantial overhead.
833             size_t index = rng_() % n;
834             if (index < v.size()) {
835               v[index] = std::forward<Value>(value);
836             }
837           }
838           ++n;
839         });
840
841       // output is unsorted!
842       for (auto& val: v) {
843         if (!handler(std::move(val))) {
844           return false;
845         }
846       }
847       return true;
848     }
849   };
850
851   template<class Source,
852            class Value,
853            class Gen = Generator<Value, Source, Random>>
854   Gen compose(GenImpl<Value, Source>&& source) const {
855     return Gen(std::move(source.self()), count_, rng_);
856   }
857
858   template<class Source,
859            class Value,
860            class Gen = Generator<Value, Source, Random>>
861   Gen compose(const GenImpl<Value, Source>& source) const {
862     return Gen(source.self(), count_, rng_);
863   }
864 };
865
866 /**
867  * Skip - For skipping N items from the beginning of a source generator.
868  *
869  * This type is usually used through the 'skip' helper function, like:
870  *
871  *   auto page = from(results)
872  *             | skip(pageSize * startPage)
873  *             | take(10);
874  */
875 class Skip : public Operator<Skip> {
876   size_t count_;
877  public:
878   explicit Skip(size_t count)
879     : count_(count) {}
880
881   template<class Value,
882            class Source>
883   class Generator :
884       public GenImpl<Value, Generator<Value, Source>> {
885     Source source_;
886     size_t count_;
887    public:
888     explicit Generator(Source source, size_t count)
889       : source_(std::move(source)) , count_(count) {}
890
891     template<class Body>
892     void foreach(Body&& body) const {
893       if (count_ == 0) {
894         source_.foreach(body);
895         return;
896       }
897       size_t n = 0;
898       source_.foreach([&](Value value) {
899           if (n < count_) {
900             ++n;
901           } else {
902             body(std::forward<Value>(value));
903           }
904         });
905     }
906
907     template<class Handler>
908     bool apply(Handler&& handler) const {
909       if (count_ == 0) {
910         return source_.apply(handler);
911       }
912       size_t n = 0;
913       return source_.apply([&](Value value) -> bool {
914           if (n < count_) {
915             ++n;
916             return true;
917           }
918           return handler(std::forward<Value>(value));
919         });
920     }
921
922     static constexpr bool infinite = Source::infinite;
923   };
924
925   template<class Source,
926            class Value,
927            class Gen = Generator<Value, Source>>
928   Gen compose(GenImpl<Value, Source>&& source) const {
929     return Gen(std::move(source.self()), count_);
930   }
931
932   template<class Source,
933            class Value,
934            class Gen = Generator<Value, Source>>
935   Gen compose(const GenImpl<Value, Source>& source) const {
936     return Gen(source.self(), count_);
937   }
938 };
939
940 /**
941  * Order - For ordering a sequence of values from a source by key.
942  * The key is extracted by the given selector functor, and this key is then
943  * compared using the specified comparator.
944  *
945  * This type is usually used through the 'order' helper function, like:
946  *
947  *   auto closest = from(places)
948  *                | orderBy([](Place& p) {
949  *                    return -distance(p.location, here);
950  *                  })
951  *                | take(10);
952  */
953 template<class Selector, class Comparer>
954 class Order : public Operator<Order<Selector, Comparer>> {
955   Selector selector_;
956   Comparer comparer_;
957  public:
958   Order() {}
959
960   explicit Order(Selector selector)
961     : selector_(std::move(selector))
962   {}
963
964   Order(Selector selector,
965         Comparer comparer)
966     : selector_(std::move(selector))
967     , comparer_(std::move(comparer))
968   {}
969
970   template<class Value,
971            class Source,
972            class StorageType = typename std::decay<Value>::type,
973            class Result = typename std::result_of<Selector(Value)>::type>
974   class Generator :
975     public GenImpl<StorageType&&,
976                    Generator<Value, Source, StorageType, Result>> {
977     static_assert(!Source::infinite, "Cannot sort infinite source!");
978     Source source_;
979     Selector selector_;
980     Comparer comparer_;
981
982     typedef std::vector<StorageType> VectorType;
983
984     VectorType asVector() const {
985       auto comparer = [&](const StorageType& a, const StorageType& b) {
986         return comparer_(selector_(a), selector_(b));
987       };
988       auto vals = source_ | as<VectorType>();
989       std::sort(vals.begin(), vals.end(), comparer);
990       return std::move(vals);
991     }
992    public:
993     Generator(Source source,
994               Selector selector,
995               Comparer comparer)
996       : source_(std::move(source)),
997         selector_(std::move(selector)),
998         comparer_(std::move(comparer)) {}
999
1000     VectorType operator|(const Collect<VectorType>&) const {
1001       return asVector();
1002     }
1003
1004     VectorType operator|(const CollectTemplate<std::vector>&) const {
1005       return asVector();
1006     }
1007
1008     template<class Body>
1009     void foreach(Body&& body) const {
1010       for (auto& value : asVector()) {
1011         body(std::move(value));
1012       }
1013     }
1014
1015     template<class Handler>
1016     bool apply(Handler&& handler) const {
1017       auto comparer = [&](const StorageType& a, const StorageType& b) {
1018         // swapped for minHeap
1019         return comparer_(selector_(b), selector_(a));
1020       };
1021       auto heap = source_ | as<VectorType>();
1022       std::make_heap(heap.begin(), heap.end(), comparer);
1023       while (!heap.empty()) {
1024         std::pop_heap(heap.begin(), heap.end(), comparer);
1025         if (!handler(std::move(heap.back()))) {
1026           return false;
1027         }
1028         heap.pop_back();
1029       }
1030       return true;
1031     }
1032   };
1033
1034   template<class Source,
1035            class Value,
1036            class Gen = Generator<Value, Source>>
1037   Gen compose(GenImpl<Value, Source>&& source) const {
1038     return Gen(std::move(source.self()), selector_, comparer_);
1039   }
1040
1041   template<class Source,
1042            class Value,
1043            class Gen = Generator<Value, Source>>
1044   Gen compose(const GenImpl<Value, Source>& source) const {
1045     return Gen(source.self(), selector_, comparer_);
1046   }
1047 };
1048
1049 /*
1050  * TypeAssertion - For verifying the exact type of the value produced by a
1051  * generator. Useful for testing and debugging, and acts as a no-op at runtime.
1052  * Pass-through at runtime. Used through the 'assert_type<>()' factory method
1053  * like so:
1054  *
1055  *   auto c =  from(vector) | assert_type<int&>() | sum;
1056  *
1057  */
1058 template<class Expected>
1059 class TypeAssertion : public Operator<TypeAssertion<Expected>> {
1060  public:
1061   template<class Source, class Value>
1062   const Source& compose(const GenImpl<Value, Source>& source) const {
1063     static_assert(std::is_same<Expected, Value>::value,
1064                   "assert_type() check failed");
1065     return source.self();
1066   }
1067
1068   template<class Source, class Value>
1069   Source&& compose(GenImpl<Value, Source>&& source) const {
1070     static_assert(std::is_same<Expected, Value>::value,
1071                   "assert_type() check failed");
1072     return std::move(source.self());
1073   }
1074 };
1075
1076 /**
1077  * Distinct - For filtering duplicates out of a sequence. A selector may be
1078  * provided to generate a key to uniquify for each value.
1079  *
1080  * This type is usually used through the 'distinct' helper function, like:
1081  *
1082  *   auto closest = from(results)
1083  *                | distinctBy([](Item& i) {
1084  *                    return i.target;
1085  *                  })
1086  *                | take(10);
1087  */
1088 template<class Selector>
1089 class Distinct : public Operator<Distinct<Selector>> {
1090   Selector selector_;
1091  public:
1092   Distinct() {}
1093
1094   explicit Distinct(Selector selector)
1095     : selector_(std::move(selector))
1096   {}
1097
1098   template<class Value,
1099            class Source>
1100   class Generator : public GenImpl<Value, Generator<Value, Source>> {
1101     Source source_;
1102     Selector selector_;
1103
1104     typedef typename std::decay<Value>::type StorageType;
1105
1106     // selector_ cannot be passed an rvalue or it would end up passing the husk
1107     // of a value to the downstream operators.
1108     typedef const StorageType& ParamType;
1109
1110     typedef typename std::result_of<Selector(ParamType)>::type KeyType;
1111     typedef typename std::decay<KeyType>::type KeyStorageType;
1112
1113    public:
1114     Generator(Source source,
1115               Selector selector)
1116       : source_(std::move(source)),
1117         selector_(std::move(selector)) {}
1118
1119     template<class Body>
1120     void foreach(Body&& body) const {
1121       std::unordered_set<KeyStorageType> keysSeen;
1122       source_.foreach([&](Value value) {
1123         if (keysSeen.insert(selector_(ParamType(value))).second) {
1124           body(std::forward<Value>(value));
1125         }
1126       });
1127     }
1128
1129     template<class Handler>
1130     bool apply(Handler&& handler) const {
1131       std::unordered_set<KeyStorageType> keysSeen;
1132       return source_.apply([&](Value value) -> bool {
1133         if (keysSeen.insert(selector_(ParamType(value))).second) {
1134           return handler(std::forward<Value>(value));
1135         }
1136         return true;
1137       });
1138     }
1139   };
1140
1141   template<class Source,
1142            class Value,
1143            class Gen = Generator<Value, Source>>
1144   Gen compose(GenImpl<Value, Source>&& source) const {
1145     return Gen(std::move(source.self()), selector_);
1146   }
1147
1148   template<class Source,
1149            class Value,
1150            class Gen = Generator<Value, Source>>
1151   Gen compose(const GenImpl<Value, Source>& source) const {
1152     return Gen(source.self(), selector_);
1153   }
1154 };
1155
1156 /**
1157  * Composed - For building up a pipeline of operations to perform, absent any
1158  * particular source generator. Useful for building up custom pipelines.
1159  *
1160  * This type is usually used by just piping two operators together:
1161  *
1162  * auto valuesOf = filter([](Optional<int>& o) { return o.hasValue(); })
1163  *               | map([](Optional<int>& o) -> int& { return o.value(); });
1164  *
1165  *  auto valuesIncluded = from(optionals) | valuesOf | as<vector>();
1166  */
1167 template<class First,
1168          class Second>
1169 class Composed : public Operator<Composed<First, Second>> {
1170   First first_;
1171   Second second_;
1172  public:
1173   Composed() {}
1174
1175   Composed(First first, Second second)
1176     : first_(std::move(first))
1177     , second_(std::move(second)) {}
1178
1179   template<class Source,
1180            class Value,
1181            class FirstRet = decltype(std::declval<First>()
1182                                      .compose(std::declval<Source>())),
1183            class SecondRet = decltype(std::declval<Second>()
1184                                       .compose(std::declval<FirstRet>()))>
1185   SecondRet compose(const GenImpl<Value, Source>& source) const {
1186     return second_.compose(first_.compose(source.self()));
1187   }
1188
1189   template<class Source,
1190            class Value,
1191            class FirstRet = decltype(std::declval<First>()
1192                                      .compose(std::declval<Source>())),
1193            class SecondRet = decltype(std::declval<Second>()
1194                                       .compose(std::declval<FirstRet>()))>
1195   SecondRet compose(GenImpl<Value, Source>&& source) const {
1196     return second_.compose(first_.compose(std::move(source.self())));
1197   }
1198 };
1199
1200 /*
1201  * Sinks
1202  */
1203
1204 /**
1205  * FoldLeft - Left-associative functional fold. For producing an aggregate value
1206  * from a seed and a folder function. Useful for custom aggregators on a
1207  * sequence.
1208  *
1209  * This type is primarily used through the 'foldl' helper method, like:
1210  *
1211  *   double movingAverage = from(values)
1212  *                        | foldl(0.0, [](double avg, double sample) {
1213  *                            return sample * 0.1 + avg * 0.9;
1214  *                          });
1215  */
1216 template<class Seed,
1217          class Fold>
1218 class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
1219   Seed seed_;
1220   Fold fold_;
1221  public:
1222   FoldLeft() {}
1223   FoldLeft(Seed seed,
1224            Fold fold)
1225     : seed_(std::move(seed))
1226     , fold_(std::move(fold))
1227   {}
1228
1229   template<class Source,
1230            class Value>
1231   Seed compose(const GenImpl<Value, Source>& source) const {
1232     static_assert(!Source::infinite, "Cannot foldl infinite source");
1233     Seed accum = seed_;
1234     source | [&](Value v) {
1235       accum = fold_(std::move(accum), std::forward<Value>(v));
1236     };
1237     return accum;
1238   }
1239 };
1240
1241 /**
1242  * First - For finding the first value in a sequence.
1243  *
1244  * This type is primarily used through the 'first' static value, like:
1245  *
1246  *   int firstThreeDigitPrime = seq(100) | filter(isPrime) | first;
1247  */
1248 class First : public Operator<First> {
1249  public:
1250   First() { }
1251
1252   template<class Source,
1253            class Value,
1254            class StorageType = typename std::decay<Value>::type>
1255   StorageType compose(const GenImpl<Value, Source>& source) const {
1256     Optional<StorageType> accum;
1257     source | [&](Value v) -> bool {
1258       accum = std::forward<Value>(v);
1259       return false;
1260     };
1261     if (!accum.hasValue()) {
1262       throw EmptySequence();
1263     }
1264     return std::move(accum.value());
1265   }
1266 };
1267
1268
1269 /**
1270  * Any - For determining whether any values in a sequence satisfy a predicate.
1271  *
1272  * This type is primarily used through the 'any' static value, like:
1273  *
1274  *   bool any20xPrimes = seq(200, 210) | filter(isPrime) | any;
1275  *
1276  * Note that it may also be used like so:
1277  *
1278  *   bool any20xPrimes = seq(200, 210) | any(isPrime);
1279  *
1280  */
1281 class Any : public Operator<Any> {
1282  public:
1283   Any() { }
1284
1285   template<class Source,
1286            class Value>
1287   bool compose(const GenImpl<Value, Source>& source) const {
1288     bool any = false;
1289     source | [&](Value v) -> bool {
1290       any = true;
1291       return false;
1292     };
1293     return any;
1294   }
1295
1296   /**
1297    * Convenience function for use like:
1298    *
1299    *  bool found = gen | any([](int i) { return i * i > 100; });
1300    */
1301   template<class Predicate,
1302            class Filter = Filter<Predicate>,
1303            class Composed = Composed<Filter, Any>>
1304   Composed operator()(Predicate pred) const {
1305     return Composed(Filter(std::move(pred)), Any());
1306   }
1307 };
1308
1309 /**
1310  * All - For determining whether all values in a sequence satisfy a predicate.
1311  *
1312  * This type is primarily used through the 'any' static value, like:
1313  *
1314  *   bool valid = from(input) | all(validate);
1315  *
1316  * Note: Passing an empty sequence through 'all()' will always return true.
1317  */
1318 template<class Predicate>
1319 class All : public Operator<All<Predicate>> {
1320   Predicate pred_;
1321  public:
1322   All() {}
1323   explicit All(Predicate pred)
1324     : pred_(std::move(pred))
1325   { }
1326
1327   template<class Source,
1328            class Value>
1329   bool compose(const GenImpl<Value, Source>& source) const {
1330     static_assert(!Source::infinite, "Cannot call 'all' on infinite source");
1331     bool all = true;
1332     source | [&](Value v) -> bool {
1333       if (!pred_(std::forward<Value>(v))) {
1334         all = false;
1335         return false;
1336       }
1337       return true;
1338     };
1339     return all;
1340   }
1341 };
1342
1343 /**
1344  * Reduce - Functional reduce, for recursively combining values from a source
1345  * using a reducer function until there is only one item left. Useful for
1346  * combining values when an empty sequence doesn't make sense.
1347  *
1348  * This type is primarily used through the 'reduce' helper method, like:
1349  *
1350  *   sring longest = from(names)
1351  *                 | reduce([](string&& best, string& current) {
1352  *                     return best.size() >= current.size() ? best : current;
1353  *                   });
1354  */
1355 template<class Reducer>
1356 class Reduce : public Operator<Reduce<Reducer>> {
1357   Reducer reducer_;
1358  public:
1359   Reduce() {}
1360   explicit Reduce(Reducer reducer)
1361     : reducer_(std::move(reducer))
1362   {}
1363
1364   template<class Source,
1365            class Value,
1366            class StorageType = typename std::decay<Value>::type>
1367   StorageType compose(const GenImpl<Value, Source>& source) const {
1368     Optional<StorageType> accum;
1369     source | [&](Value v) {
1370       if (accum.hasValue()) {
1371         accum = reducer_(std::move(accum.value()), std::forward<Value>(v));
1372       } else {
1373         accum = std::forward<Value>(v);
1374       }
1375     };
1376     if (!accum.hasValue()) {
1377       throw EmptySequence();
1378     }
1379     return accum.value();
1380   }
1381 };
1382
1383 /**
1384  * Count - for simply counting the items in a collection.
1385  *
1386  * This type is usually used through its singleton, 'count':
1387  *
1388  *   auto shortPrimes = seq(1, 100) | filter(isPrime) | count;
1389  */
1390 class Count : public Operator<Count> {
1391  public:
1392   Count() { }
1393
1394   template<class Source,
1395            class Value>
1396   size_t compose(const GenImpl<Value, Source>& source) const {
1397     static_assert(!Source::infinite, "Cannot count infinite source");
1398     return foldl(size_t(0),
1399                  [](size_t accum, Value v) {
1400                    return accum + 1;
1401                  }).compose(source);
1402   }
1403 };
1404
1405 /**
1406  * Sum - For simply summing up all the values from a source.
1407  *
1408  * This type is usually used through its singleton, 'sum':
1409  *
1410  *   auto gaussSum = seq(1, 100) | sum;
1411  */
1412 class Sum : public Operator<Sum> {
1413  public:
1414   Sum() : Operator<Sum>() {}
1415
1416   template<class Source,
1417            class Value,
1418            class StorageType = typename std::decay<Value>::type>
1419   StorageType compose(const GenImpl<Value, Source>& source) const {
1420     static_assert(!Source::infinite, "Cannot sum infinite source");
1421     return foldl(StorageType(0),
1422                  [](StorageType&& accum, Value v) {
1423                    return std::move(accum) + std::forward<Value>(v);
1424                  }).compose(source);
1425   }
1426 };
1427
1428 /**
1429  * Contains - For testing whether a value matching the given value is contained
1430  * in a sequence.
1431  *
1432  * This type should be used through the 'contains' helper method, like:
1433  *
1434  *   bool contained = seq(1, 10) | map(square) | contains(49);
1435  */
1436 template<class Needle>
1437 class Contains : public Operator<Contains<Needle>> {
1438   Needle needle_;
1439  public:
1440   explicit Contains(Needle needle)
1441     : needle_(std::move(needle))
1442   {}
1443
1444   template<class Source,
1445            class Value,
1446            class StorageType = typename std::decay<Value>::type>
1447   bool compose(const GenImpl<Value, Source>& source) const {
1448     static_assert(!Source::infinite,
1449                   "Calling contains on an infinite source might cause "
1450                   "an infinite loop.");
1451     return !(source | [this](Value value) {
1452         return !(needle_ == std::forward<Value>(value));
1453       });
1454   }
1455 };
1456
1457 /**
1458  * Min - For a value which minimizes a key, where the key is determined by a
1459  * given selector, and compared by given comparer.
1460  *
1461  * This type is usually used through the singletone 'min' or through the helper
1462  * functions 'minBy' and 'maxBy'.
1463  *
1464  *   auto oldest = from(people)
1465  *               | minBy([](Person& p) {
1466  *                   return p.dateOfBirth;
1467  *                 });
1468  */
1469 template<class Selector,
1470          class Comparer>
1471 class Min : public Operator<Min<Selector, Comparer>> {
1472   Selector selector_;
1473   Comparer comparer_;
1474  public:
1475   Min() {}
1476
1477   explicit Min(Selector selector)
1478     : selector_(std::move(selector))
1479   {}
1480
1481   Min(Selector selector,
1482         Comparer comparer)
1483     : selector_(std::move(selector))
1484     , comparer_(std::move(comparer))
1485   {}
1486
1487   template<class Value,
1488            class Source,
1489            class StorageType = typename std::decay<Value>::type,
1490            class Key = typename std::decay<
1491                typename std::result_of<Selector(Value)>::type
1492              >::type>
1493   StorageType compose(const GenImpl<Value, Source>& source) const {
1494     Optional<StorageType> min;
1495     Optional<Key> minKey;
1496     source | [&](Value v) {
1497       Key key = selector_(std::forward<Value>(v));
1498       if (!minKey.hasValue() || comparer_(key, minKey.value())) {
1499         minKey = key;
1500         min = std::forward<Value>(v);
1501       }
1502     };
1503     if (!min.hasValue()) {
1504       throw EmptySequence();
1505     }
1506     return min.value();
1507   }
1508 };
1509
1510 /**
1511  * Append - For collecting values from a source into a given output container
1512  * by appending.
1513  *
1514  * This type is usually used through the helper function 'appendTo', like:
1515  *
1516  *   vector<int64_t> ids;
1517  *   from(results) | map([](Person& p) { return p.id })
1518  *                 | appendTo(ids);
1519  */
1520 template<class Collection>
1521 class Append : public Operator<Append<Collection>> {
1522   Collection* collection_;
1523  public:
1524   explicit Append(Collection* collection)
1525     : collection_(collection)
1526   {}
1527
1528   template<class Value,
1529            class Source>
1530   Collection& compose(const GenImpl<Value, Source>& source) const {
1531     source | [&](Value v) {
1532       collection_->insert(collection_->end(), std::forward<Value>(v));
1533     };
1534     return *collection_;
1535   }
1536 };
1537
1538 /**
1539  * Collect - For collecting values from a source in a collection of the desired
1540  * type.
1541  *
1542  * This type is usually used through the helper function 'as', like:
1543  *
1544  *   std::string upper = from(stringPiece)
1545  *                     | map(&toupper)
1546  *                     | as<std::string>();
1547  */
1548 template<class Collection>
1549 class Collect : public Operator<Collect<Collection>> {
1550  public:
1551   Collect() { }
1552
1553   template<class Value,
1554            class Source,
1555            class StorageType = typename std::decay<Value>::type>
1556   Collection compose(const GenImpl<Value, Source>& source) const {
1557     Collection collection;
1558     source | [&](Value v) {
1559       collection.insert(collection.end(), std::forward<Value>(v));
1560     };
1561     return collection;
1562   }
1563 };
1564
1565
1566 /**
1567  * CollectTemplate - For collecting values from a source in a collection
1568  * constructed using the specified template type. Given the type of values
1569  * produced by the given generator, the collection type will be:
1570  *   Container<Value, Allocator<Value>>
1571  *
1572  * The allocator defaults to std::allocator, so this may be used for the STL
1573  * containers by simply using operators like 'as<set>', 'as<deque>',
1574  * 'as<vector>'. 'as', here is the helper method which is the usual means of
1575  * consturcting this operator.
1576  *
1577  * Example:
1578  *
1579  *   set<string> uniqueNames = from(names) | as<set>();
1580  */
1581 template<template<class, class> class Container,
1582          template<class> class Allocator>
1583 class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
1584  public:
1585   CollectTemplate() { }
1586
1587   template<class Value,
1588            class Source,
1589            class StorageType = typename std::decay<Value>::type,
1590            class Collection = Container<StorageType, Allocator<StorageType>>>
1591   Collection compose(const GenImpl<Value, Source>& source) const {
1592     Collection collection;
1593     source | [&](Value v) {
1594       collection.insert(collection.end(), std::forward<Value>(v));
1595     };
1596     return collection;
1597   }
1598 };
1599
1600 /**
1601  * Concat - For flattening generators of generators.
1602  *
1603  * This type is usually used through the 'concat' static value, like:
1604  *
1605  *   auto edges =
1606  *       from(nodes)
1607  *     | map([](Node& x) {
1608  *           return from(x.neighbors)
1609  *                | map([&](Node& y) {
1610  *                    return Edge(x, y);
1611  *                  });
1612  *         })
1613  *     | concat
1614  *     | as<std::set>();
1615  */
1616 class Concat : public Operator<Concat> {
1617  public:
1618   Concat() { }
1619
1620   template<class Inner,
1621            class Source,
1622            class InnerValue = typename std::decay<Inner>::type::ValueType>
1623   class Generator :
1624       public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
1625     Source source_;
1626    public:
1627     explicit Generator(Source source)
1628       : source_(std::move(source)) {}
1629
1630     template<class Handler>
1631     bool apply(Handler&& handler) const {
1632       return source_.apply([&](Inner inner) -> bool {
1633           return inner.apply(std::forward<Handler>(handler));
1634         });
1635     }
1636
1637     template<class Body>
1638     void foreach(Body&& body) const {
1639       source_.foreach([&](Inner inner) {
1640           inner.foreach(std::forward<Body>(body));
1641         });
1642     }
1643
1644     static constexpr bool infinite = Source::infinite;
1645   };
1646
1647   template<class Value,
1648            class Source,
1649            class Gen = Generator<Value, Source>>
1650   Gen compose(GenImpl<Value, Source>&& source) const {
1651     return Gen(std::move(source.self()));
1652   }
1653
1654   template<class Value,
1655            class Source,
1656            class Gen = Generator<Value, Source>>
1657   Gen compose(const GenImpl<Value, Source>& source) const {
1658     return Gen(source.self());
1659   }
1660 };
1661
1662 /**
1663  * RangeConcat - For flattening generators of iterables.
1664  *
1665  * This type is usually used through the 'rconcat' static value, like:
1666  *
1667  *   map<int, vector<int>> adjacency;
1668  *   auto sinks =
1669  *       from(adjacency)
1670  *     | get<1>()
1671  *     | rconcat()
1672  *     | as<std::set>();
1673  */
1674 class RangeConcat : public Operator<RangeConcat> {
1675  public:
1676   RangeConcat() { }
1677
1678   template<class Source,
1679            class Range,
1680            class InnerValue = typename ValueTypeOfRange<Range>::RefType>
1681   class Generator
1682     : public GenImpl<InnerValue, Generator<Source, Range, InnerValue>> {
1683     Source source_;
1684    public:
1685     explicit Generator(Source source)
1686       : source_(std::move(source)) {}
1687
1688     template<class Body>
1689     void foreach(Body&& body) const {
1690       source_.foreach([&](Range range) {
1691           for (auto& value : range) {
1692             body(value);
1693           }
1694         });
1695     }
1696
1697     template<class Handler>
1698     bool apply(Handler&& handler) const {
1699       return source_.apply([&](Range range) -> bool {
1700           for (auto& value : range) {
1701             if (!handler(value)) {
1702               return false;
1703             }
1704           }
1705           return true;
1706         });
1707     }
1708   };
1709
1710   template<class Value,
1711            class Source,
1712            class Gen = Generator<Source, Value>>
1713   Gen compose(GenImpl<Value, Source>&& source) const {
1714     return Gen(std::move(source.self()));
1715   }
1716
1717   template<class Value,
1718            class Source,
1719            class Gen = Generator<Source, Value>>
1720   Gen compose(const GenImpl<Value, Source>& source) const {
1721     return Gen(source.self());
1722   }
1723 };
1724
1725 } //::detail
1726
1727 /**
1728  * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
1729  **/
1730 template<class Value>
1731 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
1732   class WrapperBase {
1733    public:
1734     virtual ~WrapperBase() {}
1735     virtual bool apply(const std::function<bool(Value)>& handler) const = 0;
1736     virtual void foreach(const std::function<void(Value)>& body) const = 0;
1737     virtual std::unique_ptr<const WrapperBase> clone() const = 0;
1738   };
1739
1740   template<class Wrapped>
1741   class WrapperImpl : public WrapperBase {
1742     Wrapped wrapped_;
1743    public:
1744     explicit WrapperImpl(Wrapped wrapped)
1745      : wrapped_(std::move(wrapped)) {
1746     }
1747
1748     virtual bool apply(const std::function<bool(Value)>& handler) const {
1749       return wrapped_.apply(handler);
1750     }
1751
1752     virtual void foreach(const std::function<void(Value)>& body) const {
1753       wrapped_.foreach(body);
1754     }
1755
1756     virtual std::unique_ptr<const WrapperBase> clone() const {
1757       return std::unique_ptr<const WrapperBase>(new WrapperImpl(wrapped_));
1758     }
1759   };
1760
1761   std::unique_ptr<const WrapperBase> wrapper_;
1762
1763  public:
1764   template<class Self>
1765   /* implicit */ VirtualGen(Self source)
1766    : wrapper_(new WrapperImpl<Self>(std::move(source)))
1767   { }
1768
1769   VirtualGen(VirtualGen&& source)
1770    : wrapper_(std::move(source.wrapper_))
1771   { }
1772
1773   VirtualGen(const VirtualGen& source)
1774    : wrapper_(source.wrapper_->clone())
1775   { }
1776
1777   VirtualGen& operator=(const VirtualGen& source) {
1778     wrapper_.reset(source.wrapper_->clone());
1779     return *this;
1780   }
1781
1782   VirtualGen& operator=(VirtualGen&& source) {
1783     wrapper_= std::move(source.wrapper_);
1784     return *this;
1785   }
1786
1787   bool apply(const std::function<bool(Value)>& handler) const {
1788     return wrapper_->apply(handler);
1789   }
1790
1791   void foreach(const std::function<void(Value)>& body) const {
1792     wrapper_->foreach(body);
1793   }
1794 };
1795
1796 /**
1797  * non-template operators, statically defined to avoid the need for anything but
1798  * the header.
1799  */
1800 static const detail::Sum sum;
1801
1802 static const detail::Count count;
1803
1804 static const detail::First first;
1805
1806 static const detail::Any any;
1807
1808 static const detail::Min<Identity, Less> min;
1809
1810 static const detail::Min<Identity, Greater> max;
1811
1812 static const detail::Order<Identity> order;
1813
1814 static const detail::Distinct<Identity> distinct;
1815
1816 static const detail::Map<Move> move;
1817
1818 static const detail::Concat concat;
1819
1820 static const detail::RangeConcat rconcat;
1821
1822 inline detail::Take take(size_t count) {
1823   return detail::Take(count);
1824 }
1825
1826 template<class Random = std::default_random_engine>
1827 inline detail::Sample<Random> sample(size_t count, Random rng = Random()) {
1828   return detail::Sample<Random>(count, std::move(rng));
1829 }
1830
1831 inline detail::Skip skip(size_t count) {
1832   return detail::Skip(count);
1833 }
1834
1835 }} //folly::gen
1836
1837 #pragma GCC diagnostic pop