#include <functional>
#include <memory>
#include <type_traits>
+#include <vector>
#include "folly/MoveWrapper.h"
#include "Promise.h"
typename std::add_lvalue_reference<const T>::type
value() const;
+ /// Returns a future which will call back on the other side of executor.
+ ///
+ /// f.via(e).then(a); // safe
+ ///
+ /// f.via(e).then(a).then(b); // faux pas
+ ///
+ /// a will definitely execute in the intended thread, but b may execute
+ /// either in that thread, or in the current thread. If you need to
+ /// guarantee where b executes, use a Later.
template <typename Executor>
- Future<T> executeWithSameThread(Executor* executor);
+ Future<T> via(Executor* executor);
+
+ /// Deprecated alias for via
+ template <typename Executor>
+ Future<T> executeWithSameThread(Executor* executor) {
+ return via(executor);
+ }
/**
Thread-safe version of executeWith
Instead, you may pass in a Promise so that we can set up
the rest of the chain in advance, without any racey
modifications of the continuation
+
+ Deprecated. Use a Later.
*/
template <typename Executor>
void executeWith(Executor* executor, Promise<T>&& cont_promise);
Future<typename std::result_of<F(Try<T>&&)>::type> >::type
then(F&& func);
- /// Variant where func returns a future<T> instead of a T. e.g.
+ /// Variant where func returns a Future<T> instead of a T. e.g.
///
/// Future<string> f2 = f1.then(
/// [](Try<T>&&) { return makeFuture<string>("foo"); });
Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
then(F&& func);
+ /// Variant where func is an ordinary function (static method, method)
+ ///
+ /// R doWork(Try<T>&&);
+ ///
+ /// Future<R> f2 = f1.then(doWork);
+ ///
+ /// or
+ ///
+ /// struct Worker {
+ /// static R doWork(Try<T>&&); }
+ ///
+ /// Future<R> f2 = f1.then(&Worker::doWork);
+ template <class = T, class R = std::nullptr_t>
+ typename std::enable_if<!isFuture<R>::value, Future<R>>::type
+ inline then(R(*func)(Try<T>&&)) {
+ return then([func](Try<T>&& t) {
+ return (*func)(std::move(t));
+ });
+ }
+
+ /// Variant where func returns a Future<R> instead of a R. e.g.
+ ///
+ /// struct Worker {
+ /// Future<R> doWork(Try<T>&&); }
+ ///
+ /// Future<R> f2 = f1.then(&Worker::doWork);
+ template <class = T, class R = std::nullptr_t>
+ typename std::enable_if<isFuture<R>::value, R>::type
+ inline then(R(*func)(Try<T>&&)) {
+ return then([func](Try<T>&& t) {
+ return (*func)(std::move(t));
+ });
+ }
+
+ /// Variant where func is an member function
+ ///
+ /// struct Worker {
+ /// R doWork(Try<T>&&); }
+ ///
+ /// Worker *w;
+ /// Future<R> f2 = f1.then(w, &Worker::doWork);
+ template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
+ typename std::enable_if<!isFuture<R>::value, Future<R>>::type
+ inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
+ return then([instance, func](Try<T>&& t) {
+ return (instance->*func)(std::move(t));
+ });
+ }
+
+ /// Variant where func returns a Future<R> instead of a R. e.g.
+ ///
+ /// struct Worker {
+ /// Future<R> doWork(Try<T>&&); }
+ ///
+ /// Worker *w;
+ /// Future<R> f2 = f1.then(w, &Worker::doWork);
+ template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
+ typename std::enable_if<isFuture<R>::value, R>::type
+ inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
+ return then([instance, func](Try<T>&& t) {
+ return (instance->*func)(std::move(t));
+ });
+ }
+
/// Convenience method for ignoring the value and creating a Future<void>.
/// Exceptions still propagate.
Future<void> then();
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 */
+template <class T>
+Future<T> makeFuture(Try<T>&& t);
+
/** When all the input Futures complete, the returned Future will complete.
Errors do not cause early termination; this Future will always succeed
after all its Futures have finished (whether successfully or with an
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
whenN(InputIterator first, InputIterator last, size_t n);
+/** Wait for the given future to complete on a semaphore. Returns the result of
+ * the given future.
+ *
+ * NB if the promise for the future would be fulfilled in the same thread that
+ * you call this, it will deadlock.
+ */
+template <class F>
+typename F::value_type waitWithSemaphore(F&& f);
+
}} // folly::wangle
#include "Future-inl.h"