Commit 3222b57b authored by Lee Howes's avatar Lee Howes Committed by Facebook Github Bot

Remove dependncy on value-taking form of then from folly

Summary: Remove uses of folly::Future::then(task-taking-value) from folly and replace with thenValue.

Reviewed By: yfeldblum

Differential Revision: D13115197

fbshipit-source-id: 3843ec2412a0dfc0c2ee7940ff7e17320215ff72
parent 6ec1462b
......@@ -1705,7 +1705,7 @@ void doubleBatchOuterDispatch(
innerDispatchResultFutures.begin(),
innerDispatchResultFutures.end())
.toUnsafeFuture()
.then([&](std::vector<Try<std::vector<std::string>>>
.thenValue([&](std::vector<Try<std::vector<std::string>>>
innerDispatchResults) {
for (auto& unit : innerDispatchResults) {
for (auto& element : unit.value()) {
......
......@@ -84,21 +84,21 @@ void retryingImpl(size_t k, Policy&& p, FF&& ff, Prom prom) {
using F = invoke_result_t<FF, size_t>;
using T = typename F::value_type;
auto f = makeFutureWith([&] { return ff(k++); });
std::move(f).then([k,
prom = std::move(prom),
pm = std::forward<Policy>(p),
ffm = std::forward<FF>(ff)](Try<T>&& t) mutable {
std::move(f).thenTry([k,
prom = std::move(prom),
pm = std::forward<Policy>(p),
ffm = std::forward<FF>(ff)](Try<T>&& t) mutable {
if (t.hasValue()) {
prom.setValue(std::move(t).value());
return;
}
auto& x = t.exception();
auto q = makeFutureWith([&] { return pm(k, x); });
std::move(q).then([k,
prom = std::move(prom),
xm = std::move(x),
pm = std::move(pm),
ffm = std::move(ffm)](Try<bool> shouldRetry) mutable {
std::move(q).thenTry([k,
prom = std::move(prom),
xm = std::move(x),
pm = std::move(pm),
ffm = std::move(ffm)](Try<bool> shouldRetry) mutable {
if (shouldRetry.hasValue() && shouldRetry.value()) {
retryingImpl(k, std::move(pm), std::move(ffm), std::move(prom));
} else if (shouldRetry.hasValue()) {
......@@ -173,7 +173,7 @@ retryingPolicyCappedJitteredExponentialBackoff(
if (n == max_tries) {
return makeFuture(false);
}
return pm(n, ex).then(
return pm(n, ex).thenValue(
[n, backoff_min, backoff_max, jitter_param, rngp = std::move(rngp)](
bool v) mutable {
if (!v) {
......
......@@ -47,7 +47,7 @@ TEST(BarrierTest, Simple) {
for (uint32_t i = 0; i < numThreads; ++i) {
threads.emplace_back([&]() {
barrier.wait()
.then([&](bool v) {
.thenValue([&](bool v) {
std::unique_lock<std::mutex> lock(mutex);
b1TrueSeen += uint32_t(v);
if (++b1Passed == numThreads) {
......@@ -55,7 +55,7 @@ TEST(BarrierTest, Simple) {
}
return barrier.wait();
})
.then([&](bool v) {
.thenValue([&](bool v) {
std::unique_lock<std::mutex> lock(mutex);
b2TrueSeen += uint32_t(v);
if (++b2Passed == numThreads) {
......
......@@ -87,7 +87,7 @@ TEST(Collect, collectAll) {
EXPECT_TRUE(results[3].hasException());
}
// check that futures are ready in then()
// check that futures are ready in thenValue()
{
std::vector<Promise<Unit>> promises(10);
std::vector<Future<Unit>> futures;
......@@ -96,7 +96,7 @@ TEST(Collect, collectAll) {
futures.push_back(p.getFuture());
}
auto allf = collectAllSemiFuture(futures).toUnsafeFuture().then(
auto allf = collectAllSemiFuture(futures).toUnsafeFuture().thenTry(
[](Try<std::vector<Try<Unit>>>&& ts) {
for (auto& f : ts.value()) {
f.value();
......@@ -325,7 +325,7 @@ TEST(Collect, collectAny) {
EXPECT_TRUE(anyf.value().second.hasException());
}
// then()
// thenValue()
{
std::vector<Promise<int>> promises(10);
std::vector<Future<int>> futures;
......@@ -334,7 +334,7 @@ TEST(Collect, collectAny) {
futures.push_back(p.getFuture());
}
auto anyf = collectAny(futures).then(
auto anyf = collectAny(futures).thenValue(
[](std::pair<size_t, Try<int>> p) { EXPECT_EQ(42, p.second.value()); });
promises[3].setValue(42);
......@@ -441,7 +441,7 @@ TEST(Collect, alreadyCompleted) {
fs.push_back(makeFuture());
}
collectAllSemiFuture(fs).toUnsafeFuture().then(
collectAllSemiFuture(fs).toUnsafeFuture().thenValue(
[&](std::vector<Try<Unit>> ts) { EXPECT_EQ(fs.size(), ts.size()); });
}
{
......@@ -450,7 +450,7 @@ TEST(Collect, alreadyCompleted) {
fs.push_back(makeFuture(i));
}
collectAny(fs).then([&](std::pair<size_t, Try<int>> p) {
collectAny(fs).thenValue([&](std::pair<size_t, Try<int>> p) {
EXPECT_EQ(p.first, p.second.value());
});
}
......@@ -596,7 +596,7 @@ TEST(Collect, collectN) {
size_t n = 3;
collectN(futures, n)
.via(&InlineExecutor::instance())
.then([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
.thenValue([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
flag = true;
EXPECT_EQ(n, v.size());
for (auto& tt : v) {
......@@ -624,7 +624,7 @@ TEST(Collect, collectNParallel) {
size_t n = 90;
collectN(futures, n)
.via(&InlineExecutor::instance())
.then([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
.thenValue([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
flag = true;
EXPECT_EQ(n, v.size());
for (auto& tt : v) {
......@@ -687,7 +687,7 @@ TEST(Collect, collectAllVariadic) {
bool flag = false;
collectAllSemiFuture(std::move(fb), std::move(fi))
.toUnsafeFuture()
.then([&](std::tuple<Try<bool>, Try<int>> tup) {
.thenValue([&](std::tuple<Try<bool>, Try<int>> tup) {
flag = true;
EXPECT_TRUE(std::get<0>(tup).hasValue());
EXPECT_EQ(std::get<0>(tup).value(), true);
......@@ -706,7 +706,7 @@ TEST(Collect, collectAllVariadicReferences) {
Future<bool> fb = pb.getFuture();
Future<int> fi = pi.getFuture();
bool flag = false;
collectAllSemiFuture(fb, fi).toUnsafeFuture().then(
collectAllSemiFuture(fb, fi).toUnsafeFuture().thenValue(
[&](std::tuple<Try<bool>, Try<int>> tup) {
flag = true;
EXPECT_TRUE(std::get<0>(tup).hasValue());
......@@ -728,7 +728,7 @@ TEST(Collect, collectAllVariadicWithException) {
bool flag = false;
collectAllSemiFuture(std::move(fb), std::move(fi))
.toUnsafeFuture()
.then([&](std::tuple<Try<bool>, Try<int>> tup) {
.thenValue([&](std::tuple<Try<bool>, Try<int>> tup) {
flag = true;
EXPECT_TRUE(std::get<0>(tup).hasValue());
EXPECT_EQ(std::get<0>(tup).value(), true);
......@@ -747,11 +747,12 @@ TEST(Collect, collectVariadic) {
Future<bool> fb = pb.getFuture();
Future<int> fi = pi.getFuture();
bool flag = false;
collect(std::move(fb), std::move(fi)).then([&](std::tuple<bool, int> tup) {
flag = true;
EXPECT_EQ(std::get<0>(tup), true);
EXPECT_EQ(std::get<1>(tup), 42);
});
collect(std::move(fb), std::move(fi))
.thenValue([&](std::tuple<bool, int> tup) {
flag = true;
EXPECT_EQ(std::get<0>(tup), true);
EXPECT_EQ(std::get<1>(tup), 42);
});
pb.setValue(true);
EXPECT_FALSE(flag);
pi.setValue(42);
......
......@@ -27,7 +27,7 @@ TEST(Ensure, basic) {
auto cob = [&] { count++; };
auto f = makeFuture(42)
.ensure(cob)
.then([](int) { throw std::runtime_error("ensure"); })
.thenValue([](int) { throw std::runtime_error("ensure"); })
.ensure(cob);
EXPECT_THROW(std::move(f).get(), std::runtime_error);
......
......@@ -241,7 +241,7 @@ TEST(Future, hasPreconditionValid) {
DOIT(f.value());
DOIT(f.poll());
DOIT(std::move(f).then());
DOIT(std::move(f).then([](auto&&) {}));
DOIT(std::move(f).thenValue([](auto&&) {}));
#undef DOIT
}
......@@ -945,11 +945,11 @@ TEST(Future, then) {
.then([](const Try<std::string> t) {
return makeFuture(t.value() + ";6");
})
.then([](std::string&& s) { return makeFuture(s + ";7"); })
.then([](const std::string&& s) { return makeFuture(s + ";8"); })
.then([](const std::string& s) { return makeFuture(s + ";9"); })
.then([](std::string s) { return makeFuture(s + ";10"); })
.then([](const std::string s) { return makeFuture(s + ";11"); });
.thenValue([](std::string&& s) { return makeFuture(s + ";7"); })
.thenValue([](const std::string&& s) { return makeFuture(s + ";8"); })
.thenValue([](const std::string& s) { return makeFuture(s + ";9"); })
.thenValue([](std::string s) { return makeFuture(s + ";10"); })
.thenValue([](const std::string s) { return makeFuture(s + ";11"); });
EXPECT_EQ(f.value(), "1;2;3;4;5;6;7;8;9;10;11");
}
......@@ -1020,14 +1020,14 @@ TEST(Future, thenTry) {
TEST(Future, thenValue) {
bool flag = false;
makeFuture<int>(42).then([&](int i) {
makeFuture<int>(42).thenValue([&](int i) {
EXPECT_EQ(42, i);
flag = true;
});
EXPECT_TRUE(flag);
flag = false;
makeFuture<int>(42).then([](int i) { return i; }).then([&](int i) {
makeFuture<int>(42).thenValue([](int i) { return i; }).thenValue([&](int i) {
flag = true;
EXPECT_EQ(42, i);
});
......@@ -1048,7 +1048,7 @@ TEST(Future, thenValue) {
TEST(Future, thenValueFuture) {
bool flag = false;
makeFuture<int>(42)
.then([](int i) { return makeFuture<int>(std::move(i)); })
.thenValue([](int i) { return makeFuture<int>(std::move(i)); })
.then([&](Try<int>&& t) {
flag = true;
EXPECT_EQ(42, t.value());
......@@ -1085,10 +1085,9 @@ TEST(Future, thenFunction) {
.then(doWorkStatic)
.then(Worker::doWorkStatic)
.then(&Worker::doWork, &w)
.then(doWorkStaticValue)
.thenValue(doWorkStaticValue);
EXPECT_EQ(f.value(), "start;static;class-static;class;value;value");
EXPECT_EQ(f.value(), "start;static;class-static;class;value");
}
static Future<std::string> doWorkStaticFuture(Try<std::string>&& t) {
......@@ -1116,12 +1115,7 @@ TEST(Future, thenFunctionFuture) {
TEST(Future, thenStdFunction) {
{
std::function<int(folly::Unit)> fn = [](folly::Unit) { return 42; };
auto f = makeFuture().then(std::move(fn));
EXPECT_EQ(f.value(), 42);
}
{
std::function<int(int)> fn = [](int i) { return i + 23; };
auto f = makeFuture(19).then(std::move(fn));
auto f = makeFuture().thenValue(std::move(fn));
EXPECT_EQ(f.value(), 42);
}
{
......@@ -1137,7 +1131,7 @@ TEST(Future, thenStdFunction) {
{
bool flag = false;
std::function<void(folly::Unit)> fn = [&flag](folly::Unit) { flag = true; };
auto f = makeFuture().then(std::move(fn));
auto f = makeFuture().thenValue(std::move(fn));
EXPECT_TRUE(f.isReady());
EXPECT_TRUE(flag);
}
......@@ -1408,7 +1402,7 @@ TEST(Future, thenDynamic) {
// sure that we call the then lambda with folly::dynamic and not
// Try<folly::dynamic> because that then fails to compile
Promise<folly::dynamic> p;
Future<folly::dynamic> f = p.getFuture().then(
Future<folly::dynamic> f = p.getFuture().thenValue(
[](const folly::dynamic& d) { return folly::dynamic(d.asInt() + 3); });
p.setValue(2);
EXPECT_EQ(std::move(f).get(), 5);
......@@ -1509,9 +1503,9 @@ TEST(Future, invokeCallbackReturningValueAsRvalue) {
// The continuation will be forward-constructed - copied if given as & and
// moved if given as && - everywhere construction is required.
// The continuation will be invoked with the same cvref as it is passed.
EXPECT_EQ(101, makeFuture<int>(100).then(foo).value());
EXPECT_EQ(202, makeFuture<int>(200).then(cfoo).value());
EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());
EXPECT_EQ(101, makeFuture<int>(100).thenValue(foo).value());
EXPECT_EQ(202, makeFuture<int>(200).thenValue(cfoo).value());
EXPECT_EQ(303, makeFuture<int>(300).thenValue(Foo()).value());
}
TEST(Future, invokeCallbackReturningFutureAsRvalue) {
......@@ -1533,10 +1527,6 @@ TEST(Future, invokeCallbackReturningFutureAsRvalue) {
// The continuation will be forward-constructed - copied if given as & and
// moved if given as && - everywhere construction is required.
// The continuation will be invoked with the same cvref as it is passed.
EXPECT_EQ(101, makeFuture<int>(100).then(foo).value());
EXPECT_EQ(202, makeFuture<int>(200).then(cfoo).value());
EXPECT_EQ(303, makeFuture<int>(300).then(Foo()).value());
EXPECT_EQ(101, makeFuture<int>(100).thenValue(foo).value());
EXPECT_EQ(202, makeFuture<int>(200).thenValue(cfoo).value());
EXPECT_EQ(303, makeFuture<int>(300).thenValue(Foo()).value());
......@@ -1594,7 +1584,7 @@ TEST(Future, makePromiseContract) {
ManualExecutor e;
auto c = makePromiseContract<int>(&e);
c.second = std::move(c.second).then([](int _) { return _ + 1; });
c.second = std::move(c.second).thenValue([](int _) { return _ + 1; });
EXPECT_FALSE(c.second.isReady());
c.first.setValue(3);
EXPECT_FALSE(c.second.isReady());
......
......@@ -29,7 +29,7 @@ TEST(NonCopyableLambda, basic) {
std::placeholders::_1));
// The previous statement can be simplified in C++14:
// Future<Unit>().then([promise = std::move(promise)]() mutable {
// Future<Unit>().thenValue([promise = std::move(promise)](auto&&) mutable {
// promise.setValue(123);
// });
......@@ -53,7 +53,8 @@ TEST(NonCopyableLambda, unique_ptr) {
// The previous statement can be simplified in C++14:
// auto future =
// promise.getFuture().then([int_ptr = std::move(int_ptr)]() mutable {
// promise.getFuture().thenValue([int_ptr = std::move(int_ptr)](
// auto&&) mutable {
// ++*int_ptr;
// return std::move(int_ptr);
// });
......@@ -69,7 +70,7 @@ TEST(NonCopyableLambda, Function) {
Function<int(int)> callback = [](int x) { return x + 1; };
auto future = promise.getFuture().then(std::move(callback));
auto future = promise.getFuture().thenValue(std::move(callback));
EXPECT_THROW(callback(0), std::bad_function_call);
EXPECT_FALSE(future.isReady());
......@@ -83,7 +84,7 @@ TEST(NonCopyableLambda, FunctionConst) {
Function<int(int) const> callback = [](int x) { return x + 1; };
auto future = promise.getFuture().then(std::move(callback));
auto future = promise.getFuture().thenValue(std::move(callback));
EXPECT_THROW(callback(0), std::bad_function_call);
EXPECT_FALSE(future.isReady());
......
......@@ -22,7 +22,7 @@ using namespace folly;
TEST(SelfDestruct, then) {
auto* p = new Promise<int>();
auto future = p->getFuture().then([p](int x) {
auto future = p->getFuture().thenValue([p](int x) {
delete p;
return x + 1;
});
......
......@@ -391,7 +391,7 @@ TEST(SemiFuture, MakeFutureFromSemiFuture) {
Promise<int> p;
std::atomic<int> result{0};
auto f = p.getSemiFuture();
auto future = std::move(f).via(&e).then([&](int value) {
auto future = std::move(f).via(&e).thenValue([&](int value) {
result = value;
return value;
});
......@@ -410,7 +410,7 @@ TEST(SemiFuture, MakeFutureFromSemiFutureReturnFuture) {
Promise<int> p;
int result{0};
auto f = p.getSemiFuture();
auto future = std::move(f).via(&e).then([&](int value) {
auto future = std::move(f).via(&e).thenValue([&](int value) {
result = value;
return folly::makeFuture(std::move(value));
});
......@@ -431,11 +431,11 @@ TEST(SemiFuture, MakeFutureFromSemiFutureReturnSemiFuture) {
auto f = p.getSemiFuture();
auto future = std::move(f)
.via(&e)
.then([&](int value) {
.thenValue([&](int value) {
result = value;
return folly::makeSemiFuture(std::move(value));
})
.then([&](int value) {
.thenValue([&](int value) {
return folly::makeSemiFuture(std::move(value));
});
e.loopOnce();
......@@ -454,7 +454,7 @@ TEST(SemiFuture, MakeFutureFromSemiFutureLValue) {
Promise<int> p;
std::atomic<int> result{0};
auto f = p.getSemiFuture();
auto future = std::move(f).via(&e).then([&](int value) {
auto future = std::move(f).via(&e).thenValue([&](int value) {
result = value;
return value;
});
......@@ -675,7 +675,7 @@ TEST(SemiFuture, ChainingDefertoThenWithValue) {
return a;
});
// Run "F" here inline in a task running on the eventbase
auto tf = std::move(sf).via(&e2).then([&](int a) { result = a; });
auto tf = std::move(sf).via(&e2).thenValue([&](int a) { result = a; });
p.setValue(7);
tf.getVia(&e2);
ASSERT_EQ(innerResult, 7);
......@@ -710,7 +710,8 @@ TEST(SemiFuture, DeferWithinContinuation) {
Promise<int> p;
Promise<int> p2;
auto f = p.getSemiFuture().via(&e2);
auto resultF = std::move(f).then([&, p3 = std::move(p2)](int outer) mutable {
auto resultF = std::move(f).thenValue([&, p3 = std::move(p2)](
int outer) mutable {
result = outer;
return makeSemiFuture<int>(std::move(outer))
.deferValue([&, p4 = std::move(p3)](int inner) mutable {
......@@ -953,8 +954,8 @@ TEST(SemiFuture, semiFutureWithinCtxCleanedUpWhenTaskFinishedInTime) {
promise.getSemiFuture()
.within(longEnough)
.toUnsafeFuture()
.then([&target](
folly::Try<std::shared_ptr<int>>&& callbackInput) mutable {
.thenTry([&target](
folly::Try<std::shared_ptr<int>>&& callbackInput) mutable {
target = callbackInput.value();
});
promise.setValue(input);
......@@ -968,7 +969,7 @@ TEST(SemiFuture, semiFutureWithinNoValueReferenceWhenTimeOut) {
Promise<std::shared_ptr<int>> promise;
auto veryShort = std::chrono::milliseconds(1);
promise.getSemiFuture().within(veryShort).toUnsafeFuture().then(
promise.getSemiFuture().within(veryShort).toUnsafeFuture().thenTry(
[](folly::Try<std::shared_ptr<int>>&& callbackInput) {
// Timeout is fired. Verify callbackInput is not referenced
EXPECT_EQ(0, callbackInput.value().use_count());
......
......@@ -7,70 +7,58 @@ using namespace folly;
TEST(Basic, thenVariants) {
SomeClass anObject;
// clang-format off
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A>&&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, Try<A>&&>());}
{Future<B> f = someFuture<A>().then([&](Try<A>&&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, Try<A> const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, Try<A> const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A> const&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, Try<A> const&>());}
{Future<B> f = someFuture<A>().then([&](Try<A> const&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, Try<A>>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, Try<A>>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A>>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, Try<A>>());}
{Future<B> f = someFuture<A>().then([&](Try<A>){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A>&>, &anObject);}
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, A&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, A&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, A&&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, A&&>());}
{Future<B> f = someFuture<A>().then([&](A&&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, A const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, A const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, A const&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, A const&>());}
{Future<B> f = someFuture<A>().then([&](A const&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, A>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, A>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, A>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, A>());}
{Future<B> f = someFuture<A>().then([&](A){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, A&>, &anObject);}
{Future<B> f = someFuture<A>().then(&aFunction<B, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A>&&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, Try<A>&&>());}
{Future<B> f = someFuture<A>().then([&](Try<A>&&){return B();});}
{Future<B> f = someFuture<A>().then(&aFunction<B, Try<A> const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, Try<A> const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A> const&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, Try<A> const&>());}
{Future<B> f = someFuture<A>().then([&](Try<A> const&){return B();});}
{Future<B> f = someFuture<A>().then(&aFunction<B, Try<A>>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, Try<A>>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A>>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, Try<A>>());}
{Future<B> f = someFuture<A>().then([&](Try<A>){return B();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A>&>, &anObject);}
{Future<B> f = someFuture<A>().then(&aFunction<B, A&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, A&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, A&&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, A&&>());}
{Future<B> f = someFuture<A>().then([&](A&&){return B();});}
{Future<B> f = someFuture<A>().then(&aFunction<B, A const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, A const&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, A const&>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, A const&>());}
{Future<B> f = someFuture<A>().then([&](A const&){return B();});}
{Future<B> f = someFuture<A>().then(&aFunction<B, A>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, A>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, A>, &anObject);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, A>());}
{Future<B> f = someFuture<A>().then([&](A){return B();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, A&>, &anObject);}
// clang-format on
{Future<B> f = someFuture<A>().thenValue(&aFunction<Future<B>, A&&>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<Future<B>, A&&>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<Future<B>, A&&>());}
{Future<B> f = someFuture<A>().thenValue([&](A&&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().thenValue(&aFunction<Future<B>, A const&>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<Future<B>, A const&>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<Future<B>, A const&>());}
{Future<B> f = someFuture<A>().thenValue([&](A const&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().thenValue(&aFunction<Future<B>, A>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<Future<B>, A>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<Future<B>, A>());}
{Future<B> f = someFuture<A>().thenValue([&](A){return someFuture<B>();});}
{Future<B> f = someFuture<A>().thenValue(&aFunction<B, A&&>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<B, A&&>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<B, A&&>());}
{Future<B> f = someFuture<A>().thenValue([&](A&&){return B();});}
{Future<B> f = someFuture<A>().thenValue(&aFunction<B, A const&>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<B, A const&>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<B, A const&>());}
{Future<B> f = someFuture<A>().thenValue([&](A const&){return B();});}
{Future<B> f = someFuture<A>().thenValue(&aFunction<B, A>);}
{Future<B> f = someFuture<A>().thenValue(&SomeClass::aStaticMethod<B, A>);}
{Future<B> f = someFuture<A>().thenValue(aStdFunction<B, A>());}
{Future<B> f = someFuture<A>().thenValue([&](A){return B();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A>&&>, &anObject);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A> const&>, &anObject);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<Future<B>, Try<A>>, &anObject);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A>&&>, &anObject);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A> const&>, &anObject);}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, Try<A>>, &anObject);}
}
......@@ -132,7 +132,7 @@ TEST(Then, tryConstValue) {
}
TEST(Then, constRValueReference) {
auto future = makeFuture<Widget>(23).then([](const Widget&& w) {
auto future = makeFuture<Widget>(23).thenValue([](const Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
......@@ -141,7 +141,7 @@ TEST(Then, constRValueReference) {
}
TEST(Then, rValueReference) {
auto future = makeFuture<Widget>(23).then([](Widget&& w) {
auto future = makeFuture<Widget>(23).thenValue([](Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
......@@ -150,7 +150,7 @@ TEST(Then, rValueReference) {
}
TEST(Then, constLValueReference) {
auto future = makeFuture<Widget>(23).then([](const Widget& w) {
auto future = makeFuture<Widget>(23).thenValue([](const Widget& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
......@@ -159,7 +159,7 @@ TEST(Then, constLValueReference) {
}
TEST(Then, value) {
auto future = makeFuture<Widget>(23).then([](Widget w) {
auto future = makeFuture<Widget>(23).thenValue([](Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
......@@ -168,7 +168,7 @@ TEST(Then, value) {
}
TEST(Then, constValue) {
auto future = makeFuture<Widget>(23).then([](const Widget w) {
auto future = makeFuture<Widget>(23).thenValue([](const Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
......
......@@ -30,7 +30,8 @@ TEST(Unwrap, simpleScenario) {
// Makes sure that unwrap() works when chaning Future's commands.
TEST(Unwrap, chainCommands) {
Future<Future<int>> future = makeFuture(makeFuture(5484));
auto unwrapped = std::move(future).unwrap().then([](int i) { return i; });
auto unwrapped =
std::move(future).unwrap().thenValue([](int i) { return i; });
EXPECT_EQ(5484, unwrapped.value());
}
......
......@@ -79,7 +79,7 @@ TEST(Via, exceptionOnLaunch) {
}
TEST(Via, thenValue) {
auto future = makeFuture(std::move(1)).then([](Try<int>&& t) {
auto future = makeFuture(std::move(1)).thenTry([](Try<int>&& t) {
return t.value() == 1;
});
......@@ -87,7 +87,7 @@ TEST(Via, thenValue) {
}
TEST(Via, thenFuture) {
auto future = makeFuture(1).then(
auto future = makeFuture(1).thenTry(
[](Try<int>&& t) { return makeFuture(t.value() == 1); });
EXPECT_TRUE(future.value());
}
......@@ -107,8 +107,8 @@ TEST(Via, thenFunction) {
} w;
auto f = makeFuture(std::string("start"))
.then(doWorkStatic)
.then(Worker::doWorkStatic)
.thenTry(doWorkStatic)
.thenTry(Worker::doWorkStatic)
.then(&Worker::doWork, &w);
EXPECT_EQ(f.value(), "start;static;class-static;class");
......@@ -117,12 +117,12 @@ TEST(Via, thenFunction) {
TEST_F(ViaFixture, threadHops) {
auto westThreadId = std::this_thread::get_id();
auto f = via(eastExecutor.get())
.then([=](Try<Unit>&& /* t */) {
.thenTry([=](Try<Unit>&& /* t */) {
EXPECT_NE(std::this_thread::get_id(), westThreadId);
return makeFuture<int>(1);
})
.via(westExecutor.get())
.then([=](Try<int>&& t) {
.thenTry([=](Try<int>&& t) {
EXPECT_EQ(std::this_thread::get_id(), westThreadId);
return t.value();
});
......@@ -136,23 +136,23 @@ TEST_F(ViaFixture, chainVias) {
EXPECT_NE(std::this_thread::get_id(), westThreadId);
return 1;
})
.then([=](int val) {
.thenValue([=](int val) {
return makeFuture(val)
.via(westExecutor.get())
.then([=](int v) mutable {
.thenValue([=](int v) mutable {
EXPECT_EQ(std::this_thread::get_id(), westThreadId);
return v + 1;
});
})
.then([=](int val) {
.thenValue([=](int val) {
// even though ultimately the future that triggers this one
// executed in the west thread, this then() inherited the
// executed in the west thread, this thenValue() inherited the
// executor from its predecessor, ie the eastExecutor.
EXPECT_NE(std::this_thread::get_id(), westThreadId);
return val + 1;
})
.via(westExecutor.get())
.then([=](int val) {
.thenValue([=](int val) {
// go back to west, so we can wait on it
EXPECT_EQ(std::this_thread::get_id(), westThreadId);
return val + 1;
......@@ -366,7 +366,7 @@ TEST(Via, callbackRace) {
std::vector<Future<Unit>> futures;
for (auto& p : *promises) {
futures.emplace_back(p.getFuture().via(&x).then([](Try<Unit>&&) {}));
futures.emplace_back(p.getFuture().via(&x).thenTry([](Try<Unit>&&) {}));
}
x.waitForStartup();
......@@ -487,9 +487,11 @@ TEST(Via, viaRaces) {
std::thread t1([&] {
p.getFuture()
.via(&x)
.then([&](Try<Unit>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.then([&](Try<Unit>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.then([&](Try<Unit>&&) { done = true; });
.thenTry(
[&](Try<Unit>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.thenTry(
[&](Try<Unit>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.thenTry([&](Try<Unit>&&) { done = true; });
});
std::thread t2([&] { p.setValue(); });
......
......@@ -9,10 +9,10 @@
# X
# accepts (Try<T>&&, Try<T> const&, Try<T>, T&&, T const&, T, nothing)
def test(*args)
def test(form, *args)
args = args.join(", ")
[
"{Future<B> f = someFuture<A>().then(#{args});}",
"{Future<B> f = someFuture<A>().#{form}(#{args});}",
#"{Future<B> f = makeFuture(A()).then(#{args}, anExecutor);}",
]
end
......@@ -30,35 +30,59 @@ return_types = [
"B",
#"Try<B>",
]
param_types = [
try_param_types = [
"Try<A>&&",
"Try<A> const&",
"Try<A>",
"Try<A>&",
]
value_param_types = [
"A&&",
"A const&",
"A",
"A&",
]
tests = (
return_types.map { |ret|
param_types.map { |param|
if param != "" then
both = "#{ret}, #{param}"
[
["&aFunction<#{both}>"],
["&SomeClass::aStaticMethod<#{both}>"],
["&SomeClass::aMethod<#{both}>", "&anObject"],
["aStdFunction<#{both}>()"],
["[&](#{param}){return #{retval(ret)};}"],
]
else
[["[&](){return #{retval(ret)};}"]]
end
}
}.flatten(2)
).map {|a| test(a)}.flatten
def doMap(form, param_types, return_types)
(
return_types.map { |ret|
param_types.map { |param|
if param != "" then
both = "#{ret}, #{param}"
[
["&aFunction<#{both}>"],
["&SomeClass::aStaticMethod<#{both}>"],
#["&SomeClass::aMethod<#{both}>", "&anObject"],
["aStdFunction<#{both}>()"],
["[&](#{param}){return #{retval(ret)};}"],
]
else
[["[&](){return #{retval(ret)};}"]]
end
}
}.flatten(2)
).map {|a| test(form, a)}.flatten
end
def doMapMultiArg(form, param_types, return_types)
(
return_types.map { |ret|
param_types.map { |param|
if param != "" then
both = "#{ret}, #{param}"
[
["&SomeClass::aMethod<#{both}>", "&anObject"],
]
else
[["[&](){return #{retval(ret)};}"]]
end
}
}.flatten(2)
).map {|a| test(form, a)}.flatten
end
# TODO(#T29171940): Modify this to thenTry on deletion of the Try form of then
tests = doMap("then", try_param_types, return_types)
tests.concat doMap("thenValue", value_param_types, return_types)
tests.concat doMapMultiArg("then", try_param_types, return_types)
print <<EOF
// This file is #{"@"}generated by then_compile_test.rb. Do not edit directly.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment