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