2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef FOLLY_GEN_BASE_H_
18 #error This file may only be included from folly/gen/Base.h
21 #include <folly/Portability.h>
23 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
25 FOLLY_GCC_DISABLE_WARNING("-Wshadow")
31 * ArgumentReference - For determining ideal argument type to receive a value.
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&
44 * Group - The output objects from the GroupBy operator
46 template <class Key, class Value>
47 class Group : public GenImpl<Value&&, Group<Key, Value>> {
49 static_assert(!std::is_reference<Key>::value &&
50 !std::is_reference<Value>::value,
51 "Key and Value must be decayed types");
53 typedef std::vector<Value> VectorType;
55 typedef Value ValueType;
57 Group(Key key, VectorType values)
58 : key_(std::move(key)), values_(std::move(values)) {}
60 const Key& key() const { return key_; }
62 size_t size() const { return values_.size(); }
63 const VectorType& values() const { return values_; }
64 VectorType& values() { return values_; }
66 VectorType operator|(const detail::Collect<VectorType>&) const {
70 VectorType operator|(const detail::CollectTemplate<std::vector>&) const {
75 void foreach(Body&& body) const {
76 for (auto& value : values_) {
77 body(std::move(value));
81 template <class Handler>
82 bool apply(Handler&& handler) const {
83 for (auto& value : values_) {
84 if (!handler(std::move(value))) {
91 // GroupBy only takes in finite generators, so we only have finite groups
92 static constexpr bool infinite = false;
96 mutable VectorType values_;
101 // Classes used for the implementation of Sources, Operators, and Sinks
104 ******************************* Sources ***************************************
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.
114 * This type is primarily used through the 'from' helper method, like:
116 * string& longestName = from(names)
117 * | maxBy([](string& s) { return s.size() });
119 template <class Container, class Value>
120 class ReferencedSource
121 : public GenImpl<Value, ReferencedSource<Container, Value>> {
122 Container* container_;
125 explicit ReferencedSource(Container* container) : container_(container) {}
127 template <class Body>
128 void foreach(Body&& body) const {
129 for (auto& value : *container_) {
130 body(std::forward<Value>(value));
134 template <class Handler>
135 bool apply(Handler&& handler) const {
136 for (auto& value : *container_) {
137 if (!handler(std::forward<Value>(value))) {
144 // from takes in a normal stl structure, which are all finite
145 static constexpr bool infinite = false;
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.
154 * This type is primarily used through the 'fromCopy' function, like:
156 * auto sourceCopy = fromCopy(makeAVector());
157 * auto sum = sourceCopy | sum;
158 * auto max = sourceCopy | max;
160 * Though it is also used for the initializer_list specialization of from().
162 template <class StorageType, class Container>
164 : public GenImpl<const StorageType&, CopiedSource<StorageType, Container>> {
165 static_assert(!std::is_reference<StorageType>::value,
166 "StorageType must be decayed");
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
174 static_assert(!std::is_reference<Container>::value,
175 "Can't copy into a reference");
176 std::shared_ptr<const Container> copy_;
179 typedef Container ContainerType;
181 template <class SourceContainer>
182 explicit CopiedSource(const SourceContainer& container)
183 : copy_(new Container(begin(container), end(container))) {}
185 explicit CopiedSource(Container&& container)
186 : copy_(new Container(std::move(container))) {}
188 // To enable re-use of cached results.
189 CopiedSource(const CopiedSource<StorageType, Container>& source)
190 : copy_(source.copy_) {}
192 template <class Body>
193 void foreach(Body&& body) const {
194 for (const auto& value : *copy_) {
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)) {
210 // from takes in a normal stl structure, which are all finite
211 static constexpr bool infinite = false;
215 * RangeSource - For producing values from a folly::Range. Useful for referring
216 * to a slice of some container.
218 * This type is primarily used through the 'from' function, like:
220 * auto rangeSource = from(folly::range(v.begin(), v.end()));
221 * auto sum = rangeSource | sum;
223 * Reminder: Be careful not to invalidate iterators when using ranges like this.
225 template <class Iterator>
226 class RangeSource : public GenImpl<typename Range<Iterator>::reference,
227 RangeSource<Iterator>> {
228 Range<Iterator> range_;
231 RangeSource() = default;
232 explicit RangeSource(Range<Iterator> range) : range_(std::move(range)) {}
234 template <class Handler>
235 bool apply(Handler&& handler) const {
236 for (auto& value : range_) {
237 if (!handler(value)) {
244 template <class Body>
245 void foreach(Body&& body) const {
246 for (auto& value : range_) {
251 // folly::Range only supports finite ranges
252 static constexpr bool infinite = false;
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.
260 * This type is primarily used through the 'seq' and 'range' function, like:
262 * int total = seq(1, 10) | sum;
263 * auto indexes = range(0, 10);
264 * auto endless = seq(0); // 0, 1, 2, 3, ...
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.");
275 explicit Sequence(Value start, SequenceImpl impl)
276 : start_(std::move(start)), impl_(std::move(impl)) {}
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)) {
288 template <class Body>
289 void foreach(Body&& body) const {
290 for (Value current = start_; impl_.test(current); impl_.step(current)) {
295 // Let the implementation say if we are infinite or not
296 static constexpr bool infinite = SequenceImpl::infinite;
300 * Sequence implementations (range, sequence, infinite, with/without step)
302 template <class Value>
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;
313 template <class Value, class Distance>
314 class RangeWithStepImpl {
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;
326 template <class Value>
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;
337 template <class Value, class Distance>
338 class SeqWithStepImpl {
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;
350 template <class Value>
353 bool test(const Value& /* current */) const { return true; }
354 void step(Value& current) const { ++current; }
355 static constexpr bool infinite = true;
359 * GenratorBuilder - Helper for GENERTATOR macro.
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));
371 * Yield - For producing values from a user-defined generator by way of a
374 template <class Value, class Source>
375 class Yield : public GenImpl<Value, Yield<Value, Source>> {
379 explicit Yield(Source source) : source_(std::move(source)) {}
381 template <class Handler>
382 bool apply(Handler&& handler) const {
384 auto body = [&](Value value) {
385 if (!handler(std::forward<Value>(value))) {
397 template <class Body>
398 void foreach(Body&& body) const {
399 source_(std::forward<Body>(body));
403 template <class Value>
404 class Empty : public GenImpl<Value, Empty<Value>> {
406 template <class Handler>
407 bool apply(Handler&&) const {
411 template <class Body>
412 void foreach(Body&&) const {}
414 // No values, so finite
415 static constexpr bool infinite = false;
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");
425 explicit SingleReference(Value& ref) : ptr_(&ref) {}
427 template <class Handler>
428 bool apply(Handler&& handler) const {
429 return handler(*ptr_);
432 template <class Body>
433 void foreach(Body&& body) const {
437 // One value, so finite
438 static constexpr bool infinite = false;
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");
448 explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
450 template <class Handler>
451 bool apply(Handler&& handler) const {
452 return handler(value_);
455 template <class Body>
456 void foreach(Body&& body) const {
460 // One value, so finite
461 static constexpr bool infinite = false;
465 ***************************** Operators ***************************************
469 * Map - For producing a sequence of values by passing each value from a source
470 * collection through a predicate.
472 * This type is usually used through the 'map' or 'mapped' helper function:
474 * auto squares = seq(1, 10) | map(square) | asVector;
476 template <class Predicate>
477 class Map : public Operator<Map<Predicate>> {
483 explicit Map(Predicate pred) : pred_(std::move(pred)) {}
485 template <class Value,
487 class Result = typename ArgumentReference<
488 typename std::result_of<Predicate(Value)>::type>::type>
489 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
494 explicit Generator(Source source, const Predicate& pred)
495 : source_(std::move(source)), pred_(pred) {}
497 template <class Body>
498 void foreach(Body&& body) const {
500 [&](Value value) { body(pred_(std::forward<Value>(value))); });
503 template <class Handler>
504 bool apply(Handler&& handler) const {
505 return source_.apply([&](Value value) {
506 return handler(pred_(std::forward<Value>(value)));
510 static constexpr bool infinite = Source::infinite;
513 template <class Source,
515 class Gen = Generator<Value, Source>>
516 Gen compose(GenImpl<Value, Source>&& source) const {
517 return Gen(std::move(source.self()), pred_);
520 template <class Source,
522 class Gen = Generator<Value, Source>>
523 Gen compose(const GenImpl<Value, Source>& source) const {
524 return Gen(source.self(), pred_);
529 * Filter - For filtering values from a source sequence by a predicate.
531 * This type is usually used through the 'filter' helper function, like:
533 * auto nonEmpty = from(strings)
534 * | filter([](const string& str) -> bool {
535 * return !str.empty();
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,
541 * auto nonNull = from(pointers) | filter();
543 * will give a vector of all the pointers != nullptr.
545 template <class Predicate>
546 class Filter : public Operator<Filter<Predicate>> {
551 explicit Filter(Predicate pred) : pred_(std::move(pred)) {}
553 template <class Value, class Source>
554 class Generator : public GenImpl<Value, Generator<Value, Source>> {
559 explicit Generator(Source source, const Predicate& pred)
560 : source_(std::move(source)), pred_(pred) {}
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
567 body(std::forward<Value>(value));
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
577 return handler(std::forward<Value>(value));
583 static constexpr bool infinite = Source::infinite;
586 template <class Source,
588 class Gen = Generator<Value, Source>>
589 Gen compose(GenImpl<Value, Source>&& source) const {
590 return Gen(std::move(source.self()), pred_);
593 template <class Source,
595 class Gen = Generator<Value, Source>>
596 Gen compose(const GenImpl<Value, Source>& source) const {
597 return Gen(source.self(), pred_);
602 * Until - For producing values from a source until a predicate is satisfied.
604 * This type is usually used through the 'until' helper function, like:
606 * auto best = from(sortedItems)
607 * | until([](Item& item) { return item.score > 100; })
610 template <class Predicate>
611 class Until : public Operator<Until<Predicate>> {
616 explicit Until(Predicate pred) : pred_(std::move(pred)) {}
618 template <class Value, class Source>
619 class Generator : public GenImpl<Value, Generator<Value, Source>> {
624 explicit Generator(Source source, const Predicate& pred)
625 : source_(std::move(source)), pred_(pred) {}
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
634 if (!handler(std::forward<Value>(value))) {
643 // Theoretically an 'until' might stop an infinite
644 static constexpr bool infinite = false;
647 template <class Source,
649 class Gen = Generator<Value, Source>>
650 Gen compose(GenImpl<Value, Source>&& source) const {
651 return Gen(std::move(source.self()), pred_);
654 template <class Source,
656 class Gen = Generator<Value, Source>>
657 Gen compose(const GenImpl<Value, Source>& source) const {
658 return Gen(source.self(), pred_);
663 * Take - For producing up to N values from a source.
665 * This type is usually used through the 'take' helper function, like:
667 * auto best = from(docs)
668 * | orderByDescending(scoreDoc)
671 class Take : public Operator<Take> {
675 explicit Take(size_t count) : count_(count) {}
677 template <class Value, class Source>
678 class Generator : public GenImpl<Value, Generator<Value, Source>> {
683 explicit Generator(Source source, size_t count)
684 : source_(std::move(source)), count_(count) {}
686 template <class Handler>
687 bool apply(Handler&& handler) const {
692 bool cancelled = false;
693 source_.apply([&](Value value) -> bool {
694 if (!handler(std::forward<Value>(value))) {
703 // take will stop an infinite generator
704 static constexpr bool infinite = false;
707 template <class Source,
709 class Gen = Generator<Value, Source>>
710 Gen compose(GenImpl<Value, Source>&& source) const {
711 return Gen(std::move(source.self()), count_);
714 template <class Source,
716 class Gen = Generator<Value, Source>>
717 Gen compose(const GenImpl<Value, Source>& source) const {
718 return Gen(source.self(), count_);
723 * Stride - For producing every Nth value from a source.
725 * This type is usually used through the 'stride' helper function, like:
727 * auto half = from(samples)
730 class Stride : public Operator<Stride> {
734 explicit Stride(size_t stride) : stride_(stride) {
736 throw std::invalid_argument("stride must not be 0");
740 template <class Value, class Source>
741 class Generator : public GenImpl<Value, Generator<Value, Source>> {
746 explicit Generator(Source source, size_t stride)
747 : source_(std::move(source)), stride_(stride) {}
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))) {
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));
774 // Taking every Nth of an infinite list is still infinte
775 static constexpr bool infinite = Source::infinite;
778 template <class Source,
780 class Gen = Generator<Value, Source>>
781 Gen compose(GenImpl<Value, Source>&& source) const {
782 return Gen(std::move(source.self()), stride_);
785 template <class Source,
787 class Gen = Generator<Value, Source>>
788 Gen compose(const GenImpl<Value, Source>& source) const {
789 return Gen(source.self(), stride_);
794 * Sample - For taking a random sample of N elements from a sequence
795 * (without replacement).
797 template <class Random>
798 class Sample : public Operator<Sample<Random>> {
803 explicit Sample(size_t count, Random rng)
804 : count_(count), rng_(std::move(rng)) {}
806 template <class Value,
809 class StorageType = typename std::decay<Value>::type>
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");
822 explicit Generator(Source source, size_t count, Random rng)
823 : source_(std::move(source)), count_(count), rng_(std::move(rng)) {}
825 template <class Handler>
826 bool apply(Handler&& handler) const {
830 std::vector<StorageType> v;
832 // use reservoir sampling to give each source value an equal chance
833 // of appearing in our output.
835 source_.foreach([&](Value value) -> void {
836 if (v.size() < count_) {
837 v.push_back(std::forward<Value>(value));
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);
850 // output is unsorted!
851 for (auto& val : v) {
852 if (!handler(std::move(val))) {
859 // Only takes N elements, so finite
860 static constexpr bool infinite = false;
863 template <class Source,
865 class Gen = Generator<Value, Source, Random>>
866 Gen compose(GenImpl<Value, Source>&& source) const {
867 return Gen(std::move(source.self()), count_, rng_);
870 template <class Source,
872 class Gen = Generator<Value, Source, Random>>
873 Gen compose(const GenImpl<Value, Source>& source) const {
874 return Gen(source.self(), count_, rng_);
879 * Skip - For skipping N items from the beginning of a source generator.
881 * This type is usually used through the 'skip' helper function, like:
883 * auto page = from(results)
884 * | skip(pageSize * startPage)
887 class Skip : public Operator<Skip> {
891 explicit Skip(size_t count) : count_(count) {}
893 template <class Value, class Source>
894 class Generator : public GenImpl<Value, Generator<Value, Source>> {
899 explicit Generator(Source source, size_t count)
900 : source_(std::move(source)), count_(count) {}
902 template <class Body>
903 void foreach(Body&& body) const {
905 source_.foreach(body);
909 source_.foreach([&](Value value) {
913 body(std::forward<Value>(value));
918 template <class Handler>
919 bool apply(Handler&& handler) const {
921 return source_.apply(std::forward<Handler>(handler));
924 return source_.apply([&](Value value) -> bool {
929 return handler(std::forward<Value>(value));
933 // Skipping N items of an infinite source is still infinite
934 static constexpr bool infinite = Source::infinite;
937 template <class Source,
939 class Gen = Generator<Value, Source>>
940 Gen compose(GenImpl<Value, Source>&& source) const {
941 return Gen(std::move(source.self()), count_);
944 template <class Source,
946 class Gen = Generator<Value, Source>>
947 Gen compose(const GenImpl<Value, Source>& source) const {
948 return Gen(source.self(), count_);
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.
957 * This type is usually used through the 'order' helper function, like:
959 * auto closest = from(places)
960 * | orderBy([](Place& p) {
961 * return -distance(p.location, here);
965 template <class Selector, class Comparer>
966 class Order : public Operator<Order<Selector, Comparer>> {
973 explicit Order(Selector selector) : selector_(std::move(selector)) {}
975 Order(Selector selector, Comparer comparer)
976 : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
978 template <class Value,
980 class StorageType = typename std::decay<Value>::type,
981 class Result = typename std::result_of<Selector(Value)>::type>
983 : public GenImpl<StorageType&&,
984 Generator<Value, Source, StorageType, Result>> {
985 static_assert(!Source::infinite, "Cannot sort infinite source!");
990 typedef std::vector<StorageType> VectorType;
992 VectorType asVector() const {
993 auto comparer = [&](const StorageType& a, const StorageType& b) {
994 return comparer_(selector_(a), selector_(b));
996 auto vals = source_ | as<VectorType>();
997 std::sort(vals.begin(), vals.end(), comparer);
998 return std::move(vals);
1002 Generator(Source source, Selector selector, Comparer comparer)
1003 : source_(std::move(source)),
1004 selector_(std::move(selector)),
1005 comparer_(std::move(comparer)) {}
1007 VectorType operator|(const Collect<VectorType>&) const {
1011 VectorType operator|(const CollectTemplate<std::vector>&) const {
1015 template <class Body>
1016 void foreach(Body&& body) const {
1017 for (auto& value : asVector()) {
1018 body(std::move(value));
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));
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()))) {
1040 // Can only be run on and produce finite generators
1041 static constexpr bool infinite = false;
1044 template <class Source,
1046 class Gen = Generator<Value, Source>>
1047 Gen compose(GenImpl<Value, Source>&& source) const {
1048 return Gen(std::move(source.self()), selector_, comparer_);
1051 template <class Source,
1053 class Gen = Generator<Value, Source>>
1054 Gen compose(const GenImpl<Value, Source>& source) const {
1055 return Gen(source.self(), selector_, comparer_);
1060 * GroupBy - Group values by a given key selector, producing a sequence of
1063 * This type is usually used through the 'groupBy' helper function, like:
1067 * | groupBy([](const Place& p) {
1070 * | [](Group<std::string, Place>&& g) {
1071 * cout << g.key() << ": " << (g | first).description;
1074 template <class Selector>
1075 class GroupBy : public Operator<GroupBy<Selector>> {
1081 explicit GroupBy(Selector selector) : selector_(std::move(selector)) {}
1083 template <class Value,
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>
1090 Group<KeyDecayed, ValueDecayed>&&,
1091 Generator<Value, Source, ValueDecayed, Key, KeyDecayed>> {
1092 static_assert(!Source::infinite, "Cannot group infinite source!");
1097 Generator(Source source, Selector selector)
1098 : source_(std::move(source)), selector_(std::move(selector)) {}
1100 typedef Group<KeyDecayed, ValueDecayed> GroupType;
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));
1110 for (auto& kg : groups) {
1111 GroupType group(kg.first, std::move(kg.second));
1112 if (!handler(std::move(group))) {
1120 // Can only be run on and produce finite generators
1121 static constexpr bool infinite = false;
1124 template <class Source,
1126 class Gen = Generator<Value, Source>>
1127 Gen compose(GenImpl<Value, Source>&& source) const {
1128 return Gen(std::move(source.self()), selector_);
1131 template <class Source,
1133 class Gen = Generator<Value, Source>>
1134 Gen compose(const GenImpl<Value, Source>& source) const {
1135 return Gen(source.self(), selector_);
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
1145 * auto c = from(vector) | assert_type<int&>() | sum;
1148 template <class Expected>
1149 class TypeAssertion : public Operator<TypeAssertion<Expected>> {
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();
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());
1167 * Distinct - For filtering duplicates out of a sequence. A selector may be
1168 * provided to generate a key to uniquify for each value.
1170 * This type is usually used through the 'distinct' helper function, like:
1172 * auto closest = from(results)
1173 * | distinctBy([](Item& i) {
1178 template <class Selector>
1179 class Distinct : public Operator<Distinct<Selector>> {
1183 Distinct() = default;
1185 explicit Distinct(Selector selector) : selector_(std::move(selector)) {}
1187 template <class Value, class Source>
1188 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1192 typedef typename std::decay<Value>::type StorageType;
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;
1198 typedef typename std::result_of<Selector(ParamType)>::type KeyType;
1199 typedef typename std::decay<KeyType>::type KeyStorageType;
1202 Generator(Source source, Selector selector)
1203 : source_(std::move(source)), selector_(std::move(selector)) {}
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));
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));
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;
1231 template <class Source,
1233 class Gen = Generator<Value, Source>>
1234 Gen compose(GenImpl<Value, Source>&& source) const {
1235 return Gen(std::move(source.self()), selector_);
1238 template <class Source,
1240 class Gen = Generator<Value, Source>>
1241 Gen compose(const GenImpl<Value, Source>& source) const {
1242 return Gen(source.self(), selector_);
1247 * Composer - Helper class for adapting pipelines into functors. Primarily used
1250 template <class Operators>
1255 explicit Composer(Operators op) : op_(std::move(op)) {}
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));
1266 * Batch - For producing fixed-size batches of each value from a source.
1268 * This type is usually used through the 'batch' helper function:
1273 * | map([](const std::vector<int>& batch) {
1274 * return from(batch) | sum;
1278 class Batch : public Operator<Batch> {
1282 explicit Batch(size_t batchSize) : batchSize_(batchSize) {
1283 if (batchSize_ == 0) {
1284 throw std::invalid_argument("Batch size must be non-zero!");
1288 template <class Value,
1290 class StorageType = typename std::decay<Value>::type,
1291 class VectorType = std::vector<StorageType>>
1293 : public GenImpl<VectorType&,
1294 Generator<Value, Source, StorageType, VectorType>> {
1299 explicit Generator(Source source, size_t batchSize)
1300 : source_(std::move(source)), batchSize_(batchSize) {}
1302 template <class Handler>
1303 bool apply(Handler&& handler) const {
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_);
1313 // Always need more if the handler is not called.
1316 // Flush everything, if and only if `handler` hasn't returned false.
1317 if (shouldContinue && !batch_.empty()) {
1318 shouldContinue = handler(batch_);
1321 return shouldContinue;
1324 // Taking n-tuples of an infinite source is still infinite
1325 static constexpr bool infinite = Source::infinite;
1328 template <class Source,
1330 class Gen = Generator<Value, Source>>
1331 Gen compose(GenImpl<Value, Source>&& source) const {
1332 return Gen(std::move(source.self()), batchSize_);
1335 template <class Source,
1337 class Gen = Generator<Value, Source>>
1338 Gen compose(const GenImpl<Value, Source>& source) const {
1339 return Gen(source.self(), batchSize_);
1344 * Concat - For flattening generators of generators.
1346 * This type is usually used through the 'concat' static value, like:
1350 * | map([](Node& x) {
1351 * return from(x.neighbors)
1352 * | map([&](Node& y) {
1353 * return Edge(x, y);
1359 class Concat : public Operator<Concat> {
1363 template <class Inner,
1365 class InnerValue = typename std::decay<Inner>::type::ValueType>
1367 : public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
1371 explicit Generator(Source source) : source_(std::move(source)) {}
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));
1380 template <class Body>
1381 void foreach(Body&& body) const {
1382 source_.foreach([&](Inner inner) {
1383 inner.foreach(std::forward<Body>(body));
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
1392 static constexpr bool infinite =
1393 Source::infinite || std::decay<Inner>::type::infinite;
1396 template <class Value,
1398 class Gen = Generator<Value, Source>>
1399 Gen compose(GenImpl<Value, Source>&& source) const {
1400 return Gen(std::move(source.self()));
1403 template <class Value,
1405 class Gen = Generator<Value, Source>>
1406 Gen compose(const GenImpl<Value, Source>& source) const {
1407 return Gen(source.self());
1412 * RangeConcat - For flattening generators of iterables.
1414 * This type is usually used through the 'rconcat' static value, like:
1416 * map<int, vector<int>> adjacency;
1423 class RangeConcat : public Operator<RangeConcat> {
1425 RangeConcat() = default;
1427 template <class Range,
1429 class InnerValue = typename ValueTypeOfRange<Range>::RefType>
1431 : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
1435 explicit Generator(Source source) : source_(std::move(source)) {}
1437 template <class Body>
1438 void foreach(Body&& body) const {
1439 source_.foreach([&](Range range) {
1440 for (auto& value : range) {
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)) {
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;
1463 template <class Value,
1465 class Gen = Generator<Value, Source>>
1466 Gen compose(GenImpl<Value, Source>&& source) const {
1467 return Gen(std::move(source.self()));
1470 template <class Value,
1472 class Gen = Generator<Value, Source>>
1473 Gen compose(const GenImpl<Value, Source>& source) const {
1474 return Gen(source.self());
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)'.
1487 * This type is used through the `guard` helper, like so:
1490 * = byLine(STDIN_FILENO)
1491 * | guard<std::runtime_error>([](std::runtime_error& e,
1493 * LOG(ERROR) << sp << ": " << e.str();
1494 * return true; // continue processing subsequent lines
1499 * TODO(tjackson): Rename this back to Guard.
1501 template <class Exception, class ErrorHandler>
1502 class GuardImpl : public Operator<GuardImpl<Exception, ErrorHandler>> {
1503 ErrorHandler handler_;
1506 explicit GuardImpl(ErrorHandler handler) : handler_(std::move(handler)) {}
1508 template <class Value, class Source>
1509 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1511 ErrorHandler handler_;
1514 explicit Generator(Source source, ErrorHandler handler)
1515 : source_(std::move(source)), handler_(std::move(handler)) {}
1517 template <class Handler>
1518 bool apply(Handler&& handler) const {
1519 return source_.apply([&](Value value) -> bool {
1521 handler(std::forward<Value>(value));
1523 } catch (Exception& e) {
1524 return handler_(e, std::forward<Value>(value));
1529 // Just passes value though, length unaffected
1530 static constexpr bool infinite = Source::infinite;
1533 template <class Value,
1535 class Gen = Generator<Value, Source>>
1536 Gen compose(GenImpl<Value, Source>&& source) const {
1537 return Gen(std::move(source.self()), handler_);
1540 template <class Value,
1542 class Gen = Generator<Value, Source>>
1543 Gen compose(const GenImpl<Value, Source>& source) const {
1544 return Gen(source.self(), handler_);
1549 * Dereference - For dereferencing a sequence of pointers while filtering out
1552 * This type is usually used through the 'dereference' static value, like:
1554 * auto refs = from(ptrs) | dereference;
1556 class Dereference : public Operator<Dereference> {
1558 Dereference() = default;
1560 template <class Value,
1562 class Result = decltype(*std::declval<Value>())>
1563 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1567 explicit Generator(Source source) : source_(std::move(source)) {}
1569 template <class Body>
1570 void foreach(Body&& body) const {
1571 source_.foreach([&](Value value) {
1573 return body(*std::forward<Value>(value));
1578 template <class Handler>
1579 bool apply(Handler&& handler) const {
1580 return source_.apply([&](Value value) -> bool {
1582 return handler(*std::forward<Value>(value));
1588 // Just passes value though, length unaffected
1589 static constexpr bool infinite = Source::infinite;
1592 template <class Source,
1594 class Gen = Generator<Value, Source>>
1595 Gen compose(GenImpl<Value, Source>&& source) const {
1596 return Gen(std::move(source.self()));
1599 template <class Source,
1601 class Gen = Generator<Value, Source>>
1602 Gen compose(const GenImpl<Value, Source>& source) const {
1603 return Gen(source.self());
1608 * Indirect - For producing a sequence of the addresses of the values in the
1611 * This type is usually used through the 'indirect' static value, like:
1613 * auto ptrs = from(refs) | indirect;
1615 class Indirect : public Operator<Indirect> {
1617 Indirect() = default;
1619 template <class Value,
1621 class Result = typename std::remove_reference<Value>::type*>
1622 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1624 static_assert(!std::is_rvalue_reference<Value>::value,
1625 "Cannot use indirect on an rvalue");
1628 explicit Generator(Source source) : source_(std::move(source)) {}
1630 template <class Body>
1631 void foreach(Body&& body) const {
1632 source_.foreach([&](Value value) {
1633 return body(&std::forward<Value>(value));
1637 template <class Handler>
1638 bool apply(Handler&& handler) const {
1639 return source_.apply([&](Value value) -> bool {
1640 return handler(&std::forward<Value>(value));
1644 // Just passes value though, length unaffected
1645 static constexpr bool infinite = Source::infinite;
1648 template <class Source,
1650 class Gen = Generator<Value, Source>>
1651 Gen compose(GenImpl<Value, Source>&& source) const {
1652 return Gen(std::move(source.self()));
1655 template <class Source,
1657 class Gen = Generator<Value, Source>>
1658 Gen compose(const GenImpl<Value, Source>& source) const {
1659 return Gen(source.self());
1664 * Cycle - For repeating a sequence forever.
1666 * This type is usually used through the 'cycle' static value, like:
1673 * or in the finite case:
1675 * auto thrice = g | cycle(3);
1677 template <bool forever>
1678 class Cycle : public Operator<Cycle<forever>> {
1679 off_t limit_; // not used if forever == true
1683 explicit Cycle(off_t limit) : limit_(limit) {
1686 "Cycle limit constructor should not be used when forever == true.");
1689 template <class Value, class Source>
1690 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1695 explicit Generator(Source source, off_t limit)
1696 : source_(std::move(source)), limit_(limit) {}
1698 template <class Handler>
1699 bool apply(Handler&& handler) const {
1701 auto handler2 = [&](Value value) {
1702 cont = handler(std::forward<Value>(value));
1705 // Becomes an infinte loop if forever == true
1706 for (off_t count = 0; (forever || count != limit_); ++count) {
1708 source_.apply(handler2);
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;
1725 template <class Source,
1727 class Gen = Generator<Value, Source>>
1728 Gen compose(GenImpl<Value, Source>&& source) const {
1729 return Gen(std::move(source.self()), limit_);
1732 template <class Source,
1734 class Gen = Generator<Value, Source>>
1735 Gen compose(const GenImpl<Value, Source>& source) const {
1736 return Gen(source.self(), limit_);
1740 * Convenience function for finite cycles used like:
1742 * auto tripled = gen | cycle(3);
1744 Cycle<false> operator()(off_t limit) const { return Cycle<false>(limit); }
1748 ******************************* Sinks *****************************************
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
1756 * This type is primarily used through the 'foldl' helper method, like:
1758 * double movingAverage = from(values)
1759 * | foldl(0.0, [](double avg, double sample) {
1760 * return sample * 0.1 + avg * 0.9;
1763 template <class Seed, class Fold>
1764 class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
1769 FoldLeft() = default;
1770 FoldLeft(Seed seed, Fold fold)
1771 : seed_(std::move(seed)), fold_(std::move(fold)) {}
1773 template <class Source, class Value>
1774 Seed compose(const GenImpl<Value, Source>& source) const {
1775 static_assert(!Source::infinite, "Cannot foldl infinite source");
1777 source | [&](Value v) {
1778 accum = fold_(std::move(accum), std::forward<Value>(v));
1785 * First - For finding the first value in a sequence.
1787 * This type is primarily used through the 'first' static value, like:
1789 * int firstThreeDigitPrime = seq(100) | filter(isPrime) | first;
1791 class First : public Operator<First> {
1795 template <class Source,
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);
1809 * IsEmpty - a helper class for isEmpty and notEmpty
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
1816 * Used primarily through 'isEmpty' and 'notEmpty' static values
1818 * bool hasPrimes = g | filter(prime) | notEmpty;
1819 * bool lacksEvens = g | filter(even) | isEmpty;
1821 * Also used in the implementation of 'any' and 'all'
1823 template <bool emptyResult>
1824 class IsEmpty : public Operator<IsEmpty<emptyResult>> {
1826 IsEmpty() = default;
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 "
1835 bool ans = emptyResult;
1837 [&](Value /* v */) -> bool {
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.
1850 * This type is primarily used through the 'reduce' helper method, like:
1852 * sring longest = from(names)
1853 * | reduce([](string&& best, string& current) {
1854 * return best.size() >= current.size() ? best : current;
1857 template <class Reducer>
1858 class Reduce : public Operator<Reduce<Reducer>> {
1863 explicit Reduce(Reducer reducer) : reducer_(std::move(reducer)) {}
1865 template <class Source,
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));
1875 accum = std::forward<Value>(v);
1883 * Count - for simply counting the items in a collection.
1885 * This type is usually used through its singleton, 'count':
1887 * auto shortPrimes = seq(1, 100) | filter(isPrime) | count;
1889 class Count : public Operator<Count> {
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; })
1903 * Sum - For simply summing up all the values from a source.
1905 * This type is usually used through its singleton, 'sum':
1907 * auto gaussSum = seq(1, 100) | sum;
1909 class Sum : public Operator<Sum> {
1913 template <class Source,
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);
1926 * Contains - For testing whether a value matching the given value is contained
1929 * This type should be used through the 'contains' helper method, like:
1931 * bool contained = seq(1, 10) | map(square) | contains(49);
1933 template <class Needle>
1934 class Contains : public Operator<Contains<Needle>> {
1938 explicit Contains(Needle needle) : needle_(std::move(needle)) {}
1940 template <class Source,
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));
1954 * Min - For a value which minimizes a key, where the key is determined by a
1955 * given selector, and compared by given comparer.
1957 * This type is usually used through the singletone 'min' or through the helper
1958 * functions 'minBy' and 'maxBy'.
1960 * auto oldest = from(people)
1961 * | minBy([](Person& p) {
1962 * return p.dateOfBirth;
1965 template <class Selector, class Comparer>
1966 class Min : public Operator<Min<Selector, Comparer>> {
1970 template <typename T>
1971 const T& asConst(const T& t) const {
1978 explicit Min(Selector selector) : selector_(std::move(selector)) {}
1980 Min(Selector selector, Comparer comparer)
1981 : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
1983 template <class Value,
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)) {
2001 minKey = std::move(key);
2002 min = std::forward<Value>(v);
2009 * Append - For collecting values from a source into a given output container
2012 * This type is usually used through the helper function 'appendTo', like:
2014 * vector<int64_t> ids;
2015 * from(results) | map([](Person& p) { return p.id })
2018 template <class Collection>
2019 class Append : public Operator<Append<Collection>> {
2020 Collection* collection_;
2023 explicit Append(Collection* collection) : collection_(collection) {}
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));
2031 return *collection_;
2036 * Collect - For collecting values from a source in a collection of the desired
2039 * This type is usually used through the helper function 'as', like:
2041 * std::string upper = from(stringPiece)
2043 * | as<std::string>();
2045 template <class Collection>
2046 class Collect : public Operator<Collect<Collection>> {
2048 Collect() = default;
2050 template <class Value,
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));
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>>
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.
2077 * set<string> uniqueNames = from(names) | as<set>();
2079 template <template <class, class> class Container,
2080 template <class> class Allocator>
2081 class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
2083 CollectTemplate() = default;
2085 template <class Value,
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));
2101 * UnwrapOr - For unwrapping folly::Optional values, or providing the given
2102 * fallback value. Usually used through the 'unwrapOr' helper like so:
2104 * auto best = from(scores) | max | unwrapOr(-1);
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
2114 explicit UnwrapOr(T&& value) : value_(std::move(value)) {}
2115 explicit UnwrapOr(const T& value) : value_(value) {}
2117 T& value() { return value_; }
2118 const T& value() const { return value_; }
2125 T&& operator|(Optional<T>&& opt, UnwrapOr<T>&& fallback) {
2126 if (T* p = opt.get_pointer()) {
2127 return std::move(*p);
2129 return std::move(fallback.value());
2133 T& operator|(Optional<T>& opt, UnwrapOr<T>& fallback) {
2134 if (T* p = opt.get_pointer()) {
2137 return fallback.value();
2141 const T& operator|(const Optional<T>& opt, const UnwrapOr<T>& fallback) {
2142 if (const T* p = opt.get_pointer()) {
2145 return fallback.value();
2148 // Mixed type unwrapping always returns values, moving where possible
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);
2158 return std::move(fallback.value());
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()) {
2170 return std::move(fallback.value());
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);
2182 return fallback.value();
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()) {
2194 return fallback.value();
2198 * Unwrap - For unwrapping folly::Optional values in a folly::gen style. Usually
2199 * used through the 'unwrap' instace like so:
2201 * auto best = from(scores) | max | unwrap; // may throw
2206 T&& operator|(Optional<T>&& opt, const Unwrap&) {
2207 return std::move(opt.value());
2211 T& operator|(Optional<T>& opt, const Unwrap&) {
2216 const T& operator|(const Optional<T>& opt, const Unwrap&) {
2223 * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
2225 template <class Value>
2226 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
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;
2235 template <class Wrapped>
2236 class WrapperImpl : public WrapperBase {
2240 explicit WrapperImpl(Wrapped wrapped) : wrapped_(std::move(wrapped)) {}
2242 bool apply(const std::function<bool(Value)>& handler) const override {
2243 return wrapped_.apply(handler);
2246 void foreach(const std::function<void(Value)>& body) const override {
2247 wrapped_.foreach(body);
2250 std::unique_ptr<const WrapperBase> clone() const override {
2251 return std::unique_ptr<const WrapperBase>(new WrapperImpl(wrapped_));
2255 std::unique_ptr<const WrapperBase> wrapper_;
2258 template <class Self>
2259 /* implicit */ VirtualGen(Self source)
2260 : wrapper_(new WrapperImpl<Self>(std::move(source))) {}
2262 VirtualGen(VirtualGen&& source) noexcept
2263 : wrapper_(std::move(source.wrapper_)) {}
2265 VirtualGen(const VirtualGen& source) : wrapper_(source.wrapper_->clone()) {}
2267 VirtualGen& operator=(const VirtualGen& source) {
2268 wrapper_.reset(source.wrapper_->clone());
2272 VirtualGen& operator=(VirtualGen&& source) noexcept {
2273 wrapper_ = std::move(source.wrapper_);
2277 bool apply(const std::function<bool(Value)>& handler) const {
2278 return wrapper_->apply(handler);
2281 void foreach(const std::function<void(Value)>& body) const {
2282 wrapper_->foreach(body);
2287 * non-template operators, statically defined to avoid the need for anything but
2290 constexpr detail::Sum sum{};
2292 constexpr detail::Count count{};
2294 constexpr detail::First first{};
2296 constexpr detail::IsEmpty<true> isEmpty{};
2298 constexpr detail::IsEmpty<false> notEmpty{};
2300 constexpr detail::Min<Identity, Less> min{};
2302 constexpr detail::Min<Identity, Greater> max{};
2304 constexpr detail::Order<Identity> order{};
2306 constexpr detail::Distinct<Identity> distinct{};
2308 constexpr detail::Map<Move> move{};
2310 constexpr detail::Concat concat{};
2312 constexpr detail::RangeConcat rconcat{};
2314 constexpr detail::Cycle<true> cycle{};
2316 constexpr detail::Dereference dereference{};
2318 constexpr detail::Indirect indirect{};
2320 constexpr detail::Unwrap unwrap{};
2322 template <class Number>
2323 inline detail::Take take(Number count) {
2325 throw std::invalid_argument("Negative value passed to take()");
2327 return detail::Take(static_cast<size_t>(count));
2330 inline detail::Stride stride(size_t s) { return detail::Stride(s); }
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));
2337 inline detail::Skip skip(size_t count) { return detail::Skip(count); }
2339 inline detail::Batch batch(size_t batchSize) {
2340 return detail::Batch(batchSize);