2 * Copyright 2015 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 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
22 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wshadow"
25 namespace folly { namespace gen {
28 * ArgumentReference - For determining ideal argument type to receive a value.
31 struct ArgumentReference
32 : public std::conditional<
33 std::is_reference<T>::value,
34 T, // T& -> T&, T&& -> T&&, const T& -> const T&
35 typename std::conditional<std::is_const<T>::value,
36 T&, // const int -> const int&
41 * Group - The output objects from the GroupBy operator
43 template <class Key, class Value>
44 class Group : public GenImpl<Value&&, Group<Key, Value>> {
46 static_assert(!std::is_reference<Key>::value &&
47 !std::is_reference<Value>::value,
48 "Key and Value must be decayed types");
50 typedef std::vector<Value> VectorType;
52 typedef Value ValueType;
54 Group(Key key, VectorType values)
55 : key_(std::move(key)), values_(std::move(values)) {}
57 const Key& key() const { return key_; }
59 size_t size() const { return values_.size(); }
60 const VectorType& values() const { return values_; }
61 VectorType& values() { return values_; }
63 VectorType operator|(const detail::Collect<VectorType>&) const {
67 VectorType operator|(const detail::CollectTemplate<std::vector>&) const {
72 void foreach(Body&& body) const {
73 for (auto& value : values_) {
74 body(std::move(value));
78 template <class Handler>
79 bool apply(Handler&& handler) const {
80 for (auto& value : values_) {
81 if (!handler(std::move(value))) {
88 // GroupBy only takes in finite generators, so we only have finite groups
89 static constexpr bool infinite = false;
93 mutable VectorType values_;
98 // Classes used for the implementation of Sources, Operators, and Sinks
101 ******************************* Sources ***************************************
105 * ReferencedSource - Generate values from an STL-like container using
106 * iterators from .begin() until .end(). Value type defaults to the type of
107 * *container->begin(). For std::vector<int>, this would be int&. Note that the
108 * value here is a reference, so the values in the vector will be passed by
109 * reference to downstream operators.
111 * This type is primarily used through the 'from' helper method, like:
113 * string& longestName = from(names)
114 * | maxBy([](string& s) { return s.size() });
116 template <class Container, class Value>
117 class ReferencedSource
118 : public GenImpl<Value, ReferencedSource<Container, Value>> {
119 Container* container_;
122 explicit ReferencedSource(Container* container) : container_(container) {}
124 template <class Body>
125 void foreach(Body&& body) const {
126 for (auto& value : *container_) {
127 body(std::forward<Value>(value));
131 template <class Handler>
132 bool apply(Handler&& handler) const {
133 for (auto& value : *container_) {
134 if (!handler(std::forward<Value>(value))) {
141 // from takes in a normal stl structure, which are all finite
142 static constexpr bool infinite = false;
146 * CopiedSource - For producing values from eagerly from a sequence of values
147 * whose storage is owned by this class. Useful for preparing a generator for
148 * use after a source collection will no longer be available, or for when the
149 * values are specified literally with an initializer list.
151 * This type is primarily used through the 'fromCopy' function, like:
153 * auto sourceCopy = fromCopy(makeAVector());
154 * auto sum = sourceCopy | sum;
155 * auto max = sourceCopy | max;
157 * Though it is also used for the initializer_list specialization of from().
159 template <class StorageType, class Container>
161 : public GenImpl<const StorageType&, CopiedSource<StorageType, Container>> {
162 static_assert(!std::is_reference<StorageType>::value,
163 "StorageType must be decayed");
166 // Generator objects are often copied during normal construction as they are
167 // encapsulated by downstream generators. It would be bad if this caused
168 // a copy of the entire container each time, and since we're only exposing a
169 // const reference to the value, it's safe to share it between multiple
171 static_assert(!std::is_reference<Container>::value,
172 "Can't copy into a reference");
173 std::shared_ptr<const Container> copy_;
176 typedef Container ContainerType;
178 template <class SourceContainer>
179 explicit CopiedSource(const SourceContainer& container)
180 : copy_(new Container(begin(container), end(container))) {}
182 explicit CopiedSource(Container&& container)
183 : copy_(new Container(std::move(container))) {}
185 // To enable re-use of cached results.
186 CopiedSource(const CopiedSource<StorageType, Container>& source)
187 : copy_(source.copy_) {}
189 template <class Body>
190 void foreach(Body&& body) const {
191 for (const auto& value : *copy_) {
196 template <class Handler>
197 bool apply(Handler&& handler) const {
198 // The collection may be reused by others, we can't allow it to be changed.
199 for (const auto& value : *copy_) {
200 if (!handler(value)) {
207 // from takes in a normal stl structure, which are all finite
208 static constexpr bool infinite = false;
212 * RangeSource - For producing values from a folly::Range. Useful for referring
213 * to a slice of some container.
215 * This type is primarily used through the 'from' function, like:
217 * auto rangeSource = from(folly::range(v.begin(), v.end()));
218 * auto sum = rangeSource | sum;
220 * Reminder: Be careful not to invalidate iterators when using ranges like this.
222 template <class Iterator>
223 class RangeSource : public GenImpl<typename Range<Iterator>::reference,
224 RangeSource<Iterator>> {
225 Range<Iterator> range_;
228 RangeSource() = default;
229 explicit RangeSource(Range<Iterator> range) : range_(std::move(range)) {}
231 template <class Handler>
232 bool apply(Handler&& handler) const {
233 for (auto& value : range_) {
234 if (!handler(value)) {
241 template <class Body>
242 void foreach(Body&& body) const {
243 for (auto& value : range_) {
248 // folly::Range only supports finite ranges
249 static constexpr bool infinite = false;
253 * Sequence - For generating values from beginning value, incremented along the
254 * way with the ++ and += operators. Iteration may continue indefinitely.
255 * Value type specified explicitly.
257 * This type is primarily used through the 'seq' and 'range' function, like:
259 * int total = seq(1, 10) | sum;
260 * auto indexes = range(0, 10);
261 * auto endless = seq(0); // 0, 1, 2, 3, ...
263 template <class Value, class SequenceImpl>
264 class Sequence : public GenImpl<const Value&, Sequence<Value, SequenceImpl>> {
265 static_assert(!std::is_reference<Value>::value &&
266 !std::is_const<Value>::value,
267 "Value mustn't be const or ref.");
272 explicit Sequence(Value start, SequenceImpl impl)
273 : start_(std::move(start)), impl_(std::move(impl)) {}
275 template <class Handler>
276 bool apply(Handler&& handler) const {
277 for (Value current = start_; impl_.test(current); impl_.step(current)) {
278 if (!handler(current)) {
285 template <class Body>
286 void foreach(Body&& body) const {
287 for (Value current = start_; impl_.test(current); impl_.step(current)) {
292 // Let the implementation say if we are infinite or not
293 static constexpr bool infinite = SequenceImpl::infinite;
297 * Sequence implementations (range, sequence, infinite, with/without step)
299 template <class Value>
304 explicit RangeImpl(Value end) : end_(std::move(end)) {}
305 bool test(const Value& current) const { return current < end_; }
306 void step(Value& current) const { ++current; }
307 static constexpr bool infinite = false;
310 template <class Value, class Distance>
311 class RangeWithStepImpl {
316 explicit RangeWithStepImpl(Value end, Distance step)
317 : end_(std::move(end)), step_(std::move(step)) {}
318 bool test(const Value& current) const { return current < end_; }
319 void step(Value& current) const { current += step_; }
320 static constexpr bool infinite = false;
323 template <class Value>
328 explicit SeqImpl(Value end) : end_(std::move(end)) {}
329 bool test(const Value& current) const { return current <= end_; }
330 void step(Value& current) const { ++current; }
331 static constexpr bool infinite = false;
334 template <class Value, class Distance>
335 class SeqWithStepImpl {
340 explicit SeqWithStepImpl(Value end, Distance step)
341 : end_(std::move(end)), step_(std::move(step)) {}
342 bool test(const Value& current) const { return current <= end_; }
343 void step(Value& current) const { current += step_; }
344 static constexpr bool infinite = false;
347 template <class Value>
350 bool test(const Value& current) const { return true; }
351 void step(Value& current) const { ++current; }
352 static constexpr bool infinite = true;
356 * GenratorBuilder - Helper for GENERTATOR macro.
358 template <class Value>
359 struct GeneratorBuilder {
360 template <class Source,
361 class Yield = detail::Yield<Value, Source>>
362 Yield operator+(Source&& source) {
363 return Yield(std::forward<Source>(source));
368 * Yield - For producing values from a user-defined generator by way of a
371 template <class Value, class Source>
372 class Yield : public GenImpl<Value, Yield<Value, Source>> {
376 explicit Yield(Source source) : source_(std::move(source)) {}
378 template <class Handler>
379 bool apply(Handler&& handler) const {
381 auto body = [&](Value value) {
382 if (!handler(std::forward<Value>(value))) {
394 template <class Body>
395 void foreach(Body&& body) const {
396 source_(std::forward<Body>(body));
400 template <class Value>
401 class Empty : public GenImpl<Value, Empty<Value>> {
403 template <class Handler>
404 bool apply(Handler&&) const {
408 template <class Body>
409 void foreach(Body&&) const {}
411 // No values, so finite
412 static constexpr bool infinite = false;
415 template <class Value>
416 class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
417 static_assert(!std::is_reference<Value>::value,
418 "SingleReference requires non-ref types");
422 explicit SingleReference(Value& ref) : ptr_(&ref) {}
424 template <class Handler>
425 bool apply(Handler&& handler) const {
426 return handler(*ptr_);
429 template <class Body>
430 void foreach(Body&& body) const {
434 // One value, so finite
435 static constexpr bool infinite = false;
438 template <class Value>
439 class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
440 static_assert(!std::is_reference<Value>::value,
441 "SingleCopy requires non-ref types");
445 explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
447 template <class Handler>
448 bool apply(Handler&& handler) const {
449 return handler(value_);
452 template <class Body>
453 void foreach(Body&& body) const {
457 // One value, so finite
458 static constexpr bool infinite = false;
462 ***************************** Operators ***************************************
466 * Map - For producing a sequence of values by passing each value from a source
467 * collection through a predicate.
469 * This type is usually used through the 'map' or 'mapped' helper function:
471 * auto squares = seq(1, 10) | map(square) | asVector;
473 template <class Predicate>
474 class Map : public Operator<Map<Predicate>> {
480 explicit Map(Predicate pred) : pred_(std::move(pred)) {}
482 template <class Value,
484 class Result = typename ArgumentReference<
485 typename std::result_of<Predicate(Value)>::type>::type>
486 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
491 explicit Generator(Source source, const Predicate& pred)
492 : source_(std::move(source)), pred_(pred) {}
494 template <class Body>
495 void foreach(Body&& body) const {
497 [&](Value value) { body(pred_(std::forward<Value>(value))); });
500 template <class Handler>
501 bool apply(Handler&& handler) const {
502 return source_.apply([&](Value value) {
503 return handler(pred_(std::forward<Value>(value)));
507 static constexpr bool infinite = Source::infinite;
510 template <class Source,
512 class Gen = Generator<Value, Source>>
513 Gen compose(GenImpl<Value, Source>&& source) const {
514 return Gen(std::move(source.self()), pred_);
517 template <class Source,
519 class Gen = Generator<Value, Source>>
520 Gen compose(const GenImpl<Value, Source>& source) const {
521 return Gen(source.self(), pred_);
526 * Filter - For filtering values from a source sequence by a predicate.
528 * This type is usually used through the 'filter' helper function, like:
530 * auto nonEmpty = from(strings)
531 * | filter([](const string& str) -> bool {
532 * return !str.empty();
535 * Note that if no predicate is provided, the values are casted to bool and
536 * filtered based on that. So if pointers is a vector of pointers,
538 * auto nonNull = from(pointers) | filter();
540 * will give a vector of all the pointers != nullptr.
542 template <class Predicate>
543 class Filter : public Operator<Filter<Predicate>> {
548 explicit Filter(Predicate pred) : pred_(std::move(pred)) {}
550 template <class Value, class Source>
551 class Generator : public GenImpl<Value, Generator<Value, Source>> {
556 explicit Generator(Source source, const Predicate& pred)
557 : source_(std::move(source)), pred_(pred) {}
559 template <class Body>
560 void foreach(Body&& body) const {
561 source_.foreach([&](Value value) {
562 if (pred_(std::forward<Value>(value))) {
563 body(std::forward<Value>(value));
568 template <class Handler>
569 bool apply(Handler&& handler) const {
570 return source_.apply([&](Value value) -> bool {
571 if (pred_(std::forward<Value>(value))) {
572 return handler(std::forward<Value>(value));
578 static constexpr bool infinite = Source::infinite;
581 template <class Source,
583 class Gen = Generator<Value, Source>>
584 Gen compose(GenImpl<Value, Source>&& source) const {
585 return Gen(std::move(source.self()), pred_);
588 template <class Source,
590 class Gen = Generator<Value, Source>>
591 Gen compose(const GenImpl<Value, Source>& source) const {
592 return Gen(source.self(), pred_);
597 * Until - For producing values from a source until a predicate is satisfied.
599 * This type is usually used through the 'until' helper function, like:
601 * auto best = from(sortedItems)
602 * | until([](Item& item) { return item.score > 100; })
605 template <class Predicate>
606 class Until : public Operator<Until<Predicate>> {
611 explicit Until(Predicate pred) : pred_(std::move(pred)) {}
613 template <class Value, class Source>
614 class Generator : public GenImpl<Value, Generator<Value, Source>> {
619 explicit Generator(Source source, const Predicate& pred)
620 : source_(std::move(source)), pred_(pred) {}
622 template <class Handler>
623 bool apply(Handler&& handler) const {
624 bool cancelled = false;
625 source_.apply([&](Value value) -> bool {
626 if (pred_(value)) { // un-forwarded to disable move
629 if (!handler(std::forward<Value>(value))) {
638 // Theoretically an 'until' might stop an infinite
639 static constexpr bool infinite = false;
642 template <class Source,
644 class Gen = Generator<Value, Source>>
645 Gen compose(GenImpl<Value, Source>&& source) const {
646 return Gen(std::move(source.self()), pred_);
649 template <class Source,
651 class Gen = Generator<Value, Source>>
652 Gen compose(const GenImpl<Value, Source>& source) const {
653 return Gen(source.self(), pred_);
658 * Take - For producing up to N values from a source.
660 * This type is usually used through the 'take' helper function, like:
662 * auto best = from(docs)
663 * | orderByDescending(scoreDoc)
666 class Take : public Operator<Take> {
670 explicit Take(size_t count) : count_(count) {}
672 template <class Value, class Source>
673 class Generator : public GenImpl<Value, Generator<Value, Source>> {
678 explicit Generator(Source source, size_t count)
679 : source_(std::move(source)), count_(count) {}
681 template <class Handler>
682 bool apply(Handler&& handler) const {
687 bool cancelled = false;
688 source_.apply([&](Value value) -> bool {
689 if (!handler(std::forward<Value>(value))) {
698 // take will stop an infinite generator
699 static constexpr bool infinite = false;
702 template <class Source,
704 class Gen = Generator<Value, Source>>
705 Gen compose(GenImpl<Value, Source>&& source) const {
706 return Gen(std::move(source.self()), count_);
709 template <class Source,
711 class Gen = Generator<Value, Source>>
712 Gen compose(const GenImpl<Value, Source>& source) const {
713 return Gen(source.self(), count_);
718 * Stride - For producing every Nth value from a source.
720 * This type is usually used through the 'stride' helper function, like:
722 * auto half = from(samples)
725 class Stride : public Operator<Stride> {
729 explicit Stride(size_t stride) : stride_(stride) {
731 throw std::invalid_argument("stride must not be 0");
735 template <class Value, class Source>
736 class Generator : public GenImpl<Value, Generator<Value, Source>> {
741 explicit Generator(Source source, size_t stride)
742 : source_(std::move(source)), stride_(stride) {}
744 template <class Handler>
745 bool apply(Handler&& handler) const {
746 size_t distance = stride_;
747 return source_.apply([&](Value value) -> bool {
748 if (++distance >= stride_) {
749 if (!handler(std::forward<Value>(value))) {
758 template <class Body>
759 void foreach(Body&& body) const {
760 size_t distance = stride_;
761 source_.foreach([&](Value value) {
762 if (++distance >= stride_) {
763 body(std::forward<Value>(value));
769 // Taking every Nth of an infinite list is still infinte
770 static constexpr bool infinite = Source::infinite;
773 template <class Source,
775 class Gen = Generator<Value, Source>>
776 Gen compose(GenImpl<Value, Source>&& source) const {
777 return Gen(std::move(source.self()), stride_);
780 template <class Source,
782 class Gen = Generator<Value, Source>>
783 Gen compose(const GenImpl<Value, Source>& source) const {
784 return Gen(source.self(), stride_);
789 * Sample - For taking a random sample of N elements from a sequence
790 * (without replacement).
792 template <class Random>
793 class Sample : public Operator<Sample<Random>> {
798 explicit Sample(size_t count, Random rng)
799 : count_(count), rng_(std::move(rng)) {}
801 template <class Value,
804 class StorageType = typename std::decay<Value>::type>
806 : public GenImpl<StorageType&&,
807 Generator<Value, Source, Rand, StorageType>> {
808 static_assert(!Source::infinite, "Cannot sample infinite source!");
809 // It's too easy to bite ourselves if random generator is only 16-bit
810 static_assert(Random::max() >= std::numeric_limits<int32_t>::max() - 1,
811 "Random number generator must support big values");
817 explicit Generator(Source source, size_t count, Random rng)
818 : source_(std::move(source)), count_(count), rng_(std::move(rng)) {}
820 template <class Handler>
821 bool apply(Handler&& handler) const {
825 std::vector<StorageType> v;
827 // use reservoir sampling to give each source value an equal chance
828 // of appearing in our output.
830 source_.foreach([&](Value value) -> void {
831 if (v.size() < count_) {
832 v.push_back(std::forward<Value>(value));
834 // alternatively, we could create a std::uniform_int_distribution
835 // instead of using modulus, but benchmarks show this has
836 // substantial overhead.
837 size_t index = rng_() % n;
838 if (index < v.size()) {
839 v[index] = std::forward<Value>(value);
845 // output is unsorted!
846 for (auto& val : v) {
847 if (!handler(std::move(val))) {
854 // Only takes N elements, so finite
855 static constexpr bool infinite = false;
858 template <class Source,
860 class Gen = Generator<Value, Source, Random>>
861 Gen compose(GenImpl<Value, Source>&& source) const {
862 return Gen(std::move(source.self()), count_, rng_);
865 template <class Source,
867 class Gen = Generator<Value, Source, Random>>
868 Gen compose(const GenImpl<Value, Source>& source) const {
869 return Gen(source.self(), count_, rng_);
874 * Skip - For skipping N items from the beginning of a source generator.
876 * This type is usually used through the 'skip' helper function, like:
878 * auto page = from(results)
879 * | skip(pageSize * startPage)
882 class Skip : public Operator<Skip> {
886 explicit Skip(size_t count) : count_(count) {}
888 template <class Value, class Source>
889 class Generator : public GenImpl<Value, Generator<Value, Source>> {
894 explicit Generator(Source source, size_t count)
895 : source_(std::move(source)), count_(count) {}
897 template <class Body>
898 void foreach(Body&& body) const {
900 source_.foreach(body);
904 source_.foreach([&](Value value) {
908 body(std::forward<Value>(value));
913 template <class Handler>
914 bool apply(Handler&& handler) const {
916 return source_.apply(std::forward<Handler>(handler));
919 return source_.apply([&](Value value) -> bool {
924 return handler(std::forward<Value>(value));
928 // Skipping N items of an infinite source is still infinite
929 static constexpr bool infinite = Source::infinite;
932 template <class Source,
934 class Gen = Generator<Value, Source>>
935 Gen compose(GenImpl<Value, Source>&& source) const {
936 return Gen(std::move(source.self()), count_);
939 template <class Source,
941 class Gen = Generator<Value, Source>>
942 Gen compose(const GenImpl<Value, Source>& source) const {
943 return Gen(source.self(), count_);
948 * Order - For ordering a sequence of values from a source by key.
949 * The key is extracted by the given selector functor, and this key is then
950 * compared using the specified comparator.
952 * This type is usually used through the 'order' helper function, like:
954 * auto closest = from(places)
955 * | orderBy([](Place& p) {
956 * return -distance(p.location, here);
960 template <class Selector, class Comparer>
961 class Order : public Operator<Order<Selector, Comparer>> {
968 explicit Order(Selector selector) : selector_(std::move(selector)) {}
970 Order(Selector selector, Comparer comparer)
971 : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
973 template <class Value,
975 class StorageType = typename std::decay<Value>::type,
976 class Result = typename std::result_of<Selector(Value)>::type>
978 : public GenImpl<StorageType&&,
979 Generator<Value, Source, StorageType, Result>> {
980 static_assert(!Source::infinite, "Cannot sort infinite source!");
985 typedef std::vector<StorageType> VectorType;
987 VectorType asVector() const {
988 auto comparer = [&](const StorageType& a, const StorageType& b) {
989 return comparer_(selector_(a), selector_(b));
991 auto vals = source_ | as<VectorType>();
992 std::sort(vals.begin(), vals.end(), comparer);
993 return std::move(vals);
997 Generator(Source source, Selector selector, Comparer comparer)
998 : source_(std::move(source)),
999 selector_(std::move(selector)),
1000 comparer_(std::move(comparer)) {}
1002 VectorType operator|(const Collect<VectorType>&) const {
1006 VectorType operator|(const CollectTemplate<std::vector>&) const {
1010 template <class Body>
1011 void foreach(Body&& body) const {
1012 for (auto& value : asVector()) {
1013 body(std::move(value));
1017 template <class Handler>
1018 bool apply(Handler&& handler) const {
1019 auto comparer = [&](const StorageType& a, const StorageType& b) {
1020 // swapped for minHeap
1021 return comparer_(selector_(b), selector_(a));
1023 auto heap = source_ | as<VectorType>();
1024 std::make_heap(heap.begin(), heap.end(), comparer);
1025 while (!heap.empty()) {
1026 std::pop_heap(heap.begin(), heap.end(), comparer);
1027 if (!handler(std::move(heap.back()))) {
1035 // Can only be run on and produce finite generators
1036 static constexpr bool infinite = false;
1039 template <class Source,
1041 class Gen = Generator<Value, Source>>
1042 Gen compose(GenImpl<Value, Source>&& source) const {
1043 return Gen(std::move(source.self()), selector_, comparer_);
1046 template <class Source,
1048 class Gen = Generator<Value, Source>>
1049 Gen compose(const GenImpl<Value, Source>& source) const {
1050 return Gen(source.self(), selector_, comparer_);
1055 * GroupBy - Group values by a given key selector, producing a sequence of
1058 * This type is usually used through the 'groupBy' helper function, like:
1062 * | groupBy([](const Place& p) {
1065 * | [](Group<std::string, Place>&& g) {
1066 * cout << g.key() << ": " << (g | first).description;
1069 template <class Selector>
1070 class GroupBy : public Operator<GroupBy<Selector>> {
1076 explicit GroupBy(Selector selector) : selector_(std::move(selector)) {}
1078 template <class Value,
1080 class ValueDecayed = typename std::decay<Value>::type,
1081 class Key = typename std::result_of<Selector(Value)>::type,
1082 class KeyDecayed = typename std::decay<Key>::type>
1085 Group<KeyDecayed, ValueDecayed>&&,
1086 Generator<Value, Source, ValueDecayed, Key, KeyDecayed>> {
1087 static_assert(!Source::infinite, "Cannot group infinite source!");
1092 Generator(Source source, Selector selector)
1093 : source_(std::move(source)), selector_(std::move(selector)) {}
1095 typedef Group<KeyDecayed, ValueDecayed> GroupType;
1097 template <class Handler>
1098 bool apply(Handler&& handler) const {
1099 std::unordered_map<KeyDecayed, typename GroupType::VectorType> groups;
1100 source_ | [&](Value value) {
1101 const Value& cv = value;
1102 auto& group = groups[selector_(cv)];
1103 group.push_back(std::forward<Value>(value));
1105 for (auto& kg : groups) {
1106 GroupType group(kg.first, std::move(kg.second));
1107 if (!handler(std::move(group))) {
1115 // Can only be run on and produce finite generators
1116 static constexpr bool infinite = false;
1119 template <class Source,
1121 class Gen = Generator<Value, Source>>
1122 Gen compose(GenImpl<Value, Source>&& source) const {
1123 return Gen(std::move(source.self()), selector_);
1126 template <class Source,
1128 class Gen = Generator<Value, Source>>
1129 Gen compose(const GenImpl<Value, Source>& source) const {
1130 return Gen(source.self(), selector_);
1135 * TypeAssertion - For verifying the exact type of the value produced by a
1136 * generator. Useful for testing and debugging, and acts as a no-op at runtime.
1137 * Pass-through at runtime. Used through the 'assert_type<>()' factory method
1140 * auto c = from(vector) | assert_type<int&>() | sum;
1143 template <class Expected>
1144 class TypeAssertion : public Operator<TypeAssertion<Expected>> {
1146 template <class Source, class Value>
1147 const Source& compose(const GenImpl<Value, Source>& source) const {
1148 static_assert(std::is_same<Expected, Value>::value,
1149 "assert_type() check failed");
1150 return source.self();
1153 template <class Source, class Value>
1154 Source&& compose(GenImpl<Value, Source>&& source) const {
1155 static_assert(std::is_same<Expected, Value>::value,
1156 "assert_type() check failed");
1157 return std::move(source.self());
1162 * Distinct - For filtering duplicates out of a sequence. A selector may be
1163 * provided to generate a key to uniquify for each value.
1165 * This type is usually used through the 'distinct' helper function, like:
1167 * auto closest = from(results)
1168 * | distinctBy([](Item& i) {
1173 template <class Selector>
1174 class Distinct : public Operator<Distinct<Selector>> {
1178 Distinct() = default;
1180 explicit Distinct(Selector selector) : selector_(std::move(selector)) {}
1182 template <class Value, class Source>
1183 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1187 typedef typename std::decay<Value>::type StorageType;
1189 // selector_ cannot be passed an rvalue or it would end up passing the husk
1190 // of a value to the downstream operators.
1191 typedef const StorageType& ParamType;
1193 typedef typename std::result_of<Selector(ParamType)>::type KeyType;
1194 typedef typename std::decay<KeyType>::type KeyStorageType;
1197 Generator(Source source, Selector selector)
1198 : source_(std::move(source)), selector_(std::move(selector)) {}
1200 template <class Body>
1201 void foreach(Body&& body) const {
1202 std::unordered_set<KeyStorageType> keysSeen;
1203 source_.foreach([&](Value value) {
1204 if (keysSeen.insert(selector_(ParamType(value))).second) {
1205 body(std::forward<Value>(value));
1210 template <class Handler>
1211 bool apply(Handler&& handler) const {
1212 std::unordered_set<KeyStorageType> keysSeen;
1213 return source_.apply([&](Value value) -> bool {
1214 if (keysSeen.insert(selector_(ParamType(value))).second) {
1215 return handler(std::forward<Value>(value));
1221 // While running distinct on an infinite sequence might produce a
1222 // conceptually finite sequence, it will take infinite time
1223 static constexpr bool infinite = Source::infinite;
1226 template <class Source,
1228 class Gen = Generator<Value, Source>>
1229 Gen compose(GenImpl<Value, Source>&& source) const {
1230 return Gen(std::move(source.self()), selector_);
1233 template <class Source,
1235 class Gen = Generator<Value, Source>>
1236 Gen compose(const GenImpl<Value, Source>& source) const {
1237 return Gen(source.self(), selector_);
1242 * Composer - Helper class for adapting pipelines into functors. Primarily used
1245 template <class Operators>
1250 explicit Composer(Operators op) : op_(std::move(op)) {}
1252 template <class Source,
1253 class Ret = decltype(
1254 std::declval<Operators>().compose(std::declval<Source>()))>
1255 Ret operator()(Source&& source) const {
1256 return op_.compose(std::forward<Source>(source));
1261 * Batch - For producing fixed-size batches of each value from a source.
1263 * This type is usually used through the 'batch' helper function:
1268 * | map([](const std::vector<int>& batch) {
1269 * return from(batch) | sum;
1273 class Batch : public Operator<Batch> {
1277 explicit Batch(size_t batchSize) : batchSize_(batchSize) {
1278 if (batchSize_ == 0) {
1279 throw std::invalid_argument("Batch size must be non-zero!");
1283 template <class Value,
1285 class StorageType = typename std::decay<Value>::type,
1286 class VectorType = std::vector<StorageType>>
1288 : public GenImpl<VectorType&,
1289 Generator<Value, Source, StorageType, VectorType>> {
1294 explicit Generator(Source source, size_t batchSize)
1295 : source_(std::move(source)), batchSize_(batchSize) {}
1297 template <class Handler>
1298 bool apply(Handler&& handler) const {
1300 batch_.reserve(batchSize_);
1301 bool shouldContinue = source_.apply([&](Value value) -> bool {
1302 batch_.push_back(std::forward<Value>(value));
1303 if (batch_.size() == batchSize_) {
1304 bool needMore = handler(batch_);
1308 // Always need more if the handler is not called.
1311 // Flush everything, if and only if `handler` hasn't returned false.
1312 if (shouldContinue && !batch_.empty()) {
1313 shouldContinue = handler(batch_);
1316 return shouldContinue;
1319 // Taking n-tuples of an infinite source is still infinite
1320 static constexpr bool infinite = Source::infinite;
1323 template <class Source,
1325 class Gen = Generator<Value, Source>>
1326 Gen compose(GenImpl<Value, Source>&& source) const {
1327 return Gen(std::move(source.self()), batchSize_);
1330 template <class Source,
1332 class Gen = Generator<Value, Source>>
1333 Gen compose(const GenImpl<Value, Source>& source) const {
1334 return Gen(source.self(), batchSize_);
1339 * Concat - For flattening generators of generators.
1341 * This type is usually used through the 'concat' static value, like:
1345 * | map([](Node& x) {
1346 * return from(x.neighbors)
1347 * | map([&](Node& y) {
1348 * return Edge(x, y);
1354 class Concat : public Operator<Concat> {
1358 template <class Inner,
1360 class InnerValue = typename std::decay<Inner>::type::ValueType>
1362 : public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
1366 explicit Generator(Source source) : source_(std::move(source)) {}
1368 template <class Handler>
1369 bool apply(Handler&& handler) const {
1370 return source_.apply([&](Inner inner) -> bool {
1371 return inner.apply(std::forward<Handler>(handler));
1375 template <class Body>
1376 void foreach(Body&& body) const {
1377 source_.foreach([&](Inner inner) {
1378 inner.foreach(std::forward<Body>(body));
1382 // Resulting concatination is only finite if both Source and Inner are also
1383 // finite. In one sence, if dosn't make sence to call concat when the Inner
1384 // generator is infinite (you could just call first), so we could also just
1385 // static_assert if the inner is infinite. Taking the less restrictive
1387 static constexpr bool infinite =
1388 Source::infinite || std::decay<Inner>::type::infinite;
1391 template <class Value,
1393 class Gen = Generator<Value, Source>>
1394 Gen compose(GenImpl<Value, Source>&& source) const {
1395 return Gen(std::move(source.self()));
1398 template <class Value,
1400 class Gen = Generator<Value, Source>>
1401 Gen compose(const GenImpl<Value, Source>& source) const {
1402 return Gen(source.self());
1407 * RangeConcat - For flattening generators of iterables.
1409 * This type is usually used through the 'rconcat' static value, like:
1411 * map<int, vector<int>> adjacency;
1418 class RangeConcat : public Operator<RangeConcat> {
1420 RangeConcat() = default;
1422 template <class Range,
1424 class InnerValue = typename ValueTypeOfRange<Range>::RefType>
1426 : public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
1430 explicit Generator(Source source) : source_(std::move(source)) {}
1432 template <class Body>
1433 void foreach(Body&& body) const {
1434 source_.foreach([&](Range range) {
1435 for (auto& value : range) {
1441 template <class Handler>
1442 bool apply(Handler&& handler) const {
1443 return source_.apply([&](Range range) -> bool {
1444 for (auto& value : range) {
1445 if (!handler(value)) {
1453 // This is similar to concat, except that the inner iterables all are finite
1454 // so the only thing that matters is that the source is infinite.
1455 static constexpr bool infinite = Source::infinite;
1458 template <class Value,
1460 class Gen = Generator<Value, Source>>
1461 Gen compose(GenImpl<Value, Source>&& source) const {
1462 return Gen(std::move(source.self()));
1465 template <class Value,
1467 class Gen = Generator<Value, Source>>
1468 Gen compose(const GenImpl<Value, Source>& source) const {
1469 return Gen(source.self());
1474 * GuardImpl - For handling exceptions from downstream computation. Requires the
1475 * type of exception to catch, and handler function to invoke in the event of
1476 * the exception. Note that the handler may:
1477 * 1) return true to continue processing the sequence
1478 * 2) return false to end the sequence immediately
1479 * 3) throw, to pass the exception to the next catch
1480 * The handler must match the signature 'bool(Exception&, Value)'.
1482 * This type is used through the `guard` helper, like so:
1485 * = byLine(STDIN_FILENO)
1486 * | guard<std::runtime_error>([](std::runtime_error& e,
1488 * LOG(ERROR) << sp << ": " << e.str();
1489 * return true; // continue processing subsequent lines
1494 * TODO(tjackson): Rename this back to Guard.
1496 template <class Exception, class ErrorHandler>
1497 class GuardImpl : public Operator<GuardImpl<Exception, ErrorHandler>> {
1498 ErrorHandler handler_;
1501 explicit GuardImpl(ErrorHandler handler) : handler_(std::move(handler)) {}
1503 template <class Value, class Source>
1504 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1506 ErrorHandler handler_;
1509 explicit Generator(Source source, ErrorHandler handler)
1510 : source_(std::move(source)), handler_(std::move(handler)) {}
1512 template <class Handler>
1513 bool apply(Handler&& handler) const {
1514 return source_.apply([&](Value value) -> bool {
1516 handler(std::forward<Value>(value));
1518 } catch (Exception& e) {
1519 return handler_(e, std::forward<Value>(value));
1524 // Just passes value though, length unaffected
1525 static constexpr bool infinite = Source::infinite;
1528 template <class Value,
1530 class Gen = Generator<Value, Source>>
1531 Gen compose(GenImpl<Value, Source>&& source) const {
1532 return Gen(std::move(source.self()), handler_);
1535 template <class Value,
1537 class Gen = Generator<Value, Source>>
1538 Gen compose(const GenImpl<Value, Source>& source) const {
1539 return Gen(source.self(), handler_);
1544 * Dereference - For dereferencing a sequence of pointers while filtering out
1547 * This type is usually used through the 'dereference' static value, like:
1549 * auto refs = from(ptrs) | dereference;
1551 class Dereference : public Operator<Dereference> {
1553 Dereference() = default;
1555 template <class Value,
1557 class Result = decltype(*std::declval<Value>())>
1558 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1562 explicit Generator(Source source) : source_(std::move(source)) {}
1564 template <class Body>
1565 void foreach(Body&& body) const {
1566 source_.foreach([&](Value value) {
1568 return body(*value);
1573 template <class Handler>
1574 bool apply(Handler&& handler) const {
1575 return source_.apply([&](Value value) -> bool {
1577 return handler(*value);
1583 // Just passes value though, length unaffected
1584 static constexpr bool infinite = Source::infinite;
1587 template <class Source,
1589 class Gen = Generator<Value, Source>>
1590 Gen compose(GenImpl<Value, Source>&& source) const {
1591 return Gen(std::move(source.self()));
1594 template <class Source,
1596 class Gen = Generator<Value, Source>>
1597 Gen compose(const GenImpl<Value, Source>& source) const {
1598 return Gen(source.self());
1603 * Indirect - For producing a sequence of the addresses of the values in the
1606 * This type is usually used through the 'indirect' static value, like:
1608 * auto ptrs = from(refs) | indirect;
1610 class Indirect : public Operator<Indirect> {
1612 Indirect() = default;
1614 template <class Value,
1616 class Result = typename std::remove_reference<Value>::type*>
1617 class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
1619 static_assert(!std::is_rvalue_reference<Value>::value,
1620 "Cannot use indirect on an rvalue");
1623 explicit Generator(Source source) : source_(std::move(source)) {}
1625 template <class Body>
1626 void foreach(Body&& body) const {
1627 source_.foreach([&](Value value) {
1628 return body(&value);
1632 template <class Handler>
1633 bool apply(Handler&& handler) const {
1634 return source_.apply([&](Value value) -> bool {
1635 return handler(&value);
1639 // Just passes value though, length unaffected
1640 static constexpr bool infinite = Source::infinite;
1643 template <class Source,
1645 class Gen = Generator<Value, Source>>
1646 Gen compose(GenImpl<Value, Source>&& source) const {
1647 return Gen(std::move(source.self()));
1650 template <class Source,
1652 class Gen = Generator<Value, Source>>
1653 Gen compose(const GenImpl<Value, Source>& source) const {
1654 return Gen(source.self());
1659 * Cycle - For repeating a sequence forever.
1661 * This type is usually used through the 'cycle' static value, like:
1668 * or in the finite case:
1670 * auto thrice = g | cycle(3);
1672 template <bool forever>
1673 class Cycle : public Operator<Cycle<forever>> {
1674 off_t limit_; // not used if forever == true
1678 explicit Cycle(off_t limit) : limit_(limit) {
1681 "Cycle limit constructor should not be used when forever == true.");
1684 template <class Value, class Source>
1685 class Generator : public GenImpl<Value, Generator<Value, Source>> {
1690 explicit Generator(Source source, off_t limit)
1691 : source_(std::move(source)), limit_(limit) {}
1693 template <class Handler>
1694 bool apply(Handler&& handler) const {
1696 auto handler2 = [&](Value value) {
1697 cont = handler(std::forward<Value>(value));
1700 // Becomes an infinte loop if forever == true
1701 for (off_t count = 0; (forever || count != limit_); ++count) {
1703 source_.apply(handler2);
1711 // This is the hardest one to infer. If we are simply doing a finite cycle,
1712 // then (gen | cycle(n)) is infinite if and only if gen is infinite.
1713 // However, if we are doing an infinite cycle, (gen | cycle) is infinite
1714 // unless gen is empty. However, we will always mark (gen | cycle) as
1715 // infinite, because patterns such as (gen | cycle | count) can either take
1716 // on exactly one value, or infinite loop.
1717 static constexpr bool infinite = forever || Source::infinite;
1720 template <class Source,
1722 class Gen = Generator<Value, Source>>
1723 Gen compose(GenImpl<Value, Source>&& source) const {
1724 return Gen(std::move(source.self()), limit_);
1727 template <class Source,
1729 class Gen = Generator<Value, Source>>
1730 Gen compose(const GenImpl<Value, Source>& source) const {
1731 return Gen(source.self(), limit_);
1735 * Convenience function for finite cycles used like:
1737 * auto tripled = gen | cycle(3);
1739 Cycle<false> operator()(off_t limit) const { return Cycle<false>(limit); }
1743 ******************************* Sinks *****************************************
1747 * FoldLeft - Left-associative functional fold. For producing an aggregate value
1748 * from a seed and a folder function. Useful for custom aggregators on a
1751 * This type is primarily used through the 'foldl' helper method, like:
1753 * double movingAverage = from(values)
1754 * | foldl(0.0, [](double avg, double sample) {
1755 * return sample * 0.1 + avg * 0.9;
1758 template <class Seed, class Fold>
1759 class FoldLeft : public Operator<FoldLeft<Seed, Fold>> {
1764 FoldLeft() = default;
1765 FoldLeft(Seed seed, Fold fold)
1766 : seed_(std::move(seed)), fold_(std::move(fold)) {}
1768 template <class Source, class Value>
1769 Seed compose(const GenImpl<Value, Source>& source) const {
1770 static_assert(!Source::infinite, "Cannot foldl infinite source");
1772 source | [&](Value v) {
1773 accum = fold_(std::move(accum), std::forward<Value>(v));
1780 * First - For finding the first value in a sequence.
1782 * This type is primarily used through the 'first' static value, like:
1784 * int firstThreeDigitPrime = seq(100) | filter(isPrime) | first;
1786 class First : public Operator<First> {
1790 template <class Source,
1792 class StorageType = typename std::decay<Value>::type>
1793 Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
1794 Optional<StorageType> accum;
1795 source | [&](Value v) -> bool {
1796 accum = std::forward<Value>(v);
1804 * IsEmpty - a helper class for isEmpty and notEmpty
1806 * Essentially returns 'result' if the source is empty. Note that this cannot be
1807 * called on an infinite source, because then there is only one possible return
1811 * Used primarily through 'isEmpty' and 'notEmpty' static values
1813 * bool hasPrimes = g | filter(prime) | notEmpty;
1814 * bool lacksEvens = g | filter(even) | isEmpty;
1816 * Also used in the implementation of 'any' and 'all'
1818 template <bool emptyResult>
1819 class IsEmpty : public Operator<IsEmpty<emptyResult>> {
1821 IsEmpty() = default;
1823 template <class Source, class Value>
1824 bool compose(const GenImpl<Value, Source>& source) const {
1825 static_assert(!Source::infinite,
1826 "Cannot call 'all', 'any', 'isEmpty', or 'notEmpty' on "
1827 "infinite source. 'all' and 'isEmpty' will either return "
1828 "false or hang. 'any' or 'notEmpty' will either return true "
1830 bool ans = emptyResult;
1831 source | [&](Value v) -> bool {
1840 * Reduce - Functional reduce, for recursively combining values from a source
1841 * using a reducer function until there is only one item left. Useful for
1842 * combining values when an empty sequence doesn't make sense.
1844 * This type is primarily used through the 'reduce' helper method, like:
1846 * sring longest = from(names)
1847 * | reduce([](string&& best, string& current) {
1848 * return best.size() >= current.size() ? best : current;
1851 template <class Reducer>
1852 class Reduce : public Operator<Reduce<Reducer>> {
1857 explicit Reduce(Reducer reducer) : reducer_(std::move(reducer)) {}
1859 template <class Source,
1861 class StorageType = typename std::decay<Value>::type>
1862 Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
1863 static_assert(!Source::infinite, "Cannot reduce infinite source");
1864 Optional<StorageType> accum;
1865 source | [&](Value v) {
1866 if (accum.hasValue()) {
1867 accum = reducer_(std::move(accum.value()), std::forward<Value>(v));
1869 accum = std::forward<Value>(v);
1877 * Count - for simply counting the items in a collection.
1879 * This type is usually used through its singleton, 'count':
1881 * auto shortPrimes = seq(1, 100) | filter(isPrime) | count;
1883 class Count : public Operator<Count> {
1887 template <class Source, class Value>
1888 size_t compose(const GenImpl<Value, Source>& source) const {
1889 static_assert(!Source::infinite, "Cannot count infinite source");
1890 return foldl(size_t(0),
1891 [](size_t accum, Value v) {
1898 * Sum - For simply summing up all the values from a source.
1900 * This type is usually used through its singleton, 'sum':
1902 * auto gaussSum = seq(1, 100) | sum;
1904 class Sum : public Operator<Sum> {
1908 template <class Source,
1910 class StorageType = typename std::decay<Value>::type>
1911 StorageType compose(const GenImpl<Value, Source>& source) const {
1912 static_assert(!Source::infinite, "Cannot sum infinite source");
1913 return foldl(StorageType(0),
1914 [](StorageType&& accum, Value v) {
1915 return std::move(accum) + std::forward<Value>(v);
1921 * Contains - For testing whether a value matching the given value is contained
1924 * This type should be used through the 'contains' helper method, like:
1926 * bool contained = seq(1, 10) | map(square) | contains(49);
1928 template <class Needle>
1929 class Contains : public Operator<Contains<Needle>> {
1933 explicit Contains(Needle needle) : needle_(std::move(needle)) {}
1935 template <class Source,
1937 class StorageType = typename std::decay<Value>::type>
1938 bool compose(const GenImpl<Value, Source>& source) const {
1939 static_assert(!Source::infinite,
1940 "Calling contains on an infinite source might cause "
1941 "an infinite loop.");
1942 return !(source | [this](Value value) {
1943 return !(needle_ == std::forward<Value>(value));
1949 * Min - For a value which minimizes a key, where the key is determined by a
1950 * given selector, and compared by given comparer.
1952 * This type is usually used through the singletone 'min' or through the helper
1953 * functions 'minBy' and 'maxBy'.
1955 * auto oldest = from(people)
1956 * | minBy([](Person& p) {
1957 * return p.dateOfBirth;
1960 template <class Selector, class Comparer>
1961 class Min : public Operator<Min<Selector, Comparer>> {
1968 explicit Min(Selector selector) : selector_(std::move(selector)) {}
1970 Min(Selector selector, Comparer comparer)
1971 : selector_(std::move(selector)), comparer_(std::move(comparer)) {}
1973 template <class Value,
1975 class StorageType = typename std::decay<Value>::type,
1976 class Key = typename std::decay<
1977 typename std::result_of<Selector(Value)>::type>::type>
1978 Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
1979 static_assert(!Source::infinite,
1980 "Calling min or max on an infinite source will cause "
1981 "an infinite loop.");
1982 Optional<StorageType> min;
1983 Optional<Key> minKey;
1984 source | [&](Value v) {
1985 Key key = selector_(std::forward<Value>(v));
1986 if (!minKey.hasValue() || comparer_(key, minKey.value())) {
1988 min = std::forward<Value>(v);
1996 * Append - For collecting values from a source into a given output container
1999 * This type is usually used through the helper function 'appendTo', like:
2001 * vector<int64_t> ids;
2002 * from(results) | map([](Person& p) { return p.id })
2005 template <class Collection>
2006 class Append : public Operator<Append<Collection>> {
2007 Collection* collection_;
2010 explicit Append(Collection* collection) : collection_(collection) {}
2012 template <class Value, class Source>
2013 Collection& compose(const GenImpl<Value, Source>& source) const {
2014 static_assert(!Source::infinite, "Cannot appendTo with infinite source");
2015 source | [&](Value v) {
2016 collection_->insert(collection_->end(), std::forward<Value>(v));
2018 return *collection_;
2023 * Collect - For collecting values from a source in a collection of the desired
2026 * This type is usually used through the helper function 'as', like:
2028 * std::string upper = from(stringPiece)
2030 * | as<std::string>();
2032 template <class Collection>
2033 class Collect : public Operator<Collect<Collection>> {
2035 Collect() = default;
2037 template <class Value,
2039 class StorageType = typename std::decay<Value>::type>
2040 Collection compose(const GenImpl<Value, Source>& source) const {
2041 static_assert(!Source::infinite,
2042 "Cannot convert infinite source to object with as.");
2043 Collection collection;
2044 source | [&](Value v) {
2045 collection.insert(collection.end(), std::forward<Value>(v));
2052 * CollectTemplate - For collecting values from a source in a collection
2053 * constructed using the specified template type. Given the type of values
2054 * produced by the given generator, the collection type will be:
2055 * Container<Value, Allocator<Value>>
2057 * The allocator defaults to std::allocator, so this may be used for the STL
2058 * containers by simply using operators like 'as<set>', 'as<deque>',
2059 * 'as<vector>'. 'as', here is the helper method which is the usual means of
2060 * constructing this operator.
2064 * set<string> uniqueNames = from(names) | as<set>();
2066 template <template <class, class> class Container,
2067 template <class> class Allocator>
2068 class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
2070 CollectTemplate() = default;
2072 template <class Value,
2074 class StorageType = typename std::decay<Value>::type,
2075 class Collection = Container<StorageType, Allocator<StorageType>>>
2076 Collection compose(const GenImpl<Value, Source>& source) const {
2077 static_assert(!Source::infinite,
2078 "Cannot convert infinite source to object with as.");
2079 Collection collection;
2080 source | [&](Value v) {
2081 collection.insert(collection.end(), std::forward<Value>(v));
2088 * UnwrapOr - For unwrapping folly::Optional values, or providing the given
2089 * fallback value. Usually used through the 'unwrapOr' helper like so:
2091 * auto best = from(scores) | max | unwrapOr(-1);
2093 * Note that the fallback value needn't match the value in the Optional it is
2094 * unwrapping. If mis-matched types are supported, the common type of the two is
2095 * returned by value. If the types match, a reference (T&& > T& > const T&) is
2101 explicit UnwrapOr(T&& value) : value_(std::move(value)) {}
2102 explicit UnwrapOr(const T& value) : value_(value) {}
2104 T& value() { return value_; }
2105 const T& value() const { return value_; }
2112 T&& operator|(Optional<T>&& opt, UnwrapOr<T>&& fallback) {
2113 if (T* p = opt.get_pointer()) {
2114 return std::move(*p);
2116 return std::move(fallback.value());
2120 T& operator|(Optional<T>& opt, UnwrapOr<T>& fallback) {
2121 if (T* p = opt.get_pointer()) {
2124 return fallback.value();
2128 const T& operator|(const Optional<T>& opt, const UnwrapOr<T>& fallback) {
2129 if (const T* p = opt.get_pointer()) {
2132 return fallback.value();
2135 // Mixed type unwrapping always returns values, moving where possible
2138 class R = typename std::enable_if<
2139 !std::is_same<T, U>::value,
2140 typename std::common_type<T, U>::type>::type>
2141 R operator|(Optional<T>&& opt, UnwrapOr<U>&& fallback) {
2142 if (T* p = opt.get_pointer()) {
2143 return std::move(*p);
2145 return std::move(fallback.value());
2150 class R = typename std::enable_if<
2151 !std::is_same<T, U>::value,
2152 typename std::common_type<T, U>::type>::type>
2153 R operator|(const Optional<T>& opt, UnwrapOr<U>&& fallback) {
2154 if (const T* p = opt.get_pointer()) {
2157 return std::move(fallback.value());
2162 class R = typename std::enable_if<
2163 !std::is_same<T, U>::value,
2164 typename std::common_type<T, U>::type>::type>
2165 R operator|(Optional<T>&& opt, const UnwrapOr<U>& fallback) {
2166 if (T* p = opt.get_pointer()) {
2167 return std::move(*p);
2169 return fallback.value();
2174 class R = typename std::enable_if<
2175 !std::is_same<T, U>::value,
2176 typename std::common_type<T, U>::type>::type>
2177 R operator|(const Optional<T>& opt, const UnwrapOr<U>& fallback) {
2178 if (const T* p = opt.get_pointer()) {
2181 return fallback.value();
2185 * Unwrap - For unwrapping folly::Optional values in a folly::gen style. Usually
2186 * used through the 'unwrap' instace like so:
2188 * auto best = from(scores) | max | unwrap; // may throw
2193 T&& operator|(Optional<T>&& opt, const Unwrap&) {
2194 return std::move(opt.value());
2198 T& operator|(Optional<T>& opt, const Unwrap&) {
2203 const T& operator|(const Optional<T>& opt, const Unwrap&) {
2210 * VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
2212 template <class Value>
2213 class VirtualGen : public GenImpl<Value, VirtualGen<Value>> {
2216 virtual ~WrapperBase() noexcept {}
2217 virtual bool apply(const std::function<bool(Value)>& handler) const = 0;
2218 virtual void foreach(const std::function<void(Value)>& body) const = 0;
2219 virtual std::unique_ptr<const WrapperBase> clone() const = 0;
2222 template <class Wrapped>
2223 class WrapperImpl : public WrapperBase {
2227 explicit WrapperImpl(Wrapped wrapped) : wrapped_(std::move(wrapped)) {}
2229 virtual bool apply(const std::function<bool(Value)>& handler) const {
2230 return wrapped_.apply(handler);
2233 virtual void foreach(const std::function<void(Value)>& body) const {
2234 wrapped_.foreach(body);
2237 virtual std::unique_ptr<const WrapperBase> clone() const {
2238 return std::unique_ptr<const WrapperBase>(new WrapperImpl(wrapped_));
2242 std::unique_ptr<const WrapperBase> wrapper_;
2245 template <class Self>
2246 /* implicit */ VirtualGen(Self source)
2247 : wrapper_(new WrapperImpl<Self>(std::move(source))) {}
2249 VirtualGen(VirtualGen&& source) noexcept
2250 : wrapper_(std::move(source.wrapper_)) {}
2252 VirtualGen(const VirtualGen& source) : wrapper_(source.wrapper_->clone()) {}
2254 VirtualGen& operator=(const VirtualGen& source) {
2255 wrapper_.reset(source.wrapper_->clone());
2259 VirtualGen& operator=(VirtualGen&& source) noexcept {
2260 wrapper_ = std::move(source.wrapper_);
2264 bool apply(const std::function<bool(Value)>& handler) const {
2265 return wrapper_->apply(handler);
2268 void foreach(const std::function<void(Value)>& body) const {
2269 wrapper_->foreach(body);
2274 * non-template operators, statically defined to avoid the need for anything but
2277 constexpr detail::Sum sum{};
2279 constexpr detail::Count count{};
2281 constexpr detail::First first{};
2283 constexpr detail::IsEmpty<true> isEmpty{};
2285 constexpr detail::IsEmpty<false> notEmpty{};
2287 constexpr detail::Min<Identity, Less> min{};
2289 constexpr detail::Min<Identity, Greater> max{};
2291 constexpr detail::Order<Identity> order{};
2293 constexpr detail::Distinct<Identity> distinct{};
2295 constexpr detail::Map<Move> move{};
2297 constexpr detail::Concat concat{};
2299 constexpr detail::RangeConcat rconcat{};
2301 constexpr detail::Cycle<true> cycle{};
2303 constexpr detail::Dereference dereference{};
2305 constexpr detail::Indirect indirect{};
2307 constexpr detail::Unwrap unwrap{};
2309 inline detail::Take take(size_t count) { return detail::Take(count); }
2311 inline detail::Stride stride(size_t s) { return detail::Stride(s); }
2313 template <class Random = std::default_random_engine>
2314 inline detail::Sample<Random> sample(size_t count, Random rng = Random()) {
2315 return detail::Sample<Random>(count, std::move(rng));
2318 inline detail::Skip skip(size_t count) { return detail::Skip(count); }
2320 inline detail::Batch batch(size_t batchSize) {
2321 return detail::Batch(batchSize);
2326 #pragma GCC diagnostic pop