stride()
[folly.git] / folly / gen / Base.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_GEN_BASE_H
18 #define FOLLY_GEN_BASE_H
19
20 #include <functional>
21 #include <memory>
22 #include <type_traits>
23 #include <utility>
24 #include <algorithm>
25 #include <random>
26 #include <vector>
27 #include <unordered_set>
28
29 #include <folly/Range.h>
30 #include <folly/Optional.h>
31 #include <folly/Conv.h>
32 #include <folly/gen/Core.h>
33
34 /**
35  * Generator-based Sequence Comprehensions in C++, akin to C#'s LINQ
36  * @author Tom Jackson <tjackson@fb.com>
37  *
38  * This library makes it possible to write declarative comprehensions for
39  * processing sequences of values efficiently in C++. The operators should be
40  * familiar to those with experience in functional programming, and the
41  * performance will be virtually identical to the equivalent, boilerplate C++
42  * implementations.
43  *
44  * Generator objects may be created from either an stl-like container (anything
45  * supporting begin() and end()), from sequences of values, or from another
46  * generator (see below). To create a generator that pulls values from a vector,
47  * for example, one could write:
48  *
49  *   vector<string> names { "Jack", "Jill", "Sara", "Tom" };
50  *   auto gen = from(names);
51  *
52  * Generators are composed by building new generators out of old ones through
53  * the use of operators. These are reminicent of shell pipelines, and afford
54  * similar composition. Lambda functions are used liberally to describe how to
55  * handle individual values:
56  *
57  *   auto lengths = gen
58  *                | mapped([](const fbstring& name) { return name.size(); });
59  *
60  * Generators are lazy; they don't actually perform any work until they need to.
61  * As an example, the 'lengths' generator (above) won't actually invoke the
62  * provided lambda until values are needed:
63  *
64  *   auto lengthVector = lengths | as<std::vector>();
65  *   auto totalLength = lengths | sum;
66  *
67  * 'auto' is useful in here because the actual types of the generators objects
68  * are usually complicated and implementation-sensitive.
69  *
70  * If a simpler type is desired (for returning, as an example), VirtualGen<T>
71  * may be used to wrap the generator in a polymorphic wrapper:
72  *
73  *  VirtualGen<float> powersOfE() {
74  *    return seq(1) | mapped(&expf);
75  *  }
76  *
77  * To learn more about this library, including the use of infinite generators,
78  * see the examples in the comments, or the docs (coming soon).
79 */
80
81 namespace folly { namespace gen {
82
83 class EmptySequence : public std::exception {
84 public:
85   virtual const char* what() const noexcept {
86     return "This operation cannot be called on an empty sequence";
87   }
88 };
89
90 class Less {
91 public:
92   template<class First,
93            class Second>
94   auto operator()(const First& first, const Second& second) const ->
95   decltype(first < second) {
96     return first < second;
97   }
98 };
99
100 class Greater {
101 public:
102   template<class First,
103            class Second>
104   auto operator()(const First& first, const Second& second) const ->
105   decltype(first > second) {
106     return first > second;
107   }
108 };
109
110 template<int n>
111 class Get {
112 public:
113   template<class Value>
114   auto operator()(Value&& value) const ->
115   decltype(std::get<n>(std::forward<Value>(value))) {
116     return std::get<n>(std::forward<Value>(value));
117   }
118 };
119
120 template<class Class,
121          class Result>
122 class MemberFunction {
123  public:
124   typedef Result (Class::*MemberPtr)();
125  private:
126   MemberPtr member_;
127  public:
128   explicit MemberFunction(MemberPtr member)
129     : member_(member)
130   {}
131
132   Result operator()(Class&& x) const {
133     return (x.*member_)();
134   }
135
136   Result operator()(Class& x) const {
137     return (x.*member_)();
138   }
139
140   Result operator()(Class* x) const {
141     return (x->*member_)();
142   }
143 };
144
145 template<class Class,
146          class Result>
147 class ConstMemberFunction{
148  public:
149   typedef Result (Class::*MemberPtr)() const;
150  private:
151   MemberPtr member_;
152  public:
153   explicit ConstMemberFunction(MemberPtr member)
154     : member_(member)
155   {}
156
157   Result operator()(const Class& x) const {
158     return (x.*member_)();
159   }
160
161   Result operator()(const Class* x) const {
162     return (x->*member_)();
163   }
164 };
165
166 template<class Class,
167          class FieldType>
168 class Field {
169  public:
170   typedef FieldType (Class::*FieldPtr);
171  private:
172   FieldPtr field_;
173  public:
174   explicit Field(FieldPtr field)
175     : field_(field)
176   {}
177
178   const FieldType& operator()(const Class& x) const {
179     return x.*field_;
180   }
181
182   const FieldType& operator()(const Class* x) const {
183     return x->*field_;
184   }
185
186   FieldType& operator()(Class& x) const {
187     return x.*field_;
188   }
189
190   FieldType& operator()(Class* x) const {
191     return x->*field_;
192   }
193
194   FieldType&& operator()(Class&& x) const {
195     return std::move(x.*field_);
196   }
197 };
198
199 class Move {
200 public:
201   template<class Value>
202   auto operator()(Value&& value) const ->
203   decltype(std::move(std::forward<Value>(value))) {
204     return std::move(std::forward<Value>(value));
205   }
206 };
207
208 class Identity {
209 public:
210   template<class Value>
211   auto operator()(Value&& value) const ->
212   decltype(std::forward<Value>(value)) {
213     return std::forward<Value>(value);
214   }
215 };
216
217 template <class Dest>
218 class Cast {
219  public:
220   template <class Value>
221   Dest operator()(Value&& value) const {
222     return Dest(std::forward<Value>(value));
223   }
224 };
225
226 template <class Dest>
227 class To {
228  public:
229   template <class Value>
230   Dest operator()(Value&& value) const {
231     return ::folly::to<Dest>(std::forward<Value>(value));
232   }
233 };
234
235 // Specialization to allow String->StringPiece conversion
236 template <>
237 class To<StringPiece> {
238  public:
239   StringPiece operator()(StringPiece src) const {
240     return src;
241   }
242 };
243
244 namespace detail {
245
246 template<class Self>
247 struct FBounded;
248
249 /*
250  * Type Traits
251  */
252 template<class Container>
253 struct ValueTypeOfRange {
254  private:
255   static Container container_;
256  public:
257   typedef decltype(*std::begin(container_))
258     RefType;
259   typedef typename std::decay<decltype(*std::begin(container_))>::type
260     StorageType;
261 };
262
263
264 /*
265  * Sources
266  */
267 template<class Container,
268          class Value = typename ValueTypeOfRange<Container>::RefType>
269 class ReferencedSource;
270
271 template<class Value,
272          class Container = std::vector<typename std::decay<Value>::type>>
273 class CopiedSource;
274
275 template<class Value, class SequenceImpl>
276 class Sequence;
277
278 template <class Value>
279 class RangeImpl;
280
281 template <class Value, class Distance>
282 class RangeWithStepImpl;
283
284 template <class Value>
285 class SeqImpl;
286
287 template <class Value, class Distance>
288 class SeqWithStepImpl;
289
290 template <class Value>
291 class InfiniteImpl;
292
293 template<class Value, class Source>
294 class Yield;
295
296 template<class Value>
297 class Empty;
298
299 template<class Value>
300 class Just;
301
302 /*
303  * Operators
304  */
305 template<class Predicate>
306 class Map;
307
308 template<class Predicate>
309 class Filter;
310
311 template<class Predicate>
312 class Until;
313
314 class Take;
315
316 class Stride;
317
318 template<class Rand>
319 class Sample;
320
321 class Skip;
322
323 template<class Selector, class Comparer = Less>
324 class Order;
325
326 template<class Selector>
327 class Distinct;
328
329 template<class Operators>
330 class Composer;
331
332 template<class Expected>
333 class TypeAssertion;
334
335 class Concat;
336
337 class RangeConcat;
338
339 class Cycle;
340
341 class Batch;
342
343 class Dereference;
344
345 /*
346  * Sinks
347  */
348 template<class Seed,
349          class Fold>
350 class FoldLeft;
351
352 class First;
353
354 class Any;
355
356 template<class Predicate>
357 class All;
358
359 template<class Reducer>
360 class Reduce;
361
362 class Sum;
363
364 template<class Selector,
365          class Comparer>
366 class Min;
367
368 template<class Container>
369 class Collect;
370
371 template<template<class, class> class Collection = std::vector,
372          template<class> class Allocator = std::allocator>
373 class CollectTemplate;
374
375 template<class Collection>
376 class Append;
377
378 template<class Value>
379 struct GeneratorBuilder;
380
381 template<class Needle>
382 class Contains;
383
384 template<class Exception,
385          class ErrorHandler>
386 class GuardImpl;
387
388 }
389
390 /**
391  * Polymorphic wrapper
392  **/
393 template<class Value>
394 class VirtualGen;
395
396 /*
397  * Source Factories
398  */
399 template<class Container,
400          class From = detail::ReferencedSource<const Container>>
401 From fromConst(const Container& source) {
402   return From(&source);
403 }
404
405 template<class Container,
406          class From = detail::ReferencedSource<Container>>
407 From from(Container& source) {
408   return From(&source);
409 }
410
411 template<class Container,
412          class Value =
413            typename detail::ValueTypeOfRange<Container>::StorageType,
414          class CopyOf = detail::CopiedSource<Value>>
415 CopyOf fromCopy(Container&& source) {
416   return CopyOf(std::forward<Container>(source));
417 }
418
419 template<class Value,
420          class From = detail::CopiedSource<Value>>
421 From from(std::initializer_list<Value> source) {
422   return From(source);
423 }
424
425 template<class Container,
426          class From = detail::CopiedSource<typename Container::value_type,
427                                            Container>>
428 From from(Container&& source) {
429   return From(std::move(source));
430 }
431
432 template<class Value, class Impl = detail::RangeImpl<Value>,
433          class Gen = detail::Sequence<Value, Impl>>
434 Gen range(Value begin, Value end) {
435   return Gen{std::move(begin), Impl{std::move(end)}};
436 }
437
438 template<class Value, class Distance,
439          class Impl = detail::RangeWithStepImpl<Value, Distance>,
440          class Gen = detail::Sequence<Value, Impl>>
441 Gen range(Value begin, Value end, Distance step) {
442   return Gen{std::move(begin), Impl{std::move(end), std::move(step)}};
443 }
444
445 template<class Value, class Impl = detail::SeqImpl<Value>,
446          class Gen = detail::Sequence<Value, Impl>>
447 Gen seq(Value first, Value last) {
448   return Gen{std::move(first), Impl{std::move(last)}};
449 }
450
451 template<class Value, class Distance,
452          class Impl = detail::SeqWithStepImpl<Value, Distance>,
453          class Gen = detail::Sequence<Value, Impl>>
454 Gen seq(Value first, Value last, Distance step) {
455   return Gen{std::move(first), Impl{std::move(last), std::move(step)}};
456 }
457
458 template<class Value, class Impl = detail::InfiniteImpl<Value>,
459          class Gen = detail::Sequence<Value, Impl>>
460 Gen seq(Value first) {
461   return Gen{std::move(first), Impl{}};
462 }
463
464 template<class Value,
465          class Source,
466          class Yield = detail::Yield<Value, Source>>
467 Yield generator(Source&& source) {
468   return Yield(std::forward<Source>(source));
469 }
470
471 /*
472  * Create inline generator, used like:
473  *
474  *  auto gen = GENERATOR(int) { yield(1); yield(2); };
475  */
476 #define GENERATOR(TYPE)                            \
477   ::folly::gen::detail::GeneratorBuilder<TYPE>() + \
478    [=](const std::function<void(TYPE)>& yield)
479
480 /*
481  * empty() - for producing empty sequences.
482  */
483 template<class Value>
484 detail::Empty<Value> empty() {
485   return {};
486 }
487
488 template<class Value>
489 detail::Just<Value> just(Value value) {
490   return detail::Just<Value>(std::move(value));
491 }
492
493 /*
494  * Operator Factories
495  */
496 template<class Predicate,
497          class Map = detail::Map<Predicate>>
498 Map mapped(Predicate pred = Predicate()) {
499   return Map(std::move(pred));
500 }
501
502 template<class Predicate,
503          class Map = detail::Map<Predicate>>
504 Map map(Predicate pred = Predicate()) {
505   return Map(std::move(pred));
506 }
507
508 /**
509  * mapOp - Given a generator of generators, maps the application of the given
510  * operator on to each inner gen. Especially useful in aggregating nested data
511  * structures:
512  *
513  *   chunked(samples, 256)
514  *     | mapOp(filter(sampleTest) | count)
515  *     | sum;
516  */
517 template<class Operator,
518          class Map = detail::Map<detail::Composer<Operator>>>
519 Map mapOp(Operator op) {
520   return Map(detail::Composer<Operator>(std::move(op)));
521 }
522
523 /*
524  * member(...) - For extracting a member from each value.
525  *
526  *  vector<string> strings = ...;
527  *  auto sizes = from(strings) | member(&string::size);
528  *
529  * If a member is const overridden (like 'front()'), pass template parameter
530  * 'Const' to select the const version, or 'Mutable' to select the non-const
531  * version:
532  *
533  *  auto heads = from(strings) | member<Const>(&string::front);
534  */
535 enum MemberType {
536   Const,
537   Mutable
538 };
539
540 template<MemberType Constness = Const,
541          class Class,
542          class Return,
543          class Mem = ConstMemberFunction<Class, Return>,
544          class Map = detail::Map<Mem>>
545 typename std::enable_if<Constness == Const, Map>::type
546 member(Return (Class::*member)() const) {
547   return Map(Mem(member));
548 }
549
550 template<MemberType Constness = Mutable,
551          class Class,
552          class Return,
553          class Mem = MemberFunction<Class, Return>,
554          class Map = detail::Map<Mem>>
555 typename std::enable_if<Constness == Mutable, Map>::type
556 member(Return (Class::*member)()) {
557   return Map(Mem(member));
558 }
559
560 /*
561  * field(...) - For extracting a field from each value.
562  *
563  *  vector<Item> items = ...;
564  *  auto names = from(items) | field(&Item::name);
565  *
566  * Note that if the values of the generator are rvalues, any non-reference
567  * fields will be rvalues as well. As an example, the code below does not copy
568  * any strings, only moves them:
569  *
570  *  auto namesVector = from(items)
571  *                   | move
572  *                   | field(&Item::name)
573  *                   | as<vector>();
574  */
575 template<class Class,
576          class FieldType,
577          class Field = Field<Class, FieldType>,
578          class Map = detail::Map<Field>>
579 Map field(FieldType Class::*field) {
580   return Map(Field(field));
581 }
582
583 template<class Predicate,
584          class Filter = detail::Filter<Predicate>>
585 Filter filter(Predicate pred = Predicate()) {
586   return Filter(std::move(pred));
587 }
588
589 template<class Predicate,
590          class All = detail::All<Predicate>>
591 All all(Predicate pred = Predicate()) {
592   return All(std::move(pred));
593 }
594
595 template<class Predicate,
596          class Until = detail::Until<Predicate>>
597 Until until(Predicate pred = Predicate()) {
598   return Until(std::move(pred));
599 }
600
601 template<class Selector,
602          class Comparer = Less,
603          class Order = detail::Order<Selector, Comparer>>
604 Order orderBy(Selector selector = Identity(),
605               Comparer comparer = Comparer()) {
606   return Order(std::move(selector),
607                std::move(comparer));
608 }
609
610 template<class Selector,
611          class Order = detail::Order<Selector, Greater>>
612 Order orderByDescending(Selector selector = Identity()) {
613   return Order(std::move(selector));
614 }
615
616 template<class Selector,
617          class Distinct = detail::Distinct<Selector>>
618 Distinct distinctBy(Selector selector = Identity()) {
619   return Distinct(std::move(selector));
620 }
621
622 template<int n,
623          class Get = detail::Map<Get<n>>>
624 Get get() {
625   return Get();
626 }
627
628 // construct Dest from each value
629 template <class Dest,
630           class Cast = detail::Map<Cast<Dest>>>
631 Cast eachAs() {
632   return Cast();
633 }
634
635 // call folly::to on each value
636 template <class Dest,
637           class To = detail::Map<To<Dest>>>
638 To eachTo() {
639   return To();
640 }
641
642 template<class Value>
643 detail::TypeAssertion<Value> assert_type() {
644   return {};
645 }
646
647 /*
648  * Sink Factories
649  */
650 template<class Seed,
651          class Fold,
652          class FoldLeft = detail::FoldLeft<Seed, Fold>>
653 FoldLeft foldl(Seed seed = Seed(),
654                Fold fold = Fold()) {
655   return FoldLeft(std::move(seed),
656                   std::move(fold));
657 }
658
659 template<class Reducer,
660          class Reduce = detail::Reduce<Reducer>>
661 Reduce reduce(Reducer reducer = Reducer()) {
662   return Reduce(std::move(reducer));
663 }
664
665 template<class Selector = Identity,
666          class Min = detail::Min<Selector, Less>>
667 Min minBy(Selector selector = Selector()) {
668   return Min(std::move(selector));
669 }
670
671 template<class Selector,
672          class MaxBy = detail::Min<Selector, Greater>>
673 MaxBy maxBy(Selector selector = Selector()) {
674   return MaxBy(std::move(selector));
675 }
676
677 template<class Collection,
678          class Collect = detail::Collect<Collection>>
679 Collect as() {
680   return Collect();
681 }
682
683 template<template<class, class> class Container = std::vector,
684          template<class> class Allocator = std::allocator,
685          class Collect = detail::CollectTemplate<Container, Allocator>>
686 Collect as() {
687   return Collect();
688 }
689
690 template<class Collection,
691          class Append = detail::Append<Collection>>
692 Append appendTo(Collection& collection) {
693   return Append(&collection);
694 }
695
696 template<class Needle,
697          class Contains = detail::Contains<typename std::decay<Needle>::type>>
698 Contains contains(Needle&& needle) {
699   return Contains(std::forward<Needle>(needle));
700 }
701
702 template<class Exception,
703          class ErrorHandler,
704          class GuardImpl =
705            detail::GuardImpl<
706              Exception,
707              typename std::decay<ErrorHandler>::type>>
708 GuardImpl guard(ErrorHandler&& handler) {
709   return GuardImpl(std::forward<ErrorHandler>(handler));
710 }
711
712 }} // folly::gen
713
714 #include <folly/gen/Base-inl.h>
715
716 #endif // FOLLY_GEN_BASE_H