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