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