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