indirect(), for making pointers out of refs
[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 class Indirect;
346
347 /*
348  * Sinks
349  */
350 template<class Seed,
351          class Fold>
352 class FoldLeft;
353
354 class First;
355
356 class Any;
357
358 template<class Predicate>
359 class All;
360
361 template<class Reducer>
362 class Reduce;
363
364 class Sum;
365
366 template<class Selector,
367          class Comparer>
368 class Min;
369
370 template<class Container>
371 class Collect;
372
373 template<template<class, class> class Collection = std::vector,
374          template<class> class Allocator = std::allocator>
375 class CollectTemplate;
376
377 template<class Collection>
378 class Append;
379
380 template<class Value>
381 struct GeneratorBuilder;
382
383 template<class Needle>
384 class Contains;
385
386 template<class Exception,
387          class ErrorHandler>
388 class GuardImpl;
389
390 }
391
392 /**
393  * Polymorphic wrapper
394  **/
395 template<class Value>
396 class VirtualGen;
397
398 /*
399  * Source Factories
400  */
401 template<class Container,
402          class From = detail::ReferencedSource<const Container>>
403 From fromConst(const Container& source) {
404   return From(&source);
405 }
406
407 template<class Container,
408          class From = detail::ReferencedSource<Container>>
409 From from(Container& source) {
410   return From(&source);
411 }
412
413 template<class Container,
414          class Value =
415            typename detail::ValueTypeOfRange<Container>::StorageType,
416          class CopyOf = detail::CopiedSource<Value>>
417 CopyOf fromCopy(Container&& source) {
418   return CopyOf(std::forward<Container>(source));
419 }
420
421 template<class Value,
422          class From = detail::CopiedSource<Value>>
423 From from(std::initializer_list<Value> source) {
424   return From(source);
425 }
426
427 template<class Container,
428          class From = detail::CopiedSource<typename Container::value_type,
429                                            Container>>
430 From from(Container&& source) {
431   return From(std::move(source));
432 }
433
434 template<class Value, class Impl = detail::RangeImpl<Value>,
435          class Gen = detail::Sequence<Value, Impl>>
436 Gen range(Value begin, Value end) {
437   return Gen{std::move(begin), Impl{std::move(end)}};
438 }
439
440 template<class Value, class Distance,
441          class Impl = detail::RangeWithStepImpl<Value, Distance>,
442          class Gen = detail::Sequence<Value, Impl>>
443 Gen range(Value begin, Value end, Distance step) {
444   return Gen{std::move(begin), Impl{std::move(end), std::move(step)}};
445 }
446
447 template<class Value, class Impl = detail::SeqImpl<Value>,
448          class Gen = detail::Sequence<Value, Impl>>
449 Gen seq(Value first, Value last) {
450   return Gen{std::move(first), Impl{std::move(last)}};
451 }
452
453 template<class Value, class Distance,
454          class Impl = detail::SeqWithStepImpl<Value, Distance>,
455          class Gen = detail::Sequence<Value, Impl>>
456 Gen seq(Value first, Value last, Distance step) {
457   return Gen{std::move(first), Impl{std::move(last), std::move(step)}};
458 }
459
460 template<class Value, class Impl = detail::InfiniteImpl<Value>,
461          class Gen = detail::Sequence<Value, Impl>>
462 Gen seq(Value first) {
463   return Gen{std::move(first), Impl{}};
464 }
465
466 template<class Value,
467          class Source,
468          class Yield = detail::Yield<Value, Source>>
469 Yield generator(Source&& source) {
470   return Yield(std::forward<Source>(source));
471 }
472
473 /*
474  * Create inline generator, used like:
475  *
476  *  auto gen = GENERATOR(int) { yield(1); yield(2); };
477  */
478 #define GENERATOR(TYPE)                            \
479   ::folly::gen::detail::GeneratorBuilder<TYPE>() + \
480    [=](const std::function<void(TYPE)>& yield)
481
482 /*
483  * empty() - for producing empty sequences.
484  */
485 template<class Value>
486 detail::Empty<Value> empty() {
487   return {};
488 }
489
490 template<class Value>
491 detail::Just<Value> just(Value value) {
492   return detail::Just<Value>(std::move(value));
493 }
494
495 /*
496  * Operator Factories
497  */
498 template<class Predicate,
499          class Map = detail::Map<Predicate>>
500 Map mapped(Predicate pred = Predicate()) {
501   return Map(std::move(pred));
502 }
503
504 template<class Predicate,
505          class Map = detail::Map<Predicate>>
506 Map map(Predicate pred = Predicate()) {
507   return Map(std::move(pred));
508 }
509
510 /**
511  * mapOp - Given a generator of generators, maps the application of the given
512  * operator on to each inner gen. Especially useful in aggregating nested data
513  * structures:
514  *
515  *   chunked(samples, 256)
516  *     | mapOp(filter(sampleTest) | count)
517  *     | sum;
518  */
519 template<class Operator,
520          class Map = detail::Map<detail::Composer<Operator>>>
521 Map mapOp(Operator op) {
522   return Map(detail::Composer<Operator>(std::move(op)));
523 }
524
525 /*
526  * member(...) - For extracting a member from each value.
527  *
528  *  vector<string> strings = ...;
529  *  auto sizes = from(strings) | member(&string::size);
530  *
531  * If a member is const overridden (like 'front()'), pass template parameter
532  * 'Const' to select the const version, or 'Mutable' to select the non-const
533  * version:
534  *
535  *  auto heads = from(strings) | member<Const>(&string::front);
536  */
537 enum MemberType {
538   Const,
539   Mutable
540 };
541
542 /**
543  * These exist because MSVC has problems with expression SFINAE in templates
544  * assignment and comparisons don't work properly without being pulled out
545  * of the template declaration
546  */
547 template <MemberType Constness> struct ExprIsConst {
548   enum {
549     value = Constness == Const
550   };
551 };
552
553 template <MemberType Constness> struct ExprIsMutable {
554   enum {
555     value = Constness == Mutable
556   };
557 };
558
559 template<MemberType Constness = Const,
560          class Class,
561          class Return,
562          class Mem = ConstMemberFunction<Class, Return>,
563          class Map = detail::Map<Mem>>
564 typename std::enable_if<ExprIsConst<Constness>::value, Map>::type
565 member(Return (Class::*member)() const) {
566   return Map(Mem(member));
567 }
568
569 template<MemberType Constness = Mutable,
570          class Class,
571          class Return,
572          class Mem = MemberFunction<Class, Return>,
573          class Map = detail::Map<Mem>>
574 typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type
575 member(Return (Class::*member)()) {
576   return Map(Mem(member));
577 }
578
579 /*
580  * field(...) - For extracting a field from each value.
581  *
582  *  vector<Item> items = ...;
583  *  auto names = from(items) | field(&Item::name);
584  *
585  * Note that if the values of the generator are rvalues, any non-reference
586  * fields will be rvalues as well. As an example, the code below does not copy
587  * any strings, only moves them:
588  *
589  *  auto namesVector = from(items)
590  *                   | move
591  *                   | field(&Item::name)
592  *                   | as<vector>();
593  */
594 template<class Class,
595          class FieldType,
596          class Field = Field<Class, FieldType>,
597          class Map = detail::Map<Field>>
598 Map field(FieldType Class::*field) {
599   return Map(Field(field));
600 }
601
602 template<class Predicate,
603          class Filter = detail::Filter<Predicate>>
604 Filter filter(Predicate pred = Predicate()) {
605   return Filter(std::move(pred));
606 }
607
608 template<class Predicate,
609          class All = detail::All<Predicate>>
610 All all(Predicate pred = Predicate()) {
611   return All(std::move(pred));
612 }
613
614 template<class Predicate,
615          class Until = detail::Until<Predicate>>
616 Until until(Predicate pred = Predicate()) {
617   return Until(std::move(pred));
618 }
619
620 template<class Selector,
621          class Comparer = Less,
622          class Order = detail::Order<Selector, Comparer>>
623 Order orderBy(Selector selector = Identity(),
624               Comparer comparer = Comparer()) {
625   return Order(std::move(selector),
626                std::move(comparer));
627 }
628
629 template<class Selector,
630          class Order = detail::Order<Selector, Greater>>
631 Order orderByDescending(Selector selector = Identity()) {
632   return Order(std::move(selector));
633 }
634
635 template<class Selector,
636          class Distinct = detail::Distinct<Selector>>
637 Distinct distinctBy(Selector selector = Identity()) {
638   return Distinct(std::move(selector));
639 }
640
641 template<int n,
642          class Get = detail::Map<Get<n>>>
643 Get get() {
644   return Get();
645 }
646
647 // construct Dest from each value
648 template <class Dest,
649           class Cast = detail::Map<Cast<Dest>>>
650 Cast eachAs() {
651   return Cast();
652 }
653
654 // call folly::to on each value
655 template <class Dest,
656           class To = detail::Map<To<Dest>>>
657 To eachTo() {
658   return To();
659 }
660
661 template<class Value>
662 detail::TypeAssertion<Value> assert_type() {
663   return {};
664 }
665
666 /*
667  * Sink Factories
668  */
669 template<class Seed,
670          class Fold,
671          class FoldLeft = detail::FoldLeft<Seed, Fold>>
672 FoldLeft foldl(Seed seed = Seed(),
673                Fold fold = Fold()) {
674   return FoldLeft(std::move(seed),
675                   std::move(fold));
676 }
677
678 template<class Reducer,
679          class Reduce = detail::Reduce<Reducer>>
680 Reduce reduce(Reducer reducer = Reducer()) {
681   return Reduce(std::move(reducer));
682 }
683
684 template<class Selector = Identity,
685          class Min = detail::Min<Selector, Less>>
686 Min minBy(Selector selector = Selector()) {
687   return Min(std::move(selector));
688 }
689
690 template<class Selector,
691          class MaxBy = detail::Min<Selector, Greater>>
692 MaxBy maxBy(Selector selector = Selector()) {
693   return MaxBy(std::move(selector));
694 }
695
696 template<class Collection,
697          class Collect = detail::Collect<Collection>>
698 Collect as() {
699   return Collect();
700 }
701
702 template<template<class, class> class Container = std::vector,
703          template<class> class Allocator = std::allocator,
704          class Collect = detail::CollectTemplate<Container, Allocator>>
705 Collect as() {
706   return Collect();
707 }
708
709 template<class Collection,
710          class Append = detail::Append<Collection>>
711 Append appendTo(Collection& collection) {
712   return Append(&collection);
713 }
714
715 template<class Needle,
716          class Contains = detail::Contains<typename std::decay<Needle>::type>>
717 Contains contains(Needle&& needle) {
718   return Contains(std::forward<Needle>(needle));
719 }
720
721 template<class Exception,
722          class ErrorHandler,
723          class GuardImpl =
724            detail::GuardImpl<
725              Exception,
726              typename std::decay<ErrorHandler>::type>>
727 GuardImpl guard(ErrorHandler&& handler) {
728   return GuardImpl(std::forward<ErrorHandler>(handler));
729 }
730
731 }} // folly::gen
732
733 #include <folly/gen/Base-inl.h>
734
735 #endif // FOLLY_GEN_BASE_H