*/
template <class It, class F,
class ItT = typename std::iterator_traits<It>::value_type,
- class Result = decltype(std::declval<ItT>().then(std::declval<F>()))>
+ class Result
+ = typename decltype(std::declval<ItT>().then(std::declval<F>()))::value_type>
std::vector<Future<Result>> map(It first, It last, F func);
// Sugar for the most common case
*
* @returns a void Future that will call back on the given executor
*/
-template <typename Executor>
-Future<void> via(Executor* executor);
+inline Future<void> via(Executor* executor);
/** When all the input Futures complete, the returned Future will complete.
Errors do not cause early termination; this Future will always succeed
typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAll(InputIterator first, InputIterator last);
-// Sugar for the most common case
+/// Sugar for the most common case
template <class Collection>
auto collectAll(Collection&& c) -> decltype(collectAll(c.begin(), c.end())) {
return collectAll(c.begin(), c.end());
>::result_type>
collect(InputIterator first, InputIterator last);
-// Sugar for the most common case
+/// Sugar for the most common case
template <class Collection>
auto collect(Collection&& c) -> decltype(collect(c.begin(), c.end())) {
return collect(c.begin(), c.end());
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAny(InputIterator first, InputIterator last);
-// Sugar for the most common case
+/// Sugar for the most common case
template <class Collection>
auto collectAny(Collection&& c) -> decltype(collectAny(c.begin(), c.end())) {
return collectAny(c.begin(), c.end());
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
collectN(InputIterator first, InputIterator last, size_t n);
-// Sugar for the most common case
+/// Sugar for the most common case
template <class Collection>
auto collectN(Collection&& c, size_t n)
-> decltype(collectN(c.begin(), c.end(), n)) {
Func can either return a T, or a Future<T>
*/
-template <class It, class T, class F,
- class ItT = typename std::iterator_traits<It>::value_type::value_type,
- class Arg = MaybeTryArg<F, T, ItT>>
-typename std::enable_if<!isFutureResult<F, T, Arg>::value, Future<T>>::type
-reduce(It first, It last, T initial, F func);
-
-template <class It, class T, class F,
- class ItT = typename std::iterator_traits<It>::value_type::value_type,
- class Arg = MaybeTryArg<F, T, ItT>>
-typename std::enable_if<isFutureResult<F, T, Arg>::value, Future<T>>::type
-reduce(It first, It last, T initial, F func);
+template <class It, class T, class F>
+Future<T> reduce(It first, It last, T&& initial, F&& func);
+
+/// Sugar for the most common case
+template <class Collection, class T, class F>
+auto reduce(Collection&& c, T&& initial, F&& func)
+ -> decltype(reduce(c.begin(), c.end(), std::forward<T>(initial),
+ std::forward<F>(func))) {
+ return reduce(
+ c.begin(),
+ c.end(),
+ std::forward<T>(initial),
+ std::forward<F>(func));
+}
} // namespace folly