Versioning for Thrift, remove thrift/lib/cpp/config.h
[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 /**
541  * These exist because MSVC has problems with expression SFINAE in templates
542  * assignment and comparisons don't work properly without being pulled out
543  * of the template declaration
544  */
545 template <MemberType Constness> struct ExprIsConst {
546   enum {
547     value = Constness == Const
548   };
549 };
550
551 template <MemberType Constness> struct ExprIsMutable {
552   enum {
553     value = Constness == Mutable
554   };
555 };
556
557 template<MemberType Constness = Const,
558          class Class,
559          class Return,
560          class Mem = ConstMemberFunction<Class, Return>,
561          class Map = detail::Map<Mem>>
562 typename std::enable_if<ExprIsConst<Constness>::value, Map>::type
563 member(Return (Class::*member)() const) {
564   return Map(Mem(member));
565 }
566
567 template<MemberType Constness = Mutable,
568          class Class,
569          class Return,
570          class Mem = MemberFunction<Class, Return>,
571          class Map = detail::Map<Mem>>
572 typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type
573 member(Return (Class::*member)()) {
574   return Map(Mem(member));
575 }
576
577 /*
578  * field(...) - For extracting a field from each value.
579  *
580  *  vector<Item> items = ...;
581  *  auto names = from(items) | field(&Item::name);
582  *
583  * Note that if the values of the generator are rvalues, any non-reference
584  * fields will be rvalues as well. As an example, the code below does not copy
585  * any strings, only moves them:
586  *
587  *  auto namesVector = from(items)
588  *                   | move
589  *                   | field(&Item::name)
590  *                   | as<vector>();
591  */
592 template<class Class,
593          class FieldType,
594          class Field = Field<Class, FieldType>,
595          class Map = detail::Map<Field>>
596 Map field(FieldType Class::*field) {
597   return Map(Field(field));
598 }
599
600 template<class Predicate,
601          class Filter = detail::Filter<Predicate>>
602 Filter filter(Predicate pred = Predicate()) {
603   return Filter(std::move(pred));
604 }
605
606 template<class Predicate,
607          class All = detail::All<Predicate>>
608 All all(Predicate pred = Predicate()) {
609   return All(std::move(pred));
610 }
611
612 template<class Predicate,
613          class Until = detail::Until<Predicate>>
614 Until until(Predicate pred = Predicate()) {
615   return Until(std::move(pred));
616 }
617
618 template<class Selector,
619          class Comparer = Less,
620          class Order = detail::Order<Selector, Comparer>>
621 Order orderBy(Selector selector = Identity(),
622               Comparer comparer = Comparer()) {
623   return Order(std::move(selector),
624                std::move(comparer));
625 }
626
627 template<class Selector,
628          class Order = detail::Order<Selector, Greater>>
629 Order orderByDescending(Selector selector = Identity()) {
630   return Order(std::move(selector));
631 }
632
633 template<class Selector,
634          class Distinct = detail::Distinct<Selector>>
635 Distinct distinctBy(Selector selector = Identity()) {
636   return Distinct(std::move(selector));
637 }
638
639 template<int n,
640          class Get = detail::Map<Get<n>>>
641 Get get() {
642   return Get();
643 }
644
645 // construct Dest from each value
646 template <class Dest,
647           class Cast = detail::Map<Cast<Dest>>>
648 Cast eachAs() {
649   return Cast();
650 }
651
652 // call folly::to on each value
653 template <class Dest,
654           class To = detail::Map<To<Dest>>>
655 To eachTo() {
656   return To();
657 }
658
659 template<class Value>
660 detail::TypeAssertion<Value> assert_type() {
661   return {};
662 }
663
664 /*
665  * Sink Factories
666  */
667 template<class Seed,
668          class Fold,
669          class FoldLeft = detail::FoldLeft<Seed, Fold>>
670 FoldLeft foldl(Seed seed = Seed(),
671                Fold fold = Fold()) {
672   return FoldLeft(std::move(seed),
673                   std::move(fold));
674 }
675
676 template<class Reducer,
677          class Reduce = detail::Reduce<Reducer>>
678 Reduce reduce(Reducer reducer = Reducer()) {
679   return Reduce(std::move(reducer));
680 }
681
682 template<class Selector = Identity,
683          class Min = detail::Min<Selector, Less>>
684 Min minBy(Selector selector = Selector()) {
685   return Min(std::move(selector));
686 }
687
688 template<class Selector,
689          class MaxBy = detail::Min<Selector, Greater>>
690 MaxBy maxBy(Selector selector = Selector()) {
691   return MaxBy(std::move(selector));
692 }
693
694 template<class Collection,
695          class Collect = detail::Collect<Collection>>
696 Collect as() {
697   return Collect();
698 }
699
700 template<template<class, class> class Container = std::vector,
701          template<class> class Allocator = std::allocator,
702          class Collect = detail::CollectTemplate<Container, Allocator>>
703 Collect as() {
704   return Collect();
705 }
706
707 template<class Collection,
708          class Append = detail::Append<Collection>>
709 Append appendTo(Collection& collection) {
710   return Append(&collection);
711 }
712
713 template<class Needle,
714          class Contains = detail::Contains<typename std::decay<Needle>::type>>
715 Contains contains(Needle&& needle) {
716   return Contains(std::forward<Needle>(needle));
717 }
718
719 template<class Exception,
720          class ErrorHandler,
721          class GuardImpl =
722            detail::GuardImpl<
723              Exception,
724              typename std::decay<ErrorHandler>::type>>
725 GuardImpl guard(ErrorHandler&& handler) {
726   return GuardImpl(std::forward<ErrorHandler>(handler));
727 }
728
729 }} // folly::gen
730
731 #include <folly/gen/Base-inl.h>
732
733 #endif // FOLLY_GEN_BASE_H