#error This file may only be included from folly/gen/Base.h
#endif
+#include <folly/Portability.h>
+
// Ignore shadowing warnings within this file, so includers can use -Wshadow.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
+FOLLY_PUSH_WARNING
+FOLLY_GCC_DISABLE_WARNING("-Wshadow")
namespace folly {
namespace gen {
**/
template <class Value>
struct GeneratorBuilder {
- template <class Source,
- class Yield = detail::Yield<Value, Source>>
+ template <class Source, class Yield = detail::Yield<Value, Source>>
Yield operator+(Source&& source) {
return Yield(std::forward<Source>(source));
}
*
* This type is usually used through the 'map' or 'mapped' helper function:
*
- * auto squares = seq(1, 10) | map(square) | asVector;
+ * auto squares = seq(1, 10) | map(square) | as<std::vector>();
*/
template <class Predicate>
class Map : public Operator<Map<Predicate>> {
explicit Map(Predicate pred) : pred_(std::move(pred)) {}
- template <class Value,
- class Source,
- class Result = typename ArgumentReference<
- typename std::result_of<Predicate(Value)>::type>::type>
+ template <
+ class Value,
+ class Source,
+ class Result = typename ArgumentReference<
+ typename std::result_of<Predicate(Value)>::type>::type>
class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
Source source_;
Predicate pred_;
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), pred_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), pred_);
}
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), pred_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), pred_);
}
*
* auto best = from(sortedItems)
* | until([](Item& item) { return item.score > 100; })
- * | asVector;
+ * | as<std::vector>();
*/
template <class Predicate>
class Until : public Operator<Until<Predicate>> {
static constexpr bool infinite = false;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), pred_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), pred_);
}
static constexpr bool infinite = false;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), count_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), count_);
}
};
+/**
+ * Visit - For calling a function on each item before passing it down the
+ * pipeline.
+ *
+ * This type is usually used through the 'visit' helper function:
+ *
+ * auto printedValues = seq(1) | visit(debugPrint);
+ * // nothing printed yet
+ * auto results = take(10) | as<std::vector>();
+ * // results now populated, 10 values printed
+ */
+template <class Visitor>
+class Visit : public Operator<Visit<Visitor>> {
+ Visitor visitor_;
+
+ public:
+ Visit() = default;
+
+ explicit Visit(Visitor visitor) : visitor_(std::move(visitor)) {}
+
+ template <class Value, class Source>
+ class Generator : public GenImpl<Value, Generator<Value, Source>> {
+ Source source_;
+ Visitor visitor_;
+
+ public:
+ explicit Generator(Source source, const Visitor& visitor)
+ : source_(std::move(source)), visitor_(visitor) {}
+
+ template <class Body>
+ void foreach(Body&& body) const {
+ source_.foreach([&](Value value) {
+ visitor_(value); // not forwarding to avoid accidental moves
+ body(std::forward<Value>(value));
+ });
+ }
+
+ template <class Handler>
+ bool apply(Handler&& handler) const {
+ return source_.apply([&](Value value) {
+ visitor_(value); // not forwarding to avoid accidental moves
+ return handler(std::forward<Value>(value));
+ });
+ }
+
+ static constexpr bool infinite = Source::infinite;
+ };
+
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
+ Gen compose(GenImpl<Value, Source>&& source) const {
+ return Gen(std::move(source.self()), visitor_);
+ }
+
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
+ Gen compose(const GenImpl<Value, Source>& source) const {
+ return Gen(source.self(), visitor_);
+ }
+};
+
/**
* Stride - For producing every Nth value from a source.
*
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), stride_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), stride_);
}
explicit Sample(size_t count, Random rng)
: count_(count), rng_(std::move(rng)) {}
- template <class Value,
- class Source,
- class Rand,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Value,
+ class Source,
+ class Rand,
+ class StorageType = typename std::decay<Value>::type>
class Generator
: public GenImpl<StorageType&&,
Generator<Value, Source, Rand, StorageType>> {
static constexpr bool infinite = false;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source, Random>>
+ template <
+ class Source,
+ class Value,
+ class Gen = Generator<Value, Source, Random>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), count_, rng_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source, Random>>
+ template <
+ class Source,
+ class Value,
+ class Gen = Generator<Value, Source, Random>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), count_, rng_);
}
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), count_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), count_);
}
Order(Selector selector, Comparer comparer)
: selector_(std::move(selector)), comparer_(std::move(comparer)) {}
- template <class Value,
- class Source,
- class StorageType = typename std::decay<Value>::type,
- class Result = typename std::result_of<Selector(Value)>::type>
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type,
+ class Result = typename std::result_of<Selector(Value)>::type>
class Generator
: public GenImpl<StorageType&&,
Generator<Value, Source, StorageType, Result>> {
static constexpr bool infinite = false;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), selector_, comparer_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), selector_, comparer_);
}
explicit GroupBy(Selector selector) : selector_(std::move(selector)) {}
- template <class Value,
- class Source,
- class ValueDecayed = typename std::decay<Value>::type,
- class Key = typename std::result_of<Selector(Value)>::type,
- class KeyDecayed = typename std::decay<Key>::type>
+ template <
+ class Value,
+ class Source,
+ class ValueDecayed = typename std::decay<Value>::type,
+ class Key = typename std::result_of<Selector(Value)>::type,
+ class KeyDecayed = typename std::decay<Key>::type>
class Generator
: public GenImpl<
Group<KeyDecayed, ValueDecayed>&&,
static constexpr bool infinite = false;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), selector_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), selector_);
}
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), selector_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), selector_);
}
public:
explicit Composer(Operators op) : op_(std::move(op)) {}
- template <class Source,
- class Ret = decltype(
- std::declval<Operators>().compose(std::declval<Source>()))>
+ template <
+ class Source,
+ class Ret =
+ decltype(std::declval<Operators>().compose(std::declval<Source>()))>
Ret operator()(Source&& source) const {
return op_.compose(std::forward<Source>(source));
}
}
}
- template <class Value,
- class Source,
- class StorageType = typename std::decay<Value>::type,
- class VectorType = std::vector<StorageType>>
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type,
+ class VectorType = std::vector<StorageType>>
class Generator
: public GenImpl<VectorType&,
Generator<Value, Source, StorageType, VectorType>> {
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), batchSize_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), batchSize_);
}
};
+/**
+ * Window - For overlapping the lifetimes of pipeline values, especially with
+ * Futures.
+ *
+ * This type is usually used through the 'window' helper function:
+ *
+ * auto responses
+ * = byLine(STDIN)
+ * | map(makeRequestFuture)
+ * | window(1000)
+ * | map(waitFuture)
+ * | as<vector>();
+ */
+class Window : public Operator<Window> {
+ size_t windowSize_;
+
+ public:
+ explicit Window(size_t windowSize) : windowSize_(windowSize) {
+ if (windowSize_ == 0) {
+ throw std::invalid_argument("Window size must be non-zero!");
+ }
+ }
+
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type>
+ class Generator
+ : public GenImpl<StorageType&&, Generator<Value, Source, StorageType>> {
+ Source source_;
+ size_t windowSize_;
+
+ public:
+ explicit Generator(Source source, size_t windowSize)
+ : source_(std::move(source)), windowSize_(windowSize) {}
+
+ template <class Handler>
+ bool apply(Handler&& handler) const {
+ std::vector<StorageType> buffer;
+ buffer.reserve(windowSize_);
+ size_t readIndex = 0;
+ bool shouldContinue = source_.apply([&](Value value) -> bool {
+ if (buffer.size() < windowSize_) {
+ buffer.push_back(std::forward<Value>(value));
+ } else {
+ StorageType& entry = buffer[readIndex++];
+ if (readIndex == windowSize_) {
+ readIndex = 0;
+ }
+ if (!handler(std::move(entry))) {
+ return false;
+ }
+ entry = std::forward<Value>(value);
+ }
+ return true;
+ });
+ if (!shouldContinue) {
+ return false;
+ }
+ if (buffer.size() < windowSize_) {
+ for (StorageType& entry : buffer) {
+ if (!handler(std::move(entry))) {
+ return false;
+ }
+ }
+ } else {
+ for (size_t i = readIndex;;) {
+ StorageType& entry = buffer[i++];
+ if (!handler(std::move(entry))) {
+ return false;
+ }
+ if (i == windowSize_) {
+ i = 0;
+ }
+ if (i == readIndex) {
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ // Taking n-tuples of an infinite source is still infinite
+ static constexpr bool infinite = Source::infinite;
+ };
+
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
+ Gen compose(GenImpl<Value, Source>&& source) const {
+ return Gen(std::move(source.self()), windowSize_);
+ }
+
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
+ Gen compose(const GenImpl<Value, Source>& source) const {
+ return Gen(source.self(), windowSize_);
+ }
+};
+
/**
* Concat - For flattening generators of generators.
*
public:
Concat() = default;
- template <class Inner,
- class Source,
- class InnerValue = typename std::decay<Inner>::type::ValueType>
+ template <
+ class Inner,
+ class Source,
+ class InnerValue = typename std::decay<Inner>::type::ValueType>
class Generator
: public GenImpl<InnerValue, Generator<Inner, Source, InnerValue>> {
Source source_;
Source::infinite || std::decay<Inner>::type::infinite;
};
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()));
}
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self());
}
public:
RangeConcat() = default;
- template <class Range,
- class Source,
- class InnerValue = typename ValueTypeOfRange<Range>::RefType>
+ template <
+ class Range,
+ class Source,
+ class InnerValue = typename ValueTypeOfRange<Range>::RefType>
class Generator
: public GenImpl<InnerValue, Generator<Range, Source, InnerValue>> {
Source source_;
static constexpr bool infinite = Source::infinite;
};
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()));
}
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self());
}
static constexpr bool infinite = Source::infinite;
};
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), handler_);
}
- template <class Value,
- class Source,
- class Gen = Generator<Value, Source>>
+ template <class Value, class Source, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), handler_);
}
public:
Dereference() = default;
- template <class Value,
- class Source,
- class Result = decltype(*std::declval<Value>())>
+ template <
+ class Value,
+ class Source,
+ class Result = decltype(*std::declval<Value>())>
class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
Source source_;
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()));
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self());
}
public:
Indirect() = default;
- template <class Value,
- class Source,
- class Result = typename std::remove_reference<Value>::type*>
+ template <
+ class Value,
+ class Source,
+ class Result = typename std::remove_reference<Value>::type*>
class Generator : public GenImpl<Result, Generator<Value, Source, Result>> {
Source source_;
static_assert(!std::is_rvalue_reference<Value>::value,
static constexpr bool infinite = Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()));
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self());
}
static constexpr bool infinite = forever || Source::infinite;
};
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
return Gen(std::move(source.self()), limit_);
}
- template <class Source,
- class Value,
- class Gen = Generator<Value, Source>>
+ template <class Source, class Value, class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), limit_);
}
public:
First() = default;
- template <class Source,
- class Value,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Source,
+ class Value,
+ class StorageType = typename std::decay<Value>::type>
Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
Optional<StorageType> accum;
source | [&](Value v) -> bool {
Reduce() = default;
explicit Reduce(Reducer reducer) : reducer_(std::move(reducer)) {}
- template <class Source,
- class Value,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Source,
+ class Value,
+ class StorageType = typename std::decay<Value>::type>
Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite, "Cannot reduce infinite source");
Optional<StorageType> accum;
public:
Sum() = default;
- template <class Source,
- class Value,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Source,
+ class Value,
+ class StorageType = typename std::decay<Value>::type>
StorageType compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite, "Cannot sum infinite source");
return foldl(StorageType(0),
public:
explicit Contains(Needle needle) : needle_(std::move(needle)) {}
- template <class Source,
- class Value,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Source,
+ class Value,
+ class StorageType = typename std::decay<Value>::type>
bool compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite,
"Calling contains on an infinite source might cause "
Min(Selector selector, Comparer comparer)
: selector_(std::move(selector)), comparer_(std::move(comparer)) {}
- template <class Value,
- class Source,
- class StorageType = typename std::decay<Value>::type,
- class Key = typename std::decay<
- typename std::result_of<Selector(Value)>::type>::type>
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type,
+ class Key = typename std::decay<
+ typename std::result_of<Selector(Value)>::type>::type>
Optional<StorageType> compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite,
"Calling min or max on an infinite source will cause "
public:
Collect() = default;
- template <class Value,
- class Source,
- class StorageType = typename std::decay<Value>::type>
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type>
Collection compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite,
"Cannot convert infinite source to object with as.");
*
* set<string> uniqueNames = from(names) | as<set>();
*/
-template <template <class, class> class Container,
- template <class> class Allocator>
+template <
+ template <class, class> class Container,
+ template <class> class Allocator>
class CollectTemplate : public Operator<CollectTemplate<Container, Allocator>> {
public:
CollectTemplate() = default;
- template <class Value,
- class Source,
- class StorageType = typename std::decay<Value>::type,
- class Collection = Container<StorageType, Allocator<StorageType>>>
+ template <
+ class Value,
+ class Source,
+ class StorageType = typename std::decay<Value>::type,
+ class Collection = Container<StorageType, Allocator<StorageType>>>
Collection compose(const GenImpl<Value, Source>& source) const {
static_assert(!Source::infinite,
"Cannot convert infinite source to object with as.");
}
// Mixed type unwrapping always returns values, moving where possible
-template <class T,
- class U,
- class R = typename std::enable_if<
- !std::is_same<T, U>::value,
- typename std::common_type<T, U>::type>::type>
+template <
+ class T,
+ class U,
+ class R = typename std::enable_if<
+ !std::is_same<T, U>::value,
+ typename std::common_type<T, U>::type>::type>
R operator|(Optional<T>&& opt, UnwrapOr<U>&& fallback) {
if (T* p = opt.get_pointer()) {
return std::move(*p);
return std::move(fallback.value());
}
-template <class T,
- class U,
- class R = typename std::enable_if<
- !std::is_same<T, U>::value,
- typename std::common_type<T, U>::type>::type>
+template <
+ class T,
+ class U,
+ class R = typename std::enable_if<
+ !std::is_same<T, U>::value,
+ typename std::common_type<T, U>::type>::type>
R operator|(const Optional<T>& opt, UnwrapOr<U>&& fallback) {
if (const T* p = opt.get_pointer()) {
return *p;
return std::move(fallback.value());
}
-template <class T,
- class U,
- class R = typename std::enable_if<
- !std::is_same<T, U>::value,
- typename std::common_type<T, U>::type>::type>
+template <
+ class T,
+ class U,
+ class R = typename std::enable_if<
+ !std::is_same<T, U>::value,
+ typename std::common_type<T, U>::type>::type>
R operator|(Optional<T>&& opt, const UnwrapOr<U>& fallback) {
if (T* p = opt.get_pointer()) {
return std::move(*p);
return fallback.value();
}
-template <class T,
- class U,
- class R = typename std::enable_if<
- !std::is_same<T, U>::value,
- typename std::common_type<T, U>::type>::type>
+template <
+ class T,
+ class U,
+ class R = typename std::enable_if<
+ !std::is_same<T, U>::value,
+ typename std::common_type<T, U>::type>::type>
R operator|(const Optional<T>& opt, const UnwrapOr<U>& fallback) {
if (const T* p = opt.get_pointer()) {
return *p;
return opt.value();
}
-} //::detail
+} // namespace detail
/**
* VirtualGen<T> - For wrapping template types in simple polymorphic wrapper.
inline detail::Batch batch(size_t batchSize) {
return detail::Batch(batchSize);
}
-} // gen
-} // folly
-#pragma GCC diagnostic pop
+inline detail::Window window(size_t windowSize) {
+ return detail::Window(windowSize);
+}
+
+} // namespace gen
+} // namespace folly
+
+FOLLY_POP_WARNING