/*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <vector>
#include <unordered_set>
-#include "folly/Range.h"
-#include "folly/Optional.h"
-#include "folly/Conv.h"
-#include "folly/gen/Core.h"
+#include <folly/Range.h>
+#include <folly/Optional.h>
+#include <folly/Conv.h>
+#include <folly/gen/Core.h>
/**
* Generator-based Sequence Comprehensions in C++, akin to C#'s LINQ
Result operator()(Class& x) const {
return (x.*member_)();
}
+
+ Result operator()(Class* x) const {
+ return (x->*member_)();
+ }
};
template<class Class,
Result operator()(const Class& x) const {
return (x.*member_)();
}
+
+ Result operator()(const Class* x) const {
+ return (x->*member_)();
+ }
};
template<class Class,
return x.*field_;
}
+ const FieldType& operator()(const Class* x) const {
+ return x->*field_;
+ }
+
FieldType& operator()(Class& x) const {
return x.*field_;
}
+ FieldType& operator()(Class* x) const {
+ return x->*field_;
+ }
+
FieldType&& operator()(Class&& x) const {
return std::move(x.*field_);
}
class Container = std::vector<typename std::decay<Value>::type>>
class CopiedSource;
-template<class Value, bool endless = false, bool endInclusive = false>
+template<class Value, class SequenceImpl>
class Sequence;
+template <class Value>
+class RangeImpl;
+
+template <class Value, class Distance>
+class RangeWithStepImpl;
+
+template <class Value>
+class SeqImpl;
+
+template <class Value, class Distance>
+class SeqWithStepImpl;
+
+template <class Value>
+class InfiniteImpl;
+
template<class Value, class Source>
class Yield;
class Empty;
template<class Value>
-class Just;
+class SingleReference;
+
+template<class Value>
+class SingleCopy;
/*
* Operators
class Take;
+class Stride;
+
template<class Rand>
class Sample;
class Dereference;
+class Indirect;
+
/*
* Sinks
*/
return From(std::move(source));
}
-template<class Value, class Gen = detail::Sequence<Value, false, false>>
+template<class Value, class Impl = detail::RangeImpl<Value>,
+ class Gen = detail::Sequence<Value, Impl>>
Gen range(Value begin, Value end) {
- return Gen(begin, end);
+ return Gen{std::move(begin), Impl{std::move(end)}};
}
-template<class Value,
- class Gen = detail::Sequence<Value, false, true>>
+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>>
Gen seq(Value first, Value last) {
- return Gen(first, last);
+ return Gen{std::move(first), Impl{std::move(last)}};
}
-template<class Value,
- class Gen = detail::Sequence<Value, true>>
-Gen seq(Value begin) {
- return Gen(begin);
+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>>
+Gen seq(Value first) {
+ return Gen{std::move(first), Impl{}};
}
template<class Value,
/*
* empty() - for producing empty sequences.
*/
-template<class Value>
+template <class Value>
detail::Empty<Value> empty() {
return {};
}
-template<class Value>
-detail::Just<Value> just(Value value) {
- return detail::Just<Value>(std::move(value));
+template <
+ class Value,
+ class Just = typename std::conditional<
+ std::is_reference<Value>::value,
+ detail::SingleReference<typename std::remove_reference<Value>::type>,
+ detail::SingleCopy<Value>>::type>
+Just just(Value&& value) {
+ return Just(std::forward<Value>(value));
}
/*
Mutable
};
+/**
+ * These exist because MSVC has problems with expression SFINAE in templates
+ * assignment and comparisons don't work properly without being pulled out
+ * of the template declaration
+ */
+template <MemberType Constness> struct ExprIsConst {
+ enum {
+ value = Constness == Const
+ };
+};
+
+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>>
-typename std::enable_if<Constness == Const, Map>::type
+typename std::enable_if<ExprIsConst<Constness>::value, Map>::type
member(Return (Class::*member)() const) {
return Map(Mem(member));
}
class Return,
class Mem = MemberFunction<Class, Return>,
class Map = detail::Map<Mem>>
-typename std::enable_if<Constness == Mutable, Map>::type
+typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type
member(Return (Class::*member)()) {
return Map(Mem(member));
}
return Until(std::move(pred));
}
-template<class Selector,
+template<class Selector = Identity,
class Comparer = Less,
class Order = detail::Order<Selector, Comparer>>
-Order orderBy(Selector selector = Identity(),
+Order orderBy(Selector selector = Selector(),
Comparer comparer = Comparer()) {
return Order(std::move(selector),
std::move(comparer));
}
-template<class Selector,
+template<class Selector = Identity,
class Order = detail::Order<Selector, Greater>>
-Order orderByDescending(Selector selector = Identity()) {
+Order orderByDescending(Selector selector = Selector()) {
return Order(std::move(selector));
}
-template<class Selector,
+template<class Selector = Identity,
class Distinct = detail::Distinct<Selector>>
-Distinct distinctBy(Selector selector = Identity()) {
+Distinct distinctBy(Selector selector = Selector()) {
return Distinct(std::move(selector));
}
}} // folly::gen
-#include "folly/gen/Base-inl.h"
+#include <folly/gen/Base-inl.h>
#endif // FOLLY_GEN_BASE_H