map()
authorJames Sedgwick <jsedgwick@fb.com>
Tue, 21 Apr 2015 21:08:44 +0000 (14:08 -0700)
committerAlecs King <int@fb.com>
Mon, 27 Apr 2015 23:48:04 +0000 (16:48 -0700)
Summary:
simple sugary syrup, best used in conjunction with collect/whenAll

Test Plan: unit

Reviewed By: hans@fb.com

Subscribers: trunkagent, folly-diffs@, jsedgwick, yfeldblum, chalfant, cgthayer

FB internal diff: D1999047

Tasks: 6045623

Signature: t1:1999047:1429570631:62361bb43dc5489fe3d4eb31af404faf8a765402

folly/futures/Future-inl.h
folly/futures/Future.h
folly/futures/test/FutureTest.cpp

index 7a2ffc2b3263351118babc339109faff788af01a..ea8368e8dee19d6bde59e9f066516e864afed4f3 100644 (file)
@@ -1018,6 +1018,14 @@ namespace futures {
     };
   }
 
+  template <class It, class F, class ItT, class Result>
+  std::vector<Future<Result>> map(It first, It last, F func) {
+    std::vector<Future<Result>> results;
+    for (auto it = first; it != last; it++) {
+      results.push_back(it->then(func));
+    }
+    return results;
+  }
 }
 
 } // namespace folly
index 90207dd8a1000a807b9a18a9ba99b1d17d2a2934..26555753ad361394a74188e98ccfb76e1fc3564d 100644 (file)
@@ -181,6 +181,16 @@ namespace futures {
   template <class A, class Z, class... Callbacks>
   std::function<Future<Z>(Try<A>)>
   chain(Callbacks... fns);
+
+  /**
+   * Set func as the callback for each input Future and return a vector of
+   * Futures containing the results in the input order.
+   */
+  template <class It, class F,
+            class ItT = typename std::iterator_traits<It>::value_type,
+            class Result = decltype(std::declval<ItT>().then(std::declval<F>()))>
+  std::vector<Future<Result>> map(It first, It last, F func);
+
 }
 
 template <class T>
index 82ac1f175caf1dc38350273b5471587eb8780f3a..8efa6c64baf8d91e829357944248e7eb0b4ad3af 100644 (file)
@@ -1707,3 +1707,29 @@ TEST(Reduce, Basic) {
     EXPECT_EQ(6.3, f2.get());
   }
 }
+
+TEST(Map, Basic) {
+  Promise<int> p1;
+  Promise<int> p2;
+  Promise<int> p3;
+
+  std::vector<Future<int>> fs;
+  fs.push_back(p1.getFuture());
+  fs.push_back(p2.getFuture());
+  fs.push_back(p3.getFuture());
+
+  int c = 0;
+  auto fs2 = futures::map(fs.begin(), fs.end(), [&](int i){
+    c += i;
+  });
+
+  // Ensure we call the callbacks as the futures complete regardless of order
+  p2.setValue(1);
+  EXPECT_EQ(1, c);
+  p3.setValue(1);
+  EXPECT_EQ(2, c);
+  p1.setValue(1);
+  EXPECT_EQ(3, c);
+
+  EXPECT_TRUE(collect(fs2.begin(), fs2.end()).isReady());
+}