Add makeSemiFuture declarations to helpers.h
[folly.git] / folly / futures / helpers.h
index 2dc55d1bb615114303829af90a1706682f3f6c58..9b5e85ba1f0ac96ede79a336389f34faa9645e63 100644 (file)
@@ -110,6 +110,73 @@ namespace futures {
 
 } // namespace futures
 
+/**
+  Make a completed SemiFuture by moving in a value. e.g.
+
+    string foo = "foo";
+    auto f = makeSemiFuture(std::move(foo));
+
+  or
+
+    auto f = makeSemiFuture<string>("foo");
+*/
+template <class T>
+SemiFuture<typename std::decay<T>::type> makeSemiFuture(T&& t);
+
+/** Make a completed void SemiFuture. */
+SemiFuture<Unit> makeSemiFuture();
+
+/**
+  Make a SemiFuture by executing a function.
+
+  If the function returns a value of type T, makeSemiFutureWith
+  returns a completed SemiFuture<T>, capturing the value returned
+  by the function.
+
+  If the function returns a SemiFuture<T> already, makeSemiFutureWith
+  returns just that.
+
+  Either way, if the function throws, a failed Future is
+  returned that captures the exception.
+*/
+
+// makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T>
+template <class F>
+typename std::enable_if<isSemiFuture<typename std::result_of<F()>::type>::value,
+                        typename std::result_of<F()>::type>::type
+makeSemiFutureWith(F&& func);
+
+// makeSemiFutureWith(T()) -> SemiFuture<T>
+// makeSemiFutureWith(void()) -> SemiFuture<Unit>
+template <class F>
+typename std::enable_if<
+    !(isSemiFuture<typename std::result_of<F()>::type>::value),
+    SemiFuture<typename Unit::Lift<typename std::result_of<F()>::type>::type>>::type
+makeSemiFutureWith(F&& func);
+
+/// Make a failed Future from an exception_ptr.
+/// Because the Future's type cannot be inferred you have to specify it, e.g.
+///
+///   auto f = makeSemiFuture<string>(std::current_exception());
+template <class T>
+FOLLY_DEPRECATED("use makeSemiFuture(exception_wrapper)")
+SemiFuture<T> makeSemiFuture(std::exception_ptr const& e);
+
+/// Make a failed SemiFuture from an exception_wrapper.
+template <class T>
+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);
+
+/** Make a Future out of a Try */
+template <class T>
+SemiFuture<T> makeSemiFuture(Try<T>&& t);
+
 /**
   Make a completed Future by moving in a value. e.g.
 
@@ -328,6 +395,15 @@ template <
     class Result = typename futures::detail::resultOf<F, ItT&&>::value_type>
 std::vector<Future<Result>> window(Collection input, F func, size_t n);
 
+template <
+    class Collection,
+    class F,
+    class ItT = typename std::iterator_traits<
+        typename Collection::iterator>::value_type,
+    class Result = typename futures::detail::resultOf<F, ItT&&>::value_type>
+std::vector<Future<Result>>
+window(Executor* executor, Collection input, F func, size_t n);
+
 template <typename F, typename T, typename ItT>
 using MaybeTryArg = typename std::conditional<
     futures::detail::callableWith<F, T&&, Try<ItT>&&>::value,
@@ -384,76 +460,4 @@ auto unorderedReduce(Collection&& c, T&& initial, F&& func)
       std::forward<T>(initial),
       std::forward<F>(func));
 }
-
-namespace futures {
-
-/**
- *  retrying
- *
- *  Given a policy and a future-factory, creates futures according to the
- *  policy.
- *
- *  The policy must be moveable - retrying will move it a lot - and callable of
- *  either of the two forms:
- *  - Future<bool>(size_t, exception_wrapper)
- *  - bool(size_t, exception_wrapper)
- *  Internally, the latter is transformed into the former in the obvious way.
- *  The first parameter is the attempt number of the next prospective attempt;
- *  the second parameter is the most recent exception. The policy returns a
- *  Future<bool> which, when completed with true, indicates that a retry is
- *  desired.
- *
- *  We provide a few generic policies:
- *  - Basic
- *  - CappedJitteredexponentialBackoff
- *
- *  Custom policies may use the most recent try number and exception to decide
- *  whether to retry and optionally to do something interesting like delay
- *  before the retry. Users may pass inline lambda expressions as policies, or
- *  may define their own data types meeting the above requirements. Users are
- *  responsible for managing the lifetimes of anything pointed to or referred to
- *  from inside the policy.
- *
- *  For example, one custom policy may try up to k times, but only if the most
- *  recent exception is one of a few types or has one of a few error codes
- *  indicating that the failure was transitory.
- *
- *  Cancellation is not supported.
- *
- *  If both FF and Policy inline executes, then it is possible to hit a stack
- *  overflow due to the recursive nature of the retry implementation
- */
-template <class Policy, class FF>
-typename std::result_of<FF(size_t)>::type
-retrying(Policy&& p, FF&& ff);
-
-/**
- *  generic retrying policies
- */
-
-inline
-std::function<bool(size_t, const exception_wrapper&)>
-retryingPolicyBasic(
-    size_t max_tries);
-
-template <class Policy, class URNG>
-std::function<Future<bool>(size_t, const exception_wrapper&)>
-retryingPolicyCappedJitteredExponentialBackoff(
-    size_t max_tries,
-    Duration backoff_min,
-    Duration backoff_max,
-    double jitter_param,
-    URNG&& rng,
-    Policy&& p);
-
-inline
-std::function<Future<bool>(size_t, const exception_wrapper&)>
-retryingPolicyCappedJitteredExponentialBackoff(
-    size_t max_tries,
-    Duration backoff_min,
-    Duration backoff_max,
-    double jitter_param);
-
-}
-
-} // namespace
+} // namespace folly