explicit instantiation of common Future types
[folly.git] / folly / futures / helpers.h
index 138cfd475c58c10941084e27a987864c442581cd..744a01aca40b6110cf8172bd54d10ae35b8ed052 100644 (file)
@@ -58,7 +58,8 @@ namespace futures {
    */
   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
@@ -130,8 +131,7 @@ Future<T> makeFuture(Try<T>&& t);
  *
  * @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
@@ -153,7 +153,7 @@ Future<std::vector<Try<
   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());
@@ -177,7 +177,7 @@ Future<typename detail::CollectContext<
 >::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());
@@ -195,7 +195,7 @@ Future<std::pair<
   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());
@@ -213,7 +213,7 @@ Future<std::vector<std::pair<
   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)) {
@@ -234,16 +234,19 @@ using isFutureResult = isFuture<typename std::result_of<F(T&&, Arg&&)>::type>;
 
     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