/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef FOLLY_GEN_BASE_H
-#define FOLLY_GEN_BASE_H
+#pragma once
+#define FOLLY_GEN_BASE_H_
#include <algorithm>
#include <functional>
#include <folly/Conv.h>
#include <folly/Optional.h>
#include <folly/Range.h>
+#include <folly/Utility.h>
#include <folly/gen/Core.h>
/**
*
* To learn more about this library, including the use of infinite generators,
* see the examples in the comments, or the docs (coming soon).
-*/
+ */
-namespace folly { namespace gen {
+namespace folly {
+namespace gen {
class Less {
-public:
- template<class First,
- class Second>
+ public:
+ template <class First, class Second>
auto operator()(const First& first, const Second& second) const ->
decltype(first < second) {
return first < second;
};
class Greater {
-public:
- template<class First,
- class Second>
+ public:
+ template <class First, class Second>
auto operator()(const First& first, const Second& second) const ->
decltype(first > second) {
return first > second;
}
};
-template<int n>
+template <int n>
class Get {
-public:
- template<class Value>
+ public:
+ template <class Value>
auto operator()(Value&& value) const ->
decltype(std::get<n>(std::forward<Value>(value))) {
return std::get<n>(std::forward<Value>(value));
}
};
-template<class Class,
- class Result>
+template <class Class, class Result>
class MemberFunction {
public:
typedef Result (Class::*MemberPtr)();
}
};
-template<class Class,
- class Result>
+template <class Class, class Result>
class ConstMemberFunction{
public:
typedef Result (Class::*MemberPtr)() const;
}
};
-template<class Class,
- class FieldType>
+template <class Class, class FieldType>
class Field {
public:
typedef FieldType (Class::*FieldPtr);
};
class Move {
-public:
- template<class Value>
+ public:
+ template <class Value>
auto operator()(Value&& value) const ->
decltype(std::move(std::forward<Value>(value))) {
return std::move(std::forward<Value>(value));
}
};
-class Identity {
-public:
- template<class Value>
- auto operator()(Value&& value) const ->
- decltype(std::forward<Value>(value)) {
- return std::forward<Value>(value);
- }
-};
-
/**
* Class and helper function for negating a boolean Predicate
*/
}
};
-template<class Key, class Value>
+template <class Key, class Value>
class Group;
namespace detail {
-template<class Self>
+template <class Self>
struct FBounded;
/*
* Type Traits
*/
-template<class Container>
+template <class Container>
struct ValueTypeOfRange {
- private:
- static Container container_;
public:
- typedef decltype(*std::begin(container_))
- RefType;
- typedef typename std::decay<decltype(*std::begin(container_))>::type
- StorageType;
+ using RefType = decltype(*std::begin(std::declval<Container&>()));
+ using StorageType = typename std::decay<RefType>::type;
};
/*
* Sources
*/
-template<class Container,
- class Value = typename ValueTypeOfRange<Container>::RefType>
+template <
+ class Container,
+ class Value = typename ValueTypeOfRange<Container>::RefType>
class ReferencedSource;
-template<class Value,
- class Container = std::vector<typename std::decay<Value>::type>>
+template <
+ class Value,
+ class Container = std::vector<typename std::decay<Value>::type>>
class CopiedSource;
-template<class Value, class SequenceImpl>
+template <class Value, class SequenceImpl>
class Sequence;
template <class Value>
template <class Value>
class InfiniteImpl;
-template<class Value, class Source>
+template <class Value, class Source>
class Yield;
-template<class Value>
+template <class Value>
class Empty;
-template<class Value>
+template <class Value>
class SingleReference;
-template<class Value>
+template <class Value>
class SingleCopy;
/*
* Operators
*/
-template<class Predicate>
+template <class Predicate>
class Map;
-template<class Predicate>
+template <class Predicate>
class Filter;
-template<class Predicate>
+template <class Predicate>
class Until;
class Take;
class Stride;
-template<class Rand>
+template <class Rand>
class Sample;
class Skip;
-template<class Selector, class Comparer = Less>
+template <class Visitor>
+class Visit;
+
+template <class Selector, class Comparer = Less>
class Order;
-template<class Selector>
+template <class Selector>
class GroupBy;
-template<class Selector>
+template <class Selector>
class Distinct;
-template<class Operators>
+template <class Operators>
class Composer;
-template<class Expected>
+template <class Expected>
class TypeAssertion;
class Concat;
class Batch;
+class Window;
+
class Dereference;
class Indirect;
/*
* Sinks
*/
-template<class Seed,
- class Fold>
+template <class Seed, class Fold>
class FoldLeft;
class First;
template <bool result>
class IsEmpty;
-template<class Reducer>
+template <class Reducer>
class Reduce;
class Sum;
-template<class Selector,
- class Comparer>
+template <class Selector, class Comparer>
class Min;
-template<class Container>
+template <class Container>
class Collect;
-template<template<class, class> class Collection = std::vector,
- template<class> class Allocator = std::allocator>
+template <
+ template <class, class> class Collection = std::vector,
+ template <class> class Allocator = std::allocator>
class CollectTemplate;
-template<class Collection>
+template <class Collection>
class Append;
-template<class Value>
+template <class Value>
struct GeneratorBuilder;
-template<class Needle>
+template <class Needle>
class Contains;
-template<class Exception,
- class ErrorHandler>
+template <class Exception, class ErrorHandler>
class GuardImpl;
template <class T>
class Unwrap;
-}
+} // namespace detail
/**
* Polymorphic wrapper
**/
-template<class Value>
+template <class Value>
class VirtualGen;
/*
* Source Factories
*/
-template<class Container,
- class From = detail::ReferencedSource<const Container>>
+template <
+ class Container,
+ class From = detail::ReferencedSource<const Container>>
From fromConst(const Container& source) {
return From(&source);
}
-template<class Container,
- class From = detail::ReferencedSource<Container>>
+template <class Container, class From = detail::ReferencedSource<Container>>
From from(Container& source) {
return From(&source);
}
-template<class Container,
- class Value =
- typename detail::ValueTypeOfRange<Container>::StorageType,
- class CopyOf = detail::CopiedSource<Value>>
+template <
+ class Container,
+ class Value = typename detail::ValueTypeOfRange<Container>::StorageType,
+ class CopyOf = detail::CopiedSource<Value>>
CopyOf fromCopy(Container&& source) {
return CopyOf(std::forward<Container>(source));
}
-template<class Value,
- class From = detail::CopiedSource<Value>>
+template <class Value, class From = detail::CopiedSource<Value>>
From from(std::initializer_list<Value> source) {
return From(source);
}
-template<class Container,
- class From = detail::CopiedSource<typename Container::value_type,
- Container>>
+template <
+ class Container,
+ class From =
+ detail::CopiedSource<typename Container::value_type, Container>>
From from(Container&& source) {
return From(std::move(source));
}
-template<class Value, class Impl = detail::RangeImpl<Value>,
- class Gen = detail::Sequence<Value, Impl>>
+template <
+ class Value,
+ class Impl = detail::RangeImpl<Value>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen range(Value begin, Value end) {
return Gen{std::move(begin), Impl{std::move(end)}};
}
-template<class Value, class Distance,
- class Impl = detail::RangeWithStepImpl<Value, Distance>,
- class Gen = detail::Sequence<Value, Impl>>
+template <
+ class Value,
+ class Distance,
+ class Impl = detail::RangeWithStepImpl<Value, Distance>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen range(Value begin, Value end, Distance step) {
return Gen{std::move(begin), Impl{std::move(end), std::move(step)}};
}
-template<class Value, class Impl = detail::SeqImpl<Value>,
- class Gen = detail::Sequence<Value, Impl>>
+template <
+ class Value,
+ class Impl = detail::SeqImpl<Value>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen seq(Value first, Value last) {
return Gen{std::move(first), Impl{std::move(last)}};
}
-template<class Value, class Distance,
- class Impl = detail::SeqWithStepImpl<Value, Distance>,
- class Gen = detail::Sequence<Value, Impl>>
+template <
+ class Value,
+ class Distance,
+ class Impl = detail::SeqWithStepImpl<Value, Distance>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen seq(Value first, Value last, Distance step) {
return Gen{std::move(first), Impl{std::move(last), std::move(step)}};
}
-template<class Value, class Impl = detail::InfiniteImpl<Value>,
- class Gen = detail::Sequence<Value, Impl>>
+template <
+ class Value,
+ class Impl = detail::InfiniteImpl<Value>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen seq(Value first) {
return Gen{std::move(first), Impl{}};
}
-template<class Value,
- class Source,
- class Yield = detail::Yield<Value, Source>>
+template <class Value, class Source, class Yield = detail::Yield<Value, Source>>
Yield generator(Source&& source) {
return Yield(std::forward<Source>(source));
}
*
* auto gen = GENERATOR(int) { yield(1); yield(2); };
*/
-#define GENERATOR(TYPE) \
- ::folly::gen::detail::GeneratorBuilder<TYPE>() + \
- [=](const std::function<void(TYPE)>& yield)
+#define GENERATOR(TYPE) \
+ ::folly::gen::detail::GeneratorBuilder<TYPE>() + [=](auto&& yield)
/*
* empty() - for producing empty sequences.
/*
* Operator Factories
*/
-template<class Predicate,
- class Map = detail::Map<Predicate>>
+template <class Predicate, class Map = detail::Map<Predicate>>
Map mapped(Predicate pred = Predicate()) {
return Map(std::move(pred));
}
-template<class Predicate,
- class Map = detail::Map<Predicate>>
+template <class Predicate, class Map = detail::Map<Predicate>>
Map map(Predicate pred = Predicate()) {
return Map(std::move(pred));
}
* | mapOp(filter(sampleTest) | count)
* | sum;
*/
-template<class Operator,
- class Map = detail::Map<detail::Composer<Operator>>>
+template <class Operator, class Map = detail::Map<detail::Composer<Operator>>>
Map mapOp(Operator op) {
return Map(detail::Composer<Operator>(std::move(op)));
}
* assignment and comparisons don't work properly without being pulled out
* of the template declaration
*/
-template <MemberType Constness> struct ExprIsConst {
+template <MemberType Constness>
+struct ExprIsConst {
enum {
value = Constness == Const
};
};
-template <MemberType Constness> struct ExprIsMutable {
+template <MemberType Constness>
+struct ExprIsMutable {
enum {
value = Constness == Mutable
};
};
-template<MemberType Constness = Const,
- class Class,
- class Return,
- class Mem = ConstMemberFunction<Class, Return>,
- class Map = detail::Map<Mem>>
+template <
+ MemberType Constness = Const,
+ class Class,
+ class Return,
+ class Mem = ConstMemberFunction<Class, Return>,
+ class Map = detail::Map<Mem>>
typename std::enable_if<ExprIsConst<Constness>::value, Map>::type
member(Return (Class::*member)() const) {
return Map(Mem(member));
}
-template<MemberType Constness = Mutable,
- class Class,
- class Return,
- class Mem = MemberFunction<Class, Return>,
- class Map = detail::Map<Mem>>
+template <
+ MemberType Constness = Mutable,
+ class Class,
+ class Return,
+ class Mem = MemberFunction<Class, Return>,
+ class Map = detail::Map<Mem>>
typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type
member(Return (Class::*member)()) {
return Map(Mem(member));
* | field(&Item::name)
* | as<vector>();
*/
-template<class Class,
- class FieldType,
- class Field = Field<Class, FieldType>,
- class Map = detail::Map<Field>>
+template <
+ class Class,
+ class FieldType,
+ class Field = Field<Class, FieldType>,
+ class Map = detail::Map<Field>>
Map field(FieldType Class::*field) {
return Map(Field(field));
}
-template <class Predicate = Identity,
- class Filter = detail::Filter<Predicate>>
+template <class Predicate = Identity, class Filter = detail::Filter<Predicate>>
Filter filter(Predicate pred = Predicate()) {
return Filter(std::move(pred));
}
-template<class Predicate,
- class Until = detail::Until<Predicate>>
+template <class Visitor = Ignore, class Visit = detail::Visit<Visitor>>
+Visit visit(Visitor visitor = Visitor()) {
+ return Visit(std::move(visitor));
+}
+
+template <class Predicate, class Until = detail::Until<Predicate>>
Until until(Predicate pred = Predicate()) {
return Until(std::move(pred));
}
-template<class Selector = Identity,
- class Comparer = Less,
- class Order = detail::Order<Selector, Comparer>>
+template <
+ class Selector = Identity,
+ class Comparer = Less,
+ class Order = detail::Order<Selector, Comparer>>
Order orderBy(Selector selector = Selector(),
Comparer comparer = Comparer()) {
return Order(std::move(selector),
std::move(comparer));
}
-template<class Selector = Identity,
- class Order = detail::Order<Selector, Greater>>
+template <
+ class Selector = Identity,
+ class Order = detail::Order<Selector, Greater>>
Order orderByDescending(Selector selector = Selector()) {
return Order(std::move(selector));
}
-template <class Selector = Identity,
- class GroupBy = detail::GroupBy<Selector>>
+template <class Selector = Identity, class GroupBy = detail::GroupBy<Selector>>
GroupBy groupBy(Selector selector = Selector()) {
return GroupBy(std::move(selector));
}
-template<class Selector = Identity,
- class Distinct = detail::Distinct<Selector>>
+template <
+ class Selector = Identity,
+ class Distinct = detail::Distinct<Selector>>
Distinct distinctBy(Selector selector = Selector()) {
return Distinct(std::move(selector));
}
-template<int n,
- class Get = detail::Map<Get<n>>>
+template <int n, class Get = detail::Map<Get<n>>>
Get get() {
return Get();
}
// construct Dest from each value
-template <class Dest,
- class Cast = detail::Map<Cast<Dest>>>
+template <class Dest, class Cast = detail::Map<Cast<Dest>>>
Cast eachAs() {
return Cast();
}
// call folly::to on each value
-template <class Dest,
- class To = detail::Map<To<Dest>>>
+template <class Dest, class To = detail::Map<To<Dest>>>
To eachTo() {
return To();
}
-template<class Value>
+template <class Value>
detail::TypeAssertion<Value> assert_type() {
return {};
}
* from(source) | any(pred) == from(source) | filter(pred) | notEmpty
*/
-template <class Predicate = Identity,
- class Filter = detail::Filter<Predicate>,
- class NotEmpty = detail::IsEmpty<false>,
- class Composed = detail::Composed<Filter, NotEmpty>>
+template <
+ class Predicate = Identity,
+ class Filter = detail::Filter<Predicate>,
+ class NotEmpty = detail::IsEmpty<false>,
+ class Composed = detail::Composed<Filter, NotEmpty>>
Composed any(Predicate pred = Predicate()) {
return Composed(Filter(std::move(pred)), NotEmpty());
}
*
* from(source) | all(pred) == from(source) | filter(negate(pred)) | isEmpty
*/
-
-template <class Predicate = Identity,
- class Filter = detail::Filter<Negate<Predicate>>,
- class IsEmpty = detail::IsEmpty<true>,
- class Composed = detail::Composed<Filter, IsEmpty>>
+template <
+ class Predicate = Identity,
+ class Filter = detail::Filter<Negate<Predicate>>,
+ class IsEmpty = detail::IsEmpty<true>,
+ class Composed = detail::Composed<Filter, IsEmpty>>
Composed all(Predicate pred = Predicate()) {
return Composed(Filter(std::move(negate(pred))), IsEmpty());
}
-template<class Seed,
- class Fold,
- class FoldLeft = detail::FoldLeft<Seed, Fold>>
+template <class Seed, class Fold, class FoldLeft = detail::FoldLeft<Seed, Fold>>
FoldLeft foldl(Seed seed = Seed(),
Fold fold = Fold()) {
return FoldLeft(std::move(seed),
std::move(fold));
}
-template<class Reducer,
- class Reduce = detail::Reduce<Reducer>>
+template <class Reducer, class Reduce = detail::Reduce<Reducer>>
Reduce reduce(Reducer reducer = Reducer()) {
return Reduce(std::move(reducer));
}
-template<class Selector = Identity,
- class Min = detail::Min<Selector, Less>>
+template <class Selector = Identity, class Min = detail::Min<Selector, Less>>
Min minBy(Selector selector = Selector()) {
return Min(std::move(selector));
}
-template<class Selector,
- class MaxBy = detail::Min<Selector, Greater>>
+template <class Selector, class MaxBy = detail::Min<Selector, Greater>>
MaxBy maxBy(Selector selector = Selector()) {
return MaxBy(std::move(selector));
}
-template<class Collection,
- class Collect = detail::Collect<Collection>>
+template <class Collection, class Collect = detail::Collect<Collection>>
Collect as() {
return Collect();
}
-template<template<class, class> class Container = std::vector,
- template<class> class Allocator = std::allocator,
- class Collect = detail::CollectTemplate<Container, Allocator>>
+template <
+ template <class, class> class Container = std::vector,
+ template <class> class Allocator = std::allocator,
+ class Collect = detail::CollectTemplate<Container, Allocator>>
Collect as() {
return Collect();
}
-template<class Collection,
- class Append = detail::Append<Collection>>
+template <class Collection, class Append = detail::Append<Collection>>
Append appendTo(Collection& collection) {
return Append(&collection);
}
-template<class Needle,
- class Contains = detail::Contains<typename std::decay<Needle>::type>>
+template <
+ class Needle,
+ class Contains = detail::Contains<typename std::decay<Needle>::type>>
Contains contains(Needle&& needle) {
return Contains(std::forward<Needle>(needle));
}
-template<class Exception,
- class ErrorHandler,
- class GuardImpl =
- detail::GuardImpl<
- Exception,
- typename std::decay<ErrorHandler>::type>>
+template <
+ class Exception,
+ class ErrorHandler,
+ class GuardImpl =
+ detail::GuardImpl<Exception, typename std::decay<ErrorHandler>::type>>
GuardImpl guard(ErrorHandler&& handler) {
return GuardImpl(std::forward<ErrorHandler>(handler));
}
-template<class Fallback,
- class UnwrapOr = detail::UnwrapOr<typename std::decay<Fallback>::type>>
+template <
+ class Fallback,
+ class UnwrapOr = detail::UnwrapOr<typename std::decay<Fallback>::type>>
UnwrapOr unwrapOr(Fallback&& fallback) {
return UnwrapOr(std::forward<Fallback>(fallback));
}
-}} // folly::gen
+} // namespace gen
+} // namespace folly
#include <folly/gen/Base-inl.h>
-
-#endif // FOLLY_GEN_BASE_H