Commit 46bb4594 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Apply clang-format to folly/futures/

Summary: [Folly] Apply `clang-format` to `folly/futures/`.

Reviewed By: LeeHowes

Differential Revision: D9672492

fbshipit-source-id: c41632c4da6c450096eb249f0708af3db5057a14
parent 4aa9b357
......@@ -17,11 +17,11 @@
#include <folly/futures/Barrier.h>
#include <folly/lang/Exception.h>
namespace folly { namespace futures {
namespace folly {
namespace futures {
Barrier::Barrier(uint32_t n)
: size_(n),
controlBlock_(allocateControlBlock()) { }
: size_(n), controlBlock_(allocateControlBlock()) {}
Barrier::~Barrier() {
auto block = controlBlock_.load(std::memory_order_relaxed);
......@@ -78,8 +78,8 @@ folly::Future<bool> Barrier::wait() {
// Bump the value and record ourselves as reader.
// This ensures that block stays allocated, as the reader count is > 0.
auto prev = block->valueAndReaderCount.fetch_add(kReader + 1,
std::memory_order_acquire);
auto prev = block->valueAndReaderCount.fetch_add(
kReader + 1, std::memory_order_acquire);
auto prevValue = static_cast<uint32_t>(prev & kValueMask);
DCHECK_LT(prevValue, size_);
......@@ -97,8 +97,8 @@ folly::Future<bool> Barrier::wait() {
}
// Free the control block if we're the last reader at max value.
prev = block->valueAndReaderCount.fetch_sub(kReader,
std::memory_order_acq_rel);
prev =
block->valueAndReaderCount.fetch_sub(kReader, std::memory_order_acq_rel);
if (prev == (kReader | uint64_t(size_))) {
freeControlBlock(block);
}
......
......@@ -22,7 +22,8 @@
#include <folly/futures/Future.h>
#include <folly/futures/Promise.h>
namespace folly { namespace futures {
namespace folly {
namespace futures {
// A folly::Future-istic Barrier synchronization primitive
//
......
......@@ -1199,7 +1199,7 @@ Future<T>::onError(F&& func) && {
if (tf2.hasException()) {
state.setException(std::move(tf2.exception()));
} else {
tf2->setCallback_([p = state.stealPromise()](Try<T> && t3) mutable {
tf2->setCallback_([p = state.stealPromise()](Try<T>&& t3) mutable {
p.setTry(std::move(t3));
});
}
......@@ -1255,7 +1255,7 @@ Future<T>::onError(F&& func) && {
if (tf2.hasException()) {
state.setException(std::move(tf2.exception()));
} else {
tf2->setCallback_([p = state.stealPromise()](Try<T> && t3) mutable {
tf2->setCallback_([p = state.stealPromise()](Try<T>&& t3) mutable {
p.setTry(std::move(t3));
});
}
......@@ -1365,9 +1365,9 @@ Future<T> makeFuture(exception_wrapper ew) {
}
template <class T, class E>
typename std::enable_if<std::is_base_of<std::exception, E>::value,
Future<T>>::type
makeFuture(E const& e) {
typename std::enable_if<std::is_base_of<std::exception, E>::value, Future<T>>::
type
makeFuture(E const& e) {
return makeFuture(Try<T>(make_exception_wrapper<E>(e)));
}
......@@ -1620,11 +1620,9 @@ Future<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collect(
// TODO(T26439406): Make return SemiFuture
template <class InputIterator>
Future<
std::pair<size_t,
Try<
typename
std::iterator_traits<InputIterator>::value_type::value_type>>>
Future<std::pair<
size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAny(InputIterator first, InputIterator last) {
using F = typename std::iterator_traits<InputIterator>::value_type;
using T = typename F::value_type;
......@@ -1783,8 +1781,7 @@ Future<T> reduce(It first, It last, T&& initial, F&& func) {
// window (collection)
template <class Collection, class F, class ItT, class Result>
std::vector<Future<Result>>
window(Collection input, F func, size_t n) {
std::vector<Future<Result>> window(Collection input, F func, size_t n) {
// Use global QueuedImmediateExecutor singleton to avoid stack overflow.
auto executor = &QueuedImmediateExecutor::instance();
return window(executor, std::move(input), std::move(func), n);
......
......@@ -19,7 +19,8 @@
namespace folly {
template <class> class Promise;
template <class>
class Promise;
template <class T>
class SemiFuture;
......@@ -71,7 +72,8 @@ struct isTry<Try<T>> : std::true_type {};
namespace futures {
namespace detail {
template <class> class Core;
template <class>
class Core;
template <typename...>
struct ArgType;
......@@ -123,10 +125,10 @@ struct valueCallableResult {
};
template <typename L>
struct Extract : Extract<decltype(&L::operator())> { };
struct Extract : Extract<decltype(&L::operator())> {};
template <typename Class, typename R, typename... Args>
struct Extract<R(Class::*)(Args...) const> {
struct Extract<R (Class::*)(Args...) const> {
typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
......@@ -134,7 +136,7 @@ struct Extract<R(Class::*)(Args...) const> {
};
template <typename Class, typename R, typename... Args>
struct Extract<R(Class::*)(Args...)> {
struct Extract<R (Class::*)(Args...)> {
typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
......
......@@ -1158,10 +1158,11 @@ class Future : private futures::detail::FutureBase<T> {
std::forward<F>(func), typename R::Arg());
}
// clang-format off
template <typename F, typename R = futures::detail::callableResult<T, F>>
[[deprecated("must be rvalue-qualified, e.g., std::move(future).then(...)")]]
typename R::Return
then(F&& func) & = delete;
typename R::Return then(F&& func) & = delete;
// clang-format on
/// Variant where func is an member function
///
......@@ -1188,11 +1189,13 @@ class Future : private futures::detail::FutureBase<T> {
R (Caller::*func)(Args...),
Caller* instance) &&;
// clang-format off
template <typename R, typename Caller, typename... Args>
[[deprecated(
"must be rvalue-qualified, e.g., std::move(future).then(...)")]]
Future<typename isFuture<R>::Inner>
then(R (Caller::*func)(Args...), Caller* instance) & = delete;
// clang-format on
/// Execute the callback via the given Executor. The executor doesn't stick.
///
......@@ -1369,8 +1372,11 @@ class Future : private futures::detail::FutureBase<T> {
/// - `RESULT.valid() == true`
Future<Unit> then() &&;
[[deprecated("must be rvalue-qualified, e.g., std::move(future).then()")]]
// clang-format off
[[deprecated(
"must be rvalue-qualified, e.g., std::move(future).then()")]]
Future<Unit> then() & = delete;
// clang-format on
/// Convenience method for ignoring the value and creating a Future<Unit>.
/// Exceptions still propagate.
......@@ -1482,7 +1488,6 @@ class Future : private futures::detail::FutureBase<T> {
Future<T> onError(F&& func) & {
return std::move(*this).onError(std::forward<F>(func));
}
// clang-format on
/// func is like std::function<void()> and is executed unconditionally, and
/// the value/exception is passed through to the resulting Future.
......@@ -1500,6 +1505,7 @@ class Future : private futures::detail::FutureBase<T> {
/// - `RESULT.valid() == true`
template <class F>
Future<T> ensure(F&& func) &&;
// clang-format on
/// Like onError, but for timeouts. example:
///
......
......@@ -127,8 +127,7 @@ void Promise<T>::setTry(Try<T>&& t) {
template <class T>
template <class M>
void Promise<T>::setValue(M&& v) {
static_assert(!std::is_same<T, void>::value,
"Use setValue() instead");
static_assert(!std::is_same<T, void>::value, "Use setValue() instead");
setTry(Try<T>(std::forward<M>(v)));
}
......
......@@ -56,7 +56,8 @@ class FOLLY_EXPORT BrokenPromise : public PromiseException {
// forward declaration
template <class T>
class SemiFuture;
template <class T> class Future;
template <class T>
class Future;
namespace futures {
namespace detail {
......@@ -322,8 +323,7 @@ class Promise {
/// - `isFulfilled() == true`
/// - `valid() == true` (unchanged)
template <class B = T>
typename std::enable_if<std::is_same<Unit, B>::value, void>::type
setValue() {
typename std::enable_if<std::is_same<Unit, B>::value, void>::type setValue() {
setTry(Try<T>(T()));
}
......
......@@ -82,15 +82,14 @@ class SharedPromise {
/// Set an interrupt handler to handle interrupts. See the documentation for
/// Future::raise(). Your handler can do whatever it wants, but if you
/// bother to set one then you probably will want to fulfill the SharedPromise with
/// an exception (or special value) indicating how the interrupt was
/// bother to set one then you probably will want to fulfill the SharedPromise
/// with an exception (or special value) indicating how the interrupt was
/// handled.
void setInterruptHandler(std::function<void(exception_wrapper const&)>);
/// Sugar to fulfill this SharedPromise<Unit>
template <class B = T>
typename std::enable_if<std::is_same<Unit, B>::value, void>::type
setValue() {
typename std::enable_if<std::is_same<Unit, B>::value, void>::type setValue() {
setTry(Try<T>(T()));
}
......
......@@ -99,14 +99,14 @@ ThreadWheelTimekeeper::ThreadWheelTimekeeper()
wheelTimer_(
HHWheelTimer::newTimer(&eventBase_, std::chrono::milliseconds(1))) {
eventBase_.waitUntilRunning();
eventBase_.runInEventBaseThread([this]{
eventBase_.runInEventBaseThread([this] {
// 15 characters max
eventBase_.setName("FutureTimekeepr");
});
}
ThreadWheelTimekeeper::~ThreadWheelTimekeeper() {
eventBase_.runInEventBaseThreadAndWait([this]{
eventBase_.runInEventBaseThreadAndWait([this] {
wheelTimer_->cancelAll();
eventBase_.terminateLoopSoon();
});
......@@ -130,9 +130,8 @@ Future<Unit> ThreadWheelTimekeeper::after(Duration dur) {
// callback has either been executed, or will never be executed. So we are
// fine here.
//
if (!eventBase_.runInEventBaseThread([this, cob, dur]{
wheelTimer_->scheduleTimeout(cob.get(), dur);
})) {
if (!eventBase_.runInEventBaseThread(
[this, cob, dur] { wheelTimer_->scheduleTimeout(cob.get(), dur); })) {
// Release promise to break the circular reference. Because if
// scheduleTimeout fails, there is nothing to *promise*. Internally
// Core would automatically set an exception result when Promise is
......
......@@ -178,8 +178,10 @@ static_assert(sizeof(SpinLock) == 1, "missized");
/// from more than one thread at a time there won't be any problems.
template <typename T>
class Core final {
static_assert(!std::is_void<T>::value,
"void futures are not supported. Use Unit instead.");
static_assert(
!std::is_void<T>::value,
"void futures are not supported. Use Unit instead.");
public:
/// State will be Start
static Core* make() {
......@@ -584,13 +586,13 @@ class Core final {
std::atomic<unsigned char> callbackReferences_{0};
std::atomic<bool> interruptHandlerSet_{false};
SpinLock interruptLock_;
int8_t priority_ {-1};
int8_t priority_{-1};
Executor::KeepAlive<> executor_;
union {
Context context_;
};
std::unique_ptr<exception_wrapper> interrupt_ {};
std::function<void(exception_wrapper const&)> interruptHandler_ {nullptr};
std::unique_ptr<exception_wrapper> interrupt_{};
std::function<void(exception_wrapper const&)> interruptHandler_{nullptr};
};
} // namespace detail
......
......@@ -34,59 +34,57 @@ namespace folly {
/// of the functions herein have really-likely-to-collide names, like "map"
/// and "sleep".
namespace futures {
/// Returns a Future that will complete after the specified duration. The
/// Duration typedef of a `std::chrono` duration type indicates the
/// resolution you can expect to be meaningful (milliseconds at the time of
/// writing). Normally you wouldn't need to specify a Timekeeper, we will
/// use the global futures timekeeper (we run a thread whose job it is to
/// keep time for futures timeouts) but we provide the option for power
/// users.
///
/// The Timekeeper thread will be lazily created the first time it is
/// needed. If your program never uses any timeouts or other time-based
/// Futures you will pay no Timekeeper thread overhead.
Future<Unit> sleep(Duration, Timekeeper* = nullptr);
/**
* 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 = typename decltype(
std::declval<ItT>().then(std::declval<F>()))::value_type>
std::vector<Future<Result>> map(It first, It last, F func);
/**
* Set func as the callback for each input Future and return a vector of
* Futures containing the results in the input order and completing on
* exec.
*/
template <
class It,
class F,
class ItT = typename std::iterator_traits<It>::value_type,
class Result =
typename decltype(std::move(std::declval<ItT>())
.via(std::declval<Executor*>())
.then(std::declval<F>()))::value_type>
std::vector<Future<Result>> map(Executor& exec, It first, It last, F func);
// Sugar for the most common case
template <class Collection, class F>
auto map(Collection&& c, F&& func)
-> decltype(map(c.begin(), c.end(), func)) {
return map(c.begin(), c.end(), std::forward<F>(func));
}
// Sugar for the most common case
template <class Collection, class F>
auto map(Executor& exec, Collection&& c, F&& func)
-> decltype(map(exec, c.begin(), c.end(), func)) {
return map(exec, c.begin(), c.end(), std::forward<F>(func));
}
/// Returns a Future that will complete after the specified duration. The
/// Duration typedef of a `std::chrono` duration type indicates the
/// resolution you can expect to be meaningful (milliseconds at the time of
/// writing). Normally you wouldn't need to specify a Timekeeper, we will
/// use the global futures timekeeper (we run a thread whose job it is to
/// keep time for futures timeouts) but we provide the option for power
/// users.
///
/// The Timekeeper thread will be lazily created the first time it is
/// needed. If your program never uses any timeouts or other time-based
/// Futures you will pay no Timekeeper thread overhead.
Future<Unit> sleep(Duration, Timekeeper* = nullptr);
/**
* 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 = typename decltype(
std::declval<ItT>().then(std::declval<F>()))::value_type>
std::vector<Future<Result>> map(It first, It last, F func);
/**
* Set func as the callback for each input Future and return a vector of
* Futures containing the results in the input order and completing on
* exec.
*/
template <
class It,
class F,
class ItT = typename std::iterator_traits<It>::value_type,
class Result = typename decltype(std::move(std::declval<ItT>())
.via(std::declval<Executor*>())
.then(std::declval<F>()))::value_type>
std::vector<Future<Result>> map(Executor& exec, It first, It last, F func);
// Sugar for the most common case
template <class Collection, class F>
auto map(Collection&& c, F&& func) -> decltype(map(c.begin(), c.end(), func)) {
return map(c.begin(), c.end(), std::forward<F>(func));
}
// Sugar for the most common case
template <class Collection, class F>
auto map(Executor& exec, Collection&& c, F&& func)
-> decltype(map(exec, c.begin(), c.end(), func)) {
return map(exec, c.begin(), c.end(), std::forward<F>(func));
}
} // namespace futures
......@@ -140,8 +138,8 @@ makeSemiFutureWith(F&& func);
///
/// auto f = makeSemiFuture<string>(std::current_exception());
template <class T>
[[deprecated("use makeSemiFuture(exception_wrapper)")]]
SemiFuture<T> makeSemiFuture(std::exception_ptr const& e);
[[deprecated("use makeSemiFuture(exception_wrapper)")]] SemiFuture<T>
makeSemiFuture(std::exception_ptr const& e);
/// Make a failed SemiFuture from an exception_wrapper.
template <class T>
......@@ -150,9 +148,9 @@ SemiFuture<T> makeSemiFuture(exception_wrapper ew);
/** Make a SemiFuture from an exception type E that can be passed to
std::make_exception_ptr(). */
template <class T, class E>
typename std::enable_if<std::is_base_of<std::exception, E>::value,
SemiFuture<T>>::type
makeSemiFuture(E const& e);
typename std::
enable_if<std::is_base_of<std::exception, E>::value, SemiFuture<T>>::type
makeSemiFuture(E const& e);
/** Make a Future out of a Try */
template <class T>
......@@ -224,8 +222,8 @@ makeFutureWith(F&& func);
///
/// auto f = makeFuture<string>(std::current_exception());
template <class T>
[[deprecated("use makeSemiFuture(exception_wrapper)")]]
Future<T> makeFuture(std::exception_ptr const& e);
[[deprecated("use makeSemiFuture(exception_wrapper)")]] Future<T> makeFuture(
std::exception_ptr const& e);
/// Make a failed Future from an exception_wrapper.
/// NOTE: This function is deprecated. Please use makeSemiFuture and pass the
......@@ -242,9 +240,9 @@ Future<T> makeFuture(exception_wrapper ew);
valid Future where necessary.
*/
template <class T, class E>
typename std::enable_if<std::is_base_of<std::exception, E>::value,
Future<T>>::type
makeFuture(E const& e);
typename std::enable_if<std::is_base_of<std::exception, E>::value, Future<T>>::
type
makeFuture(E const& e);
/**
Make a Future out of a Try
......@@ -313,8 +311,8 @@ auto collectAllSemiFuture(Collection&& c)
}
template <class InputIterator>
Future<std::vector<Try<
typename std::iterator_traits<InputIterator>::value_type::value_type>>>
Future<std::vector<
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAll(InputIterator first, InputIterator last);
template <class Collection>
......@@ -362,8 +360,8 @@ Future<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collect(
*/
template <class InputIterator>
Future<std::pair<
size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAny(InputIterator first, InputIterator last);
/// Sugar for the most common case
......@@ -375,7 +373,7 @@ auto collectAny(Collection&& c) -> decltype(collectAny(c.begin(), c.end())) {
/** Similar to collectAny, collectAnyWithoutException return the first Future to
* complete without exceptions. If none of the future complete without
* excpetions, the last exception will be returned as a result.
*/
*/
template <class InputIterator>
Future<std::pair<
size_t,
......@@ -452,14 +450,13 @@ 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))) {
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));
c.begin(), c.end(), std::forward<T>(initial), std::forward<F>(func));
}
/** like reduce, but calls func on finished futures as they complete
......@@ -471,12 +468,12 @@ Future<T> unorderedReduce(It first, It last, T initial, F func);
/// Sugar for the most common case
template <class Collection, class T, class F>
auto unorderedReduce(Collection&& c, T&& initial, F&& func)
-> decltype(unorderedReduce(c.begin(), c.end(), std::forward<T>(initial),
std::forward<F>(func))) {
-> decltype(unorderedReduce(
c.begin(),
c.end(),
std::forward<T>(initial),
std::forward<F>(func))) {
return unorderedReduce(
c.begin(),
c.end(),
std::forward<T>(initial),
std::forward<F>(func));
c.begin(), c.end(), std::forward<T>(initial), std::forward<F>(func));
}
} // namespace folly
......@@ -25,7 +25,9 @@
#include <glog/logging.h>
namespace folly { namespace futures { namespace test {
namespace folly {
namespace futures {
namespace test {
TEST(BarrierTest, Simple) {
constexpr uint32_t numThreads = 10;
......@@ -43,26 +45,24 @@ TEST(BarrierTest, Simple) {
std::vector<std::thread> threads;
threads.reserve(numThreads);
for (uint32_t i = 0; i < numThreads; ++i) {
threads.emplace_back([&] () {
threads.emplace_back([&]() {
barrier.wait()
.then(
[&] (bool v) {
std::unique_lock<std::mutex> lock(mutex);
b1TrueSeen += uint32_t(v);
if (++b1Passed == numThreads) {
b1DoneCond.notify_one();
}
return barrier.wait();
})
.then(
[&] (bool v) {
std::unique_lock<std::mutex> lock(mutex);
b2TrueSeen += uint32_t(v);
if (++b2Passed == numThreads) {
b2DoneCond.notify_one();
}
})
.get();
.then([&](bool v) {
std::unique_lock<std::mutex> lock(mutex);
b1TrueSeen += uint32_t(v);
if (++b1Passed == numThreads) {
b1DoneCond.notify_one();
}
return barrier.wait();
})
.then([&](bool v) {
std::unique_lock<std::mutex> lock(mutex);
b2TrueSeen += uint32_t(v);
if (++b2Passed == numThreads) {
b2DoneCond.notify_one();
}
})
.get();
});
}
......@@ -116,7 +116,7 @@ TEST(BarrierTest, Random) {
auto numThreads = folly::Random::rand32(30, 91);
struct ThreadInfo {
ThreadInfo() { }
ThreadInfo() {}
std::thread thread;
uint32_t iteration = 0;
uint32_t numFutures;
......
......@@ -98,7 +98,7 @@ BENCHMARK(no_contention) {
futures.push_back(p.getFuture());
}
consumer = std::thread([&]{
consumer = std::thread([&] {
b1.post();
for (auto& f : futures) {
std::move(f).then(incr<int>);
......@@ -106,7 +106,7 @@ BENCHMARK(no_contention) {
});
consumer.join();
producer = std::thread([&]{
producer = std::thread([&] {
b2.post();
for (auto& p : promises) {
p.setValue(42);
......@@ -134,7 +134,7 @@ BENCHMARK_RELATIVE(contention) {
futures.push_back(p.getFuture());
}
consumer = std::thread([&]{
consumer = std::thread([&] {
b1.post();
for (auto& f : futures) {
sem_wait(&sem);
......@@ -142,7 +142,7 @@ BENCHMARK_RELATIVE(contention) {
}
});
producer = std::thread([&]{
producer = std::thread([&] {
b2.post();
for (auto& p : promises) {
sem_post(&sem);
......@@ -175,11 +175,11 @@ BENCHMARK_DRAW_LINE();
// The old way. Throw an exception, and rethrow to access it upstream.
void throwAndCatchImpl() {
makeFuture()
.then([](Try<Unit>&&){ throw std::runtime_error("oh no"); })
.then([](Try<Unit>&&) { throw std::runtime_error("oh no"); })
.then([](Try<Unit>&& t) {
try {
t.value();
} catch(const std::runtime_error& e) {
} catch (const std::runtime_error& e) {
// ...
return;
}
......@@ -208,13 +208,13 @@ void throwAndCatchWrappedImpl() {
// Better. Wrap an exception, and rethrow to access it upstream.
void throwWrappedAndCatchImpl() {
makeFuture()
.then([](Try<Unit>&&){
.then([](Try<Unit>&&) {
return makeFuture<Unit>(std::runtime_error("oh no"));
})
.then([](Try<Unit>&& t) {
try {
t.value();
} catch(const std::runtime_error& e) {
} catch (const std::runtime_error& e) {
// ...
return;
}
......@@ -238,15 +238,15 @@ void throwWrappedAndCatchWrappedImpl() {
}
// Simulate heavy contention on func
void contend(void(*func)()) {
void contend(void (*func)()) {
folly::BenchmarkSuspender s;
const int N = 100;
const int iters = 1000;
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, nullptr, N+1);
pthread_barrier_init(&barrier, nullptr, N + 1);
std::vector<std::thread> threads;
for (int i = 0; i < N; i++) {
threads.push_back(std::thread([&](){
threads.push_back(std::thread([&]() {
pthread_barrier_wait(&barrier);
for (int j = 0; j < iters; j++) {
func();
......@@ -340,19 +340,11 @@ template <class T>
Future<T> fGen() {
Promise<T> p;
auto f = p.getFuture()
.then([] (T&& t) {
return std::move(t);
})
.then([] (T&& t) {
return makeFuture(std::move(t));
})
.via(&exe)
.then([] (T&& t) {
return std::move(t);
})
.then([] (T&& t) {
return makeFuture(std::move(t));
});
.then([](T&& t) { return std::move(t); })
.then([](T&& t) { return makeFuture(std::move(t)); })
.via(&exe)
.then([](T&& t) { return std::move(t); })
.then([](T&& t) { return makeFuture(std::move(t)); });
p.setValue(T());
return f;
}
......@@ -371,12 +363,8 @@ void complexBenchmark() {
collect(fsGen<T>());
collectAll(fsGen<T>());
collectAny(fsGen<T>());
futures::map(fsGen<T>(), [] (const T& t) {
return t;
});
futures::map(fsGen<T>(), [] (const T& t) {
return makeFuture(T(t));
});
futures::map(fsGen<T>(), [](const T& t) { return t; });
futures::map(fsGen<T>(), [](const T& t) { return makeFuture(T(t)); });
}
BENCHMARK_DRAW_LINE();
......
......@@ -76,7 +76,7 @@ class CallbackLifetimeTest : public testing::Test {
TEST_F(CallbackLifetimeTest, thenReturnsValue) {
auto c = mkC();
via(&executor).then([_ = mkCGuard(c)]{}).wait();
via(&executor).then([_ = mkCGuard(c)] {}).wait();
EXPECT_EQ(1, *c);
}
......@@ -102,7 +102,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesExnReturnsValueMatch) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](std::exception&){})
.onError([_ = mkCGuard(c)](std::exception&) {})
.wait();
EXPECT_EQ(1, *c);
}
......@@ -120,7 +120,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesExnReturnsValueWrong) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](std::logic_error&){})
.onError([_ = mkCGuard(c)](std::logic_error&) {})
.wait();
EXPECT_EQ(1, *c);
}
......@@ -174,7 +174,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesWrapReturnsValue) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](exception_wrapper &&){})
.onError([_ = mkCGuard(c)](exception_wrapper&&) {})
.wait();
EXPECT_EQ(1, *c);
}
......@@ -183,7 +183,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesWrapReturnsValueThrows) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](exception_wrapper &&) { raise(); })
.onError([_ = mkCGuard(c)](exception_wrapper&&) { raise(); })
.wait();
EXPECT_EQ(1, *c);
}
......@@ -192,7 +192,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesWrapReturnsFuture) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](exception_wrapper &&) { return makeFuture(); })
.onError([_ = mkCGuard(c)](exception_wrapper&&) { return makeFuture(); })
.wait();
EXPECT_EQ(1, *c);
}
......@@ -201,7 +201,7 @@ TEST_F(CallbackLifetimeTest, onErrorTakesWrapReturnsFutureThrows) {
auto c = mkC();
via(&executor)
.then(raise)
.onError([_ = mkCGuard(c)](exception_wrapper &&) { return raiseFut(); })
.onError([_ = mkCGuard(c)](exception_wrapper&&) { return raiseFut(); })
.wait();
EXPECT_EQ(1, *c);
}
......@@ -66,7 +66,6 @@ TEST(Collect, collectAll) {
auto allf = collectAll(futures);
promises[0].setValue(42);
promises[1].setException(eggs);
......@@ -239,7 +238,6 @@ TEST(Collect, collect) {
collect(futures);
}
}
struct NotDefaultConstructible {
......@@ -336,10 +334,8 @@ TEST(Collect, collectAny) {
futures.push_back(p.getFuture());
}
auto anyf = collectAny(futures)
.then([](std::pair<size_t, Try<int>> p) {
EXPECT_EQ(42, p.second.value());
});
auto anyf = collectAny(futures).then(
[](std::pair<size_t, Try<int>> p) { EXPECT_EQ(42, p.second.value()); });
promises[3].setValue(42);
EXPECT_TRUE(anyf.isReady());
......@@ -430,10 +426,9 @@ TEST(Collect, alreadyCompleted) {
fs.push_back(makeFuture(i));
}
collectAny(fs)
.then([&](std::pair<size_t, Try<int>> p) {
EXPECT_EQ(p.first, p.second.value());
});
collectAny(fs).then([&](std::pair<size_t, Try<int>> p) {
EXPECT_EQ(p.first, p.second.value());
});
}
}
......@@ -479,7 +474,7 @@ TEST(Collect, parallelWithError) {
for (size_t i = 0; i < ps.size(); i++) {
ts.emplace_back([&ps, &barrier, i]() {
barrier.wait();
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
ps[i].setException(eggs);
} else {
ps[i].setValue(i);
......@@ -540,7 +535,7 @@ TEST(Collect, allParallelWithError) {
for (size_t i = 0; i < ps.size(); i++) {
ts.emplace_back([&ps, &barrier, i]() {
barrier.wait();
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
ps[i].setException(eggs);
} else {
ps[i].setValue(i);
......@@ -556,7 +551,7 @@ TEST(Collect, allParallelWithError) {
EXPECT_TRUE(f.isReady());
for (size_t i = 0; i < ps.size(); i++) {
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
EXPECT_THROW(f.value()[i].value(), eggs_t);
} else {
EXPECT_TRUE(f.value()[i].hasValue());
......@@ -728,12 +723,11 @@ 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)).then([&](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);
......
......@@ -34,7 +34,6 @@ class TestData : public RequestData {
};
TEST(Context, basic) {
// Start a new context
folly::RequestContextScopeGuard rctx;
......@@ -45,11 +44,11 @@ TEST(Context, basic) {
// Start a future
Promise<Unit> p;
auto future = p.getFuture().then([&]{
auto future = p.getFuture().then([&] {
// Check that the context followed the future
EXPECT_TRUE(RequestContext::get() != nullptr);
auto a = dynamic_cast<TestData*>(
RequestContext::get()->getContextData("test"));
auto a =
dynamic_cast<TestData*>(RequestContext::get()->getContextData("test"));
auto data = a->data_;
EXPECT_EQ(10, data);
});
......
......@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include <folly/futures/Future.h>
#include <folly/futures/detail/Core.h>
#include <folly/futures/Future.h>
#include <folly/portability/GTest.h>
using namespace folly;
......
......@@ -26,9 +26,9 @@ TEST(Ensure, basic) {
size_t count = 0;
auto cob = [&] { count++; };
auto f = makeFuture(42)
.ensure(cob)
.then([](int) { throw std::runtime_error("ensure"); })
.ensure(cob);
.ensure(cob)
.then([](int) { throw std::runtime_error("ensure"); })
.ensure(cob);
EXPECT_THROW(std::move(f).get(), std::runtime_error);
EXPECT_EQ(2, count);
......@@ -39,9 +39,9 @@ TEST(Ensure, mutableLambda) {
set->insert(1);
set->insert(2);
auto f = makeFuture(4)
.ensure([set]() mutable { set->clear(); })
.then([]() { throw std::runtime_error("ensure"); });
auto f = makeFuture(4).ensure([set]() mutable { set->clear(); }).then([]() {
throw std::runtime_error("ensure");
});
EXPECT_EQ(0, set->size());
EXPECT_THROW(std::move(f).get(), std::runtime_error);
......
......@@ -20,7 +20,7 @@
using namespace folly;
TEST(Filter, alwaysTrye) {
EXPECT_EQ(42, makeFuture(42).filter([](int){ return true; }).get());
EXPECT_EQ(42, makeFuture(42).filter([](int) { return true; }).get());
}
TEST(Filter, alwaysFalse) {
......
This diff is collapsed.
......@@ -30,9 +30,7 @@ TEST(Map, basic) {
fs.push_back(p3.getFuture());
int c = 0;
std::vector<Future<Unit>> fs2 = futures::map(fs, [&](int i){
c += i;
});
std::vector<Future<Unit>> fs2 = futures::map(fs, [&](int i) { c += i; });
// Ensure we call the callbacks as the futures complete regardless of order
p2.setValue(1);
......
......@@ -24,8 +24,7 @@ TEST(NonCopyableLambda, basic) {
Future<int> future = promise.getFuture();
Future<Unit>().then(std::bind(
[](Promise<int>& p2) mutable { p2.setValue(123); },
std::move(promise)));
[](Promise<int>& p2) mutable { p2.setValue(123); }, std::move(promise)));
// The previous statement can be simplified in C++14:
// Future<Unit>().then([promise = std::move(promise)]() mutable {
......
......@@ -32,10 +32,8 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(0);
Future<double> f1 = reduce(fs, 1.2,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
Future<double> f1 =
reduce(fs, 1.2, [](double a, Try<int>&& b) { return a + *b + 0.1; });
EXPECT_EQ(1.2, std::move(f1).get());
}
......@@ -43,10 +41,8 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(1);
Future<double> f1 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
Future<double> f1 =
reduce(fs, 0.0, [](double a, Try<int>&& b) { return a + *b + 0.1; });
EXPECT_EQ(1.1, std::move(f1).get());
}
......@@ -54,10 +50,8 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(3);
Future<double> f1 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
Future<double> f1 =
reduce(fs, 0.0, [](double a, Try<int>&& b) { return a + *b + 0.1; });
EXPECT_EQ(6.3, std::move(f1).get());
}
......@@ -65,10 +59,8 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(3);
Future<double> f1 = reduce(fs, 0.0,
[](double a, int&& b){
return a + b + 0.1;
});
Future<double> f1 =
reduce(fs, 0.0, [](double a, int&& b) { return a + b + 0.1; });
EXPECT_EQ(6.3, std::move(f1).get());
}
......@@ -76,10 +68,9 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(3);
Future<double> f2 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return makeFuture<double>(a + *b + 0.1);
});
Future<double> f2 = reduce(fs, 0.0, [](double a, Try<int>&& b) {
return makeFuture<double>(a + *b + 0.1);
});
EXPECT_EQ(6.3, std::move(f2).get());
}
......@@ -87,10 +78,9 @@ TEST(Reduce, basic) {
{
auto fs = makeFutures(3);
Future<double> f2 = reduce(fs, 0.0,
[](double a, int&& b){
return makeFuture<double>(a + b + 0.1);
});
Future<double> f2 = reduce(fs, 0.0, [](double a, int&& b) {
return makeFuture<double>(a + b + 0.1);
});
EXPECT_EQ(6.3, std::move(f2).get());
}
}
......@@ -105,15 +95,14 @@ TEST(Reduce, chain) {
};
{
auto f = collectAll(makeFutures(3)).reduce(0, [](int a, Try<int>&& b){
auto f = collectAll(makeFutures(3)).reduce(0, [](int a, Try<int>&& b) {
return a + *b;
});
EXPECT_EQ(6, std::move(f).get());
}
{
auto f = collect(makeFutures(3)).reduce(0, [](int a, int&& b){
return a + b;
});
auto f =
collect(makeFutures(3)).reduce(0, [](int a, int&& b) { return a + b; });
EXPECT_EQ(6, std::move(f).get());
}
}
......@@ -126,10 +115,9 @@ TEST(Reduce, unorderedReduce) {
fs.push_back(makeFuture(3));
Future<double> f =
unorderedReduce(fs.begin(),
fs.end(),
0.0,
[](double /* a */, int&& b) { return double(b); });
unorderedReduce(fs.begin(), fs.end(), 0.0, [](double /* a */, int&& b) {
return double(b);
});
EXPECT_EQ(3.0, std::move(f).get());
}
{
......@@ -143,10 +131,9 @@ TEST(Reduce, unorderedReduce) {
fs.push_back(p3.getFuture());
Future<double> f =
unorderedReduce(fs.begin(),
fs.end(),
0.0,
[](double /* a */, int&& b) { return double(b); });
unorderedReduce(fs.begin(), fs.end(), 0.0, [](double /* a */, int&& b) {
return double(b);
});
p3.setValue(3);
p2.setValue(2);
p1.setValue(1);
......@@ -165,10 +152,9 @@ TEST(Reduce, unorderedReduceException) {
fs.push_back(p3.getFuture());
Future<double> f =
unorderedReduce(fs.begin(),
fs.end(),
0.0,
[](double /* a */, int&& b) { return b + 0.0; });
unorderedReduce(fs.begin(), fs.end(), 0.0, [](double /* a */, int&& b) {
return b + 0.0;
});
p3.setValue(3);
p2.setException(exception_wrapper(std::runtime_error("blah")));
p1.setValue(1);
......
......@@ -31,14 +31,15 @@ using namespace folly;
// at least min_duration and at least 1 execution will take less than
// max_duration.
template <typename D, typename F>
void multiAttemptExpectDurationWithin(size_t num_tries,
D min_duration,
D max_duration,
const F& func) {
void multiAttemptExpectDurationWithin(
size_t num_tries,
D min_duration,
D max_duration,
const F& func) {
vector<thread> threads(num_tries);
vector<D> durations(num_tries, D::min());
for (size_t i = 0; i < num_tries; ++i) {
threads[i] = thread([&,i]{
threads[i] = thread([&, i] {
auto start = steady_clock::now();
func();
durations[i] = duration_cast<D>(steady_clock::now() - start);
......@@ -65,13 +66,12 @@ TEST(RetryingTest, has_op_call) {
TEST(RetryingTest, basic) {
auto r = futures::retrying(
[](size_t n, const exception_wrapper&) { return n < 3; },
[](size_t n) {
return n < 2
? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
}
).wait();
[](size_t n, const exception_wrapper&) { return n < 3; },
[](size_t n) {
return n < 2 ? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
})
.wait();
EXPECT_EQ(2, r.value());
}
......@@ -105,48 +105,48 @@ TEST(RetryingTest, policy_throws) {
}
TEST(RetryingTest, policy_future) {
atomic<size_t> sleeps {0};
atomic<size_t> sleeps{0};
auto r = futures::retrying(
[&](size_t n, const exception_wrapper&) {
return n < 3
? makeFuture(++sleeps).then([] { return true; })
: makeFuture(false);
},
[](size_t n) {
return n < 2
? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
}
).wait();
[&](size_t n, const exception_wrapper&) {
return n < 3 ? makeFuture(++sleeps).then([] { return true; })
: makeFuture(false);
},
[](size_t n) {
return n < 2 ? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
})
.wait();
EXPECT_EQ(2, r.value());
EXPECT_EQ(2, sleeps);
}
TEST(RetryingTest, policy_basic) {
auto r = futures::retrying(
futures::retryingPolicyBasic(3),
[](size_t n) {
return n < 2
? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
}
).wait();
futures::retryingPolicyBasic(3),
[](size_t n) {
return n < 2 ? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
})
.wait();
EXPECT_EQ(2, r.value());
}
TEST(RetryingTest, policy_capped_jittered_exponential_backoff) {
multiAttemptExpectDurationWithin(5, milliseconds(200), milliseconds(400), []{
multiAttemptExpectDurationWithin(5, milliseconds(200), milliseconds(400), [] {
using ms = milliseconds;
auto r = futures::retrying(
futures::retryingPolicyCappedJitteredExponentialBackoff(
3, ms(100), ms(1000), 0.1, mt19937_64(0),
[](size_t, const exception_wrapper&) { return true; }),
[](size_t n) {
return n < 2
? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
}
).wait();
futures::retryingPolicyCappedJitteredExponentialBackoff(
3,
ms(100),
ms(1000),
0.1,
mt19937_64(0),
[](size_t, const exception_wrapper&) { return true; }),
[](size_t n) {
return n < 2 ? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
})
.wait();
EXPECT_EQ(2, r.value());
});
}
......@@ -173,18 +173,17 @@ TEST(RetryingTest, policy_capped_jittered_exponential_backoff_many_retries) {
}
TEST(RetryingTest, policy_sleep_defaults) {
multiAttemptExpectDurationWithin(5, milliseconds(200), milliseconds(400), []{
multiAttemptExpectDurationWithin(5, milliseconds(200), milliseconds(400), [] {
// To ensure that this compiles with default params.
using ms = milliseconds;
auto r = futures::retrying(
futures::retryingPolicyCappedJitteredExponentialBackoff(
3, ms(100), ms(1000), 0.1),
[](size_t n) {
return n < 2
? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
}
).wait();
futures::retryingPolicyCappedJitteredExponentialBackoff(
3, ms(100), ms(1000), 0.1),
[](size_t n) {
return n < 2 ? makeFuture<size_t>(runtime_error("ha"))
: makeFuture(n);
})
.wait();
EXPECT_EQ(2, r.value());
});
}
......
......@@ -120,7 +120,7 @@ TEST(SharedPromise, moveMove) {
TEST(SharedPromise, setWith) {
SharedPromise<int> p;
p.setWith([]{ return 1; });
p.setWith([] { return 1; });
EXPECT_EQ(1, p.getFuture().value());
}
......
......@@ -7,6 +7,7 @@ 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);}
......@@ -73,4 +74,5 @@ TEST(Basic, thenVariants) {
{Future<B> f = someFuture<A>().then([&](A){return B();});}
{Future<B> f = someFuture<A>().then(&SomeClass::aMethod<B, A&>, &anObject);}
{Future<B> f = someFuture<A>().then([&](){return B();});}
// clang-format on
}
......@@ -38,28 +38,25 @@ Future<T> someFuture() {
}
template <class Ret, class... Params>
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aFunction(Params...) {
typename std::enable_if<isFuture<Ret>::value, Ret>::type aFunction(Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
template <class Ret, class... Params>
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aFunction(Params...) {
typename std::enable_if<!isFuture<Ret>::value, Ret>::type aFunction(Params...) {
return Ret();
}
template <class Ret, class... Params>
std::function<Ret(Params...)>
aStdFunction(
std::function<Ret(Params...)> aStdFunction(
typename std::enable_if<!isFuture<Ret>::value, bool>::type = false) {
return [](Params...) -> Ret { return Ret(); };
}
template <class Ret, class... Params>
std::function<Ret(Params...)>
aStdFunction(typename std::enable_if<isFuture<Ret>::value, bool>::type = true) {
std::function<Ret(Params...)> aStdFunction(
typename std::enable_if<isFuture<Ret>::value, bool>::type = true) {
typedef typename Ret::value_type T;
return [](Params...) -> Future<T> { return makeFuture(T()); };
}
......@@ -67,29 +64,25 @@ aStdFunction(typename std::enable_if<isFuture<Ret>::value, bool>::type = true) {
class SomeClass {
public:
template <class Ret, class... Params>
static
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
static typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aStaticMethod(Params...) {
return Ret();
}
template <class Ret, class... Params>
static
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aStaticMethod(Params...) {
static typename std::enable_if<isFuture<Ret>::value, Ret>::type aStaticMethod(
Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
template <class Ret, class... Params>
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aMethod(Params...) {
typename std::enable_if<!isFuture<Ret>::value, Ret>::type aMethod(Params...) {
return Ret();
}
template <class Ret, class... Params>
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aMethod(Params...) {
typename std::enable_if<isFuture<Ret>::value, Ret>::type aMethod(Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
......
......@@ -26,9 +26,9 @@ struct Widget {
int v_, copied_, moved_;
/* implicit */ Widget(int v) : v_(v), copied_(0), moved_(0) {}
Widget(const Widget& other)
: v_(other.v_), copied_(other.copied_ + 1), moved_(other.moved_) {}
: v_(other.v_), copied_(other.copied_ + 1), moved_(other.moved_) {}
Widget(Widget&& other) noexcept
: v_(other.v_), copied_(other.copied_), moved_(other.moved_ + 1) {}
: v_(other.v_), copied_(other.copied_), moved_(other.moved_ + 1) {}
Widget& operator=(const Widget& /* other */) {
throw std::logic_error("unexpected copy assignment");
}
......@@ -87,102 +87,92 @@ TEST(Then, makeFuture) {
}
TEST(Then, tryConstRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
auto future = makeFuture<Widget>(23).then([](const Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, tryRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
auto future = makeFuture<Widget>(23).then([](Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, tryConstLValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget>& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
auto future = makeFuture<Widget>(23).then([](const Try<Widget>& t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 2);
return t.value().v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, tryValue) {
auto future = makeFuture<Widget>(23).then(
[](Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 3);
return t.value().v_;
});
auto future = makeFuture<Widget>(23).then([](Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 3);
return t.value().v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, tryConstValue) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 3);
return t.value().v_;
});
auto future = makeFuture<Widget>(23).then([](const Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
EXPECT_EQ(t.value().moved_, 3);
return t.value().v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, constRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
auto future = makeFuture<Widget>(23).then([](const Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, rValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
auto future = makeFuture<Widget>(23).then([](Widget&& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, constLValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Widget& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
auto future = makeFuture<Widget>(23).then([](const Widget& w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 2);
return w.v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, value) {
auto future = makeFuture<Widget>(23).then(
[](Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
});
auto future = makeFuture<Widget>(23).then([](Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
});
EXPECT_EQ(future.value(), 23);
}
TEST(Then, constValue) {
auto future = makeFuture<Widget>(23).then(
[](const Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
});
auto future = makeFuture<Widget>(23).then([](const Widget w) {
EXPECT_EQ(w.copied_, 0);
EXPECT_EQ(w.moved_, 3);
return w.v_;
});
EXPECT_EQ(future.value(), 23);
}
......@@ -211,6 +201,5 @@ TEST(Then, objectAliveDuringDeferredNoParamContinuation) {
TEST(Then, voidThenShouldPropagateExceptions) {
EXPECT_FALSE(makeFuture(42).then().hasException());
EXPECT_TRUE(makeFuture<int>(std::runtime_error("err"))
.then().hasException());
EXPECT_TRUE(makeFuture<int>(std::runtime_error("err")).then().hasException());
}
......@@ -33,9 +33,7 @@ std::chrono::steady_clock::time_point now() {
}
struct TimekeeperFixture : public testing::Test {
TimekeeperFixture() :
timeLord_(folly::detail::getTimekeeperSingleton())
{}
TimekeeperFixture() : timeLord_(folly::detail::getTimekeeperSingleton()) {}
std::shared_ptr<Timekeeper> timeLord_;
};
......@@ -52,14 +50,14 @@ TEST_F(TimekeeperFixture, after) {
TEST(Timekeeper, futureGet) {
Promise<int> p;
auto t = std::thread([&]{ p.setValue(42); });
auto t = std::thread([&] { p.setValue(42); });
EXPECT_EQ(42, p.getFuture().get());
t.join();
}
TEST(Timekeeper, futureGetBeforeTimeout) {
Promise<int> p;
auto t = std::thread([&]{ p.setValue(42); });
auto t = std::thread([&] { p.setValue(42); });
// Technically this is a race and if the test server is REALLY overloaded
// and it takes more than a second to do that thread it could be flaky. But
// I want a low timeout (in human terms) so if this regresses and someone
......@@ -283,8 +281,13 @@ TEST(Timekeeper, onTimeout) {
TEST(Timekeeper, onTimeoutComplete) {
bool flag = false;
makeFuture(42)
.onTimeout(zero_ms, [&]{ flag = true; return -1; })
.get();
.onTimeout(
zero_ms,
[&] {
flag = true;
return -1;
})
.get();
EXPECT_FALSE(flag);
}
......@@ -317,9 +320,7 @@ TEST(Timekeeper, interruptDoesntCrash) {
TEST(Timekeeper, chainedInterruptTest) {
bool test = false;
auto f = futures::sleep(milliseconds(100)).then([&](){
test = true;
});
auto f = futures::sleep(milliseconds(100)).then([&]() { test = true; });
f.cancel();
f.wait();
EXPECT_FALSE(test);
......@@ -367,7 +368,7 @@ TEST(Timekeeper, executor) {
Promise<Unit> p;
ExecutorTester tester;
auto f = p.getFuture().via(&tester).within(one_ms).then([&](){});
auto f = p.getFuture().via(&tester).within(one_ms).then([&]() {});
p.setValue();
f.wait();
EXPECT_EQ(2, tester.count);
......@@ -395,8 +396,8 @@ TEST_F(TimekeeperFixture, atBeforeNow) {
TEST_F(TimekeeperFixture, howToCastDuration) {
// I'm not sure whether this rounds up or down but it's irrelevant for the
// purpose of this example.
auto f = timeLord_->after(std::chrono::duration_cast<Duration>(
std::chrono::nanoseconds(1)));
auto f = timeLord_->after(
std::chrono::duration_cast<Duration>(std::chrono::nanoseconds(1)));
}
TEST_F(TimekeeperFixture, destruction) {
......
......@@ -66,9 +66,9 @@ TEST(Times, success) {
bool failure = false;
auto thunk = makeThunk(ps, interrupt, ps_mutex);
auto f = folly::times(3, thunk).then([&]() mutable {
complete = true;
}).onError([&](FutureException& /* e */) { failure = true; });
auto f = folly::times(3, thunk)
.then([&]() mutable { complete = true; })
.onError([&](FutureException& /* e */) { failure = true; });
popAndFulfillPromise(ps, ps_mutex);
EXPECT_FALSE(complete);
......@@ -92,9 +92,9 @@ TEST(Times, failure) {
bool failure = false;
auto thunk = makeThunk(ps, interrupt, ps_mutex);
auto f = folly::times(3, thunk).then([&]() mutable {
complete = true;
}).onError([&](FutureException& /* e */) { failure = true; });
auto f = folly::times(3, thunk)
.then([&]() mutable { complete = true; })
.onError([&](FutureException& /* e */) { failure = true; });
popAndFulfillPromise(ps, ps_mutex);
EXPECT_FALSE(complete);
......@@ -120,9 +120,9 @@ TEST(Times, interrupt) {
bool failure = false;
auto thunk = makeThunk(ps, interrupt, ps_mutex);
auto f = folly::times(3, thunk).then([&]() mutable {
complete = true;
}).onError([&](FutureException& /* e */) { failure = true; });
auto f = folly::times(3, thunk)
.then([&]() mutable { complete = true; })
.onError([&](FutureException& /* e */) { failure = true; });
EXPECT_EQ(0, interrupt);
......
This diff is collapsed.
......@@ -31,7 +31,7 @@ TEST(Wait, waitImmediate) {
auto done = makeFuture(42).wait().value();
EXPECT_EQ(42, done);
vector<int> v{1,2,3};
vector<int> v{1, 2, 3};
auto done_v = makeFuture(v).wait().value();
EXPECT_EQ(v.size(), done_v.size());
EXPECT_EQ(v, done_v);
......@@ -67,7 +67,8 @@ TEST(Wait, wait) {
result.store(n.wait().value());
},
std::move(f));
while(!flag){}
while (!flag) {
}
EXPECT_EQ(result.load(), 1);
p.setValue(42);
th.join();
......@@ -127,179 +128,179 @@ TEST(Wait, waitReplacesSelf) {
}
TEST(Wait, waitWithDuration) {
{
Promise<int> p;
Future<int> f = p.getFuture();
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p.setValue(1);
EXPECT_TRUE(f.isReady());
}
{
Promise<int> p;
Future<int> f = p.getFuture();
p.setValue(1);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
vector<Future<bool>> v_fb;
v_fb.push_back(makeFuture(true));
v_fb.push_back(makeFuture(false));
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
EXPECT_EQ(2, f.value().size());
}
{
vector<Future<bool>> v_fb;
Promise<bool> p1;
Promise<bool> p2;
v_fb.push_back(p1.getFuture());
v_fb.push_back(p2.getFuture());
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p1.setValue(true);
EXPECT_FALSE(f.isReady());
p2.setValue(true);
EXPECT_TRUE(f.isReady());
}
{
auto f = makeFuture().wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
Promise<Unit> p;
auto start = std::chrono::steady_clock::now();
auto f = p.getFuture().wait(milliseconds(100));
auto elapsed = std::chrono::steady_clock::now() - start;
EXPECT_GE(elapsed, milliseconds(100));
EXPECT_FALSE(f.isReady());
p.setValue();
EXPECT_TRUE(f.isReady());
}
{
// Try to trigger the race where the resultant Future is not yet complete
// even if we didn't hit the timeout, and make sure we deal with it properly
Promise<Unit> p;
folly::Baton<> b;
auto t = std::thread([&]{
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue();
});
b.wait();
auto f = p.getFuture().wait(std::chrono::seconds(3600));
EXPECT_TRUE(f.isReady());
t.join();
}
{
// `Future::wait(Duration) &` when promise is fulfilled during the wait
Promise<int> p;
auto f = p.getFuture();
EXPECT_FALSE(f.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
f.wait(std::chrono::seconds(10));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
t.join();
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
}
{
// `Future::wait(Duration) &&` when promise is fulfilled during the wait
Promise<int> p;
auto f1 = p.getFuture();
EXPECT_FALSE(f1.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
auto f2 = std::move(f1).wait(std::chrono::seconds(10));
EXPECT_FALSE(f1.valid());
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
t.join();
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
}
{
// `SemiFuture::wait(Duration) &` when promise is fulfilled during the wait
Promise<int> p;
auto f = p.getSemiFuture();
EXPECT_FALSE(f.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
f.wait(std::chrono::seconds(10));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
t.join();
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
}
{
// `SemiFuture::wait(Duration) &&` when promise is fulfilled during the wait
Promise<int> p;
auto f1 = p.getSemiFuture();
EXPECT_FALSE(f1.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
auto f2 = std::move(f1).wait(std::chrono::seconds(10));
EXPECT_FALSE(f1.valid());
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
t.join();
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
}
{
Promise<int> p;
Future<int> f = p.getFuture();
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p.setValue(1);
EXPECT_TRUE(f.isReady());
}
{
Promise<int> p;
Future<int> f = p.getFuture();
p.setValue(1);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
vector<Future<bool>> v_fb;
v_fb.push_back(makeFuture(true));
v_fb.push_back(makeFuture(false));
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
EXPECT_EQ(2, f.value().size());
}
{
vector<Future<bool>> v_fb;
Promise<bool> p1;
Promise<bool> p2;
v_fb.push_back(p1.getFuture());
v_fb.push_back(p2.getFuture());
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p1.setValue(true);
EXPECT_FALSE(f.isReady());
p2.setValue(true);
EXPECT_TRUE(f.isReady());
}
{
auto f = makeFuture().wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
Promise<Unit> p;
auto start = std::chrono::steady_clock::now();
auto f = p.getFuture().wait(milliseconds(100));
auto elapsed = std::chrono::steady_clock::now() - start;
EXPECT_GE(elapsed, milliseconds(100));
EXPECT_FALSE(f.isReady());
p.setValue();
EXPECT_TRUE(f.isReady());
}
{
// Try to trigger the race where the resultant Future is not yet complete
// even if we didn't hit the timeout, and make sure we deal with it properly
Promise<Unit> p;
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue();
});
b.wait();
auto f = p.getFuture().wait(std::chrono::seconds(3600));
EXPECT_TRUE(f.isReady());
t.join();
}
{
// `Future::wait(Duration) &` when promise is fulfilled during the wait
Promise<int> p;
auto f = p.getFuture();
EXPECT_FALSE(f.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
f.wait(std::chrono::seconds(10));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
t.join();
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
}
{
// `Future::wait(Duration) &&` when promise is fulfilled during the wait
Promise<int> p;
auto f1 = p.getFuture();
EXPECT_FALSE(f1.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
auto f2 = std::move(f1).wait(std::chrono::seconds(10));
EXPECT_FALSE(f1.valid());
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
t.join();
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
}
{
// `SemiFuture::wait(Duration) &` when promise is fulfilled during the wait
Promise<int> p;
auto f = p.getSemiFuture();
EXPECT_FALSE(f.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
f.wait(std::chrono::seconds(10));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
t.join();
EXPECT_TRUE(f.isReady());
EXPECT_EQ(f.value(), 42);
}
{
// `SemiFuture::wait(Duration) &&` when promise is fulfilled during the wait
Promise<int> p;
auto f1 = p.getSemiFuture();
EXPECT_FALSE(f1.isReady());
folly::Baton<> b;
auto t = std::thread([&] {
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue(42);
});
b.wait();
auto f2 = std::move(f1).wait(std::chrono::seconds(10));
EXPECT_FALSE(f1.valid());
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
t.join();
EXPECT_TRUE(f2.valid());
EXPECT_TRUE(f2.isReady());
EXPECT_EQ(f2.value(), 42);
}
}
TEST(Wait, multipleWait) {
......
......@@ -24,9 +24,7 @@ using namespace folly;
TEST(When, predicateFalse) {
int i = 0;
auto thunk = [&] {
return makeFuture().then([&] { i += 1; });
};
auto thunk = [&] { return makeFuture().then([&] { i += 1; }); };
// false
auto f1 = folly::when(false, thunk);
......@@ -36,9 +34,7 @@ TEST(When, predicateFalse) {
TEST(When, predicateTrue) {
int i = 0;
auto thunk = [&] {
return makeFuture().then([&] { i += 1; });
};
auto thunk = [&] { return makeFuture().then([&] { i += 1; }); };
// true
auto f2 = folly::when(true, thunk);
......
......@@ -31,15 +31,12 @@ static eggs_t eggs("eggs");
TEST(Window, basic) {
// int -> Future<int>
auto fn = [](std::vector<int> input, size_t window_size, size_t expect) {
auto res = reduce(
window(
input,
[](int i) { return makeFuture(i); },
window_size),
0,
[](int sum, const Try<int>& b) {
return sum + *b;
}).get();
auto res =
reduce(
window(input, [](int i) { return makeFuture(i); }, window_size),
0,
[](int sum, const Try<int>& b) { return sum + *b; })
.get();
EXPECT_EQ(expect, res);
};
{
......@@ -59,27 +56,31 @@ TEST(Window, basic) {
}
{
// int -> Future<Unit>
auto res = reduce(window(std::vector<int>({1, 2, 3}),
[](int /* i */) { return makeFuture(); },
2),
0,
[](int sum, const Try<Unit>& b) {
EXPECT_TRUE(b.hasValue());
return sum + 1;
}).get();
auto res = reduce(
window(
std::vector<int>({1, 2, 3}),
[](int /* i */) { return makeFuture(); },
2),
0,
[](int sum, const Try<Unit>& b) {
EXPECT_TRUE(b.hasValue());
return sum + 1;
})
.get();
EXPECT_EQ(3, res);
}
{
// string -> return Future<int>
auto res = reduce(
window(
std::vector<std::string>{"1", "2", "3"},
[](std::string s) { return makeFuture<int>(folly::to<int>(s)); },
2),
0,
[](int sum, const Try<int>& b) {
return sum + *b;
}).get();
window(
std::vector<std::string>{"1", "2", "3"},
[](std::string s) {
return makeFuture<int>(folly::to<int>(s));
},
2),
0,
[](int sum, const Try<int>& b) { return sum + *b; })
.get();
EXPECT_EQ(6, res);
}
{
......@@ -98,16 +99,15 @@ TEST(Window, basic) {
}
{
SCOPED_TRACE("repeat same fn");
auto res = reduce(
window(
5UL,
[](size_t iteration) {
return folly::makeFuture(iteration); },
2),
0UL,
[](size_t sum, const Try<size_t>& b) {
return sum + b.value();
}).get();
auto res =
reduce(
window(
5UL,
[](size_t iteration) { return folly::makeFuture(iteration); },
2),
0UL,
[](size_t sum, const Try<size_t>& b) { return sum + b.value(); })
.get();
EXPECT_EQ(0 + 1 + 2 + 3 + 4, res);
}
}
......@@ -180,9 +180,7 @@ TEST(Window, parallel) {
for (size_t i = 0; i < ps.size(); i++) {
input.emplace_back(i);
}
auto f = collect(window(input, [&](int i) {
return ps[i].getFuture();
}, 3));
auto f = collect(window(input, [&](int i) { return ps[i].getFuture(); }, 3));
std::vector<std::thread> ts;
boost::barrier barrier(ps.size() + 1);
......@@ -211,16 +209,14 @@ TEST(Window, parallelWithError) {
for (size_t i = 0; i < ps.size(); i++) {
input.emplace_back(i);
}
auto f = collect(window(input, [&](int i) {
return ps[i].getFuture();
}, 3));
auto f = collect(window(input, [&](int i) { return ps[i].getFuture(); }, 3));
std::vector<std::thread> ts;
boost::barrier barrier(ps.size() + 1);
for (size_t i = 0; i < ps.size(); i++) {
ts.emplace_back([&ps, &barrier, i]() {
barrier.wait();
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
ps[i].setException(eggs);
} else {
ps[i].setValue(i);
......@@ -244,16 +240,15 @@ TEST(Window, allParallelWithError) {
for (size_t i = 0; i < ps.size(); i++) {
input.emplace_back(i);
}
auto f = collectAll(window(input, [&](int i) {
return ps[i].getFuture();
}, 3));
auto f =
collectAll(window(input, [&](int i) { return ps[i].getFuture(); }, 3));
std::vector<std::thread> ts;
boost::barrier barrier(ps.size() + 1);
for (size_t i = 0; i < ps.size(); i++) {
ts.emplace_back([&ps, &barrier, i]() {
barrier.wait();
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
ps[i].setException(eggs);
} else {
ps[i].setValue(i);
......@@ -269,7 +264,7 @@ TEST(Window, allParallelWithError) {
EXPECT_TRUE(f.isReady());
for (size_t i = 0; i < ps.size(); i++) {
if (i == (ps.size()/2)) {
if (i == (ps.size() / 2)) {
EXPECT_THROW(f.value()[i].value(), eggs_t);
} else {
EXPECT_TRUE(f.value()[i].hasValue());
......
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