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