return f;
}
+template <class T>
+template <class F>
+Future<T> Future<T>::ensure(F func) {
+ MoveWrapper<F> funcw(std::move(func));
+ return this->then([funcw](Try<T>&& t) {
+ (*funcw)();
+ return makeFuture(std::move(t));
+ });
+}
+
template <class T>
template <class F>
Future<T> Future<T>::onTimeout(Duration dur, F&& func, Timekeeper* tk) {
Future<T>>::type
onError(F&& func);
+ /// func is like std::function<void()> and is executed unconditionally, and
+ /// the value/exception is passed through to the resulting Future.
+ /// func shouldn't throw, but if it does it will be captured and propagated,
+ /// and discard any value/exception that this Future has obtained.
+ template <class F>
+ Future<T> ensure(F func);
+
/// Like onError, but for timeouts. example:
///
/// Future<int> f = makeFuture<int>(42)
ASSERT_TRUE(!!val);
EXPECT_EQ(42, *val);
}
+
+TEST(Future, ensure) {
+ size_t count = 0;
+ auto cob = [&]{ count++; };
+ auto f = makeFuture(42)
+ .ensure(cob)
+ .then([](int) { throw std::runtime_error("ensure"); })
+ .ensure(cob);
+
+ EXPECT_THROW(f.get(), std::runtime_error);
+ EXPECT_EQ(2, count);
+}